From e1db06d59d580aa640212a0d3a6aeecb9122bdf0 Mon Sep 17 00:00:00 2001
From: geireann <geireann.lindfield@gmail.com>
Date: Thu, 25 Jul 2024 15:06:01 -0400
Subject: lots more 'any' cleanup and more.

---
 .../views/nodes/formattedText/RichTextMenu.tsx     | 91 +++++++++++-----------
 1 file changed, 44 insertions(+), 47 deletions(-)

(limited to 'src/client/views/nodes/formattedText/RichTextMenu.tsx')

diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index a612f3c65..247b7c097 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -5,7 +5,7 @@ import { observer } from 'mobx-react';
 import { lift, wrapIn } from 'prosemirror-commands';
 import { Mark, MarkType } from 'prosemirror-model';
 import { wrapInList } from 'prosemirror-schema-list';
-import { EditorState, NodeSelection, TextSelection } from 'prosemirror-state';
+import { EditorState, NodeSelection, TextSelection, Transaction } from 'prosemirror-state';
 import { EditorView } from 'prosemirror-view';
 import * as React from 'react';
 import { Doc } from '../../../../fields/Doc';
@@ -17,7 +17,7 @@ import { ObservableReactComponent } from '../../ObservableReactComponent';
 import { DocumentView } from '../DocumentView';
 import { EquationBox } from '../EquationBox';
 import { FieldViewProps } from '../FieldView';
-import { FormattedTextBox } from './FormattedTextBox';
+import { FormattedTextBox, FormattedTextBoxProps } from './FormattedTextBox';
 import { updateBullets } from './ProsemirrorExampleTransfer';
 import './RichTextMenu.scss';
 import { schema } from './schema_rts';
@@ -35,8 +35,8 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
     private _linkToRef = React.createRef<HTMLInputElement>();
 
     layoutDoc: Doc | undefined;
-    @observable public view?: EditorView = undefined;
-    public editorProps: FieldViewProps | undefined;
+    @observable public view?: EditorView & { TextView ?: FormattedTextBox } = undefined;
+    public editorProps: FieldViewProps | AntimodeMenuProps |undefined;
 
     public _brushMap: Map<string, Set<Mark>> = new Map();
 
@@ -114,17 +114,17 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
     }
     _disposer: IReactionDisposer | undefined;
     componentDidMount() {
-        this._disposer = reaction(
-            () => DocumentView.Selected().slice(),
-            () => this.updateMenu(undefined, undefined, undefined, undefined)
-        );
+        // this._disposer = reaction(
+        //     () => DocumentView.Selected().slice(),
+        //     () => this.updateMenu(undefined, undefined, undefined, undefined)
+        // );
     }
     componentWillUnmount() {
         this._disposer?.();
     }
 
     @action
-    public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: any, layoutDoc: Doc | undefined) {
+    public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: FormattedTextBoxProps|AntimodeMenuProps|undefined, layoutDoc: Doc | undefined) {
         if (this._linkToRef.current?.getBoundingClientRect().width) {
             return;
         }
@@ -158,7 +158,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
         this.getTextLinkTargetTitle().then(targetTitle => this.setCurrentLink(targetTitle));
     }
 
-    setMark = (mark: Mark, state: EditorState, dispatch: any, dontToggle: boolean = false) => {
+    setMark = (mark: Mark, state: EditorState, dispatch: (tr:Transaction) => void, dontToggle: boolean = false) => {
         if (mark) {
             const newPos = state.selection.$anchor.node()?.type === schema.nodes.ordered_list ? state.selection.from : state.selection.from;
             const node = (state.selection as NodeSelection).node ?? (newPos >= 0 ? state.doc.nodeAt(newPos) : undefined);
@@ -177,17 +177,18 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
                     toggleMark(mark.type, mark.attrs)(state, dispatch);
                 }
             }
-            this.updateMenu(this.view, undefined, undefined, this.layoutDoc);
+        //    this.updateMenu(this.view, undefined, undefined, this.layoutDoc);
         }
     };
 
     // finds font sizes and families in selection
-    getActiveAlignment() {
+    getActiveAlignment = () => {
         if (this.view && this.TextView?._props.rootSelected?.()) {
-            const { path } = this.view.state.selection.$from as any;
-            for (let i = path.length - 3; i < path.length && i >= 0; i -= 3) {
-                if (path[i]?.type === this.view.state.schema.nodes.paragraph || path[i]?.type === this.view.state.schema.nodes.heading) {
-                    return path[i].attrs.align || 'left';
+            const from = this.view.state.selection.$from;
+            for (let i = from.depth; i >= 0; i--) {
+                const node = from.node(i);
+                if (node.type === this.view.state.schema.nodes.paragraph || node.type === this.view.state.schema.nodes.heading) {
+                    return node.attrs.align || 'left';
                 }
             }
         }
@@ -195,7 +196,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
     }
 
     // finds font sizes and families in selection
-    getActiveListStyle() {
+    getActiveListStyle = () => {
         const state = this.view?.state;
         if (state) {
             const pos = state.selection.$anchor;
@@ -321,7 +322,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
         if (this.view) {
             const mark = this.view.state.schema.mark(this.view.state.schema.marks.noAutoLinkAnchor);
             this.setMark(mark, this.view.state, this.view.dispatch, false);
-            this.TextView.autoLink();
+            this.TextView?.autoLink();
             this.view.focus();
         }
     };
@@ -350,7 +351,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
     };
 
     setFontField = (value: string, fontField: 'fontSize' | 'fontFamily' | 'fontColor' | 'fontHighlight') => {
-        if (this.view) {
+        if (this.TextView && this.view) {
             const { text, paragraph } = this.view.state.schema.nodes;
             const selNode = this.view.state.selection.$anchor.node();
             if (this.view.state.selection.from === 1 && this.view.state.selection.empty && [undefined, text, paragraph].includes(selNode?.type)) {
@@ -360,11 +361,11 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
             const attrs: { [key: string]: string } = {};
             attrs[fontField] = value;
             const fmark = this.view?.state.schema.marks['pF' + fontField.substring(1)].create(attrs);
-            this.setMark(fmark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(fmark)), true);
+            this.setMark(fmark, this.view.state, (tx: Transaction) => this.view!.dispatch(tx.addStoredMark(fmark)), true);
             this.view.focus();
         } else {
             Doc.UserDoc()[fontField] = value;
-            this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
+           // this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
         }
     };
 
@@ -383,17 +384,17 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
             marks && tx2.setStoredMarks([...marks]);
             this.view.dispatch(tx2);
         } else
-            !wrapInList(schema.nodes.ordered_list)(this.view.state, (tx2: any) => {
+            !wrapInList(schema.nodes.ordered_list)(this.view.state, (tx2: Transaction) => {
                 const tx3 = updateBullets(tx2, schema, newMapStyle, this.view!.state.selection.from - 1, this.view!.state.selection.to + 1);
                 marks && tx3.ensureMarks([...marks]);
                 marks && tx3.setStoredMarks([...marks]);
                 this.view!.dispatch(tx3);
             });
         this.view.focus();
-        this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
+       // this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
     };
 
-    insertSummarizer(state: EditorState, dispatch: any) {
+    insertSummarizer(state: EditorState, dispatch: (tr:Transaction) => void) {
         if (state.selection.empty) return false;
         const mark = state.schema.marks.summarize.create();
         const { tr } = state;
@@ -407,7 +408,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
     vcenterToggle = () => {
         this.layoutDoc && (this.layoutDoc._layout_centered = !this.layoutDoc._layout_centered);
     };
-    align = (view: EditorView, dispatch: any, alignment: 'left' | 'right' | 'center') => {
+    align = (view: EditorView, dispatch: (tr:Transaction) => void, alignment: 'left' | 'right' | 'center') => {
         if (this.TextView?._props.rootSelected?.()) {
             let { tr } = view.state;
             view.state.doc.nodesBetween(view.state.selection.from, view.state.selection.to, (node, pos) => {
@@ -423,7 +424,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
         }
     };
 
-    paragraphSetup(state: EditorState, dispatch: any, field: 'inset' | 'indent', value?: 0 | 10 | -10) {
+    paragraphSetup(state: EditorState, dispatch: (tr:Transaction) => void, field: 'inset' | 'indent', value?: 0 | 10 | -10) {
         let { tr } = state;
         state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos) => {
             if (node.type === schema.nodes.paragraph || node.type === schema.nodes.heading) {
@@ -439,9 +440,9 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
         return true;
     }
 
-    insertBlockquote(state: EditorState, dispatch: any) {
-        const { path } = state.selection.$from as any;
-        if (path.length > 6 && path[path.length - 6].type === schema.nodes.blockquote) {
+    insertBlockquote(state: EditorState, dispatch: (tr:Transaction) => void) {
+        const node = state.selection.$from.depth ? state.selection.$from.node(state.selection.$from.depth-1): undefined;
+        if (node?.type === schema.nodes.blockquote) {
             lift(state, dispatch);
         } else {
             wrapIn(schema.nodes.blockquote)(state, dispatch);
@@ -449,7 +450,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
         return true;
     }
 
-    insertHorizontalRule(state: EditorState, dispatch: any) {
+    insertHorizontalRule(state: EditorState, dispatch: (tr:Transaction) => void) {
         dispatch(state.tr.replaceSelectionWith(state.schema.nodes.horizontal_rule.create()).scrollIntoView());
         return true;
     }
@@ -497,7 +498,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
     }
 
     get TextView() {
-        return (this.view as any)?.TextView as FormattedTextBox;
+        return this.view?.TextView;
     }
     get TextViewFieldKey() {
         return this.TextView?._props.fieldKey;
@@ -512,11 +513,9 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
     }
 
     createLinkButton() {
-        const self = this;
-
-        function onLinkChange(e: React.ChangeEvent<HTMLInputElement>) {
-            self.TextView?.endUndoTypingBatch();
-            UndoManager.RunInBatch(() => self.setCurrentLink(e.target.value), 'link change');
+        const onLinkChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+            this.TextView?.endUndoTypingBatch();
+            UndoManager.RunInBatch(() => this.setCurrentLink(e.target.value), 'link change');
         }
 
         const link = this.currentLink ? this.currentLink : '';
@@ -524,7 +523,6 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
         const button = (
             <Tooltip title={<div className="dash-tooltip">set hyperlink</div>} placement="bottom">
                 {
-                    // eslint-disable-next-line jsx-a11y/control-has-associated-label
                     <button type="button" className="antimodeMenu-button color-preview-button">
                         <FontAwesomeIcon icon="link" size="lg" />
                     </button>
@@ -589,7 +587,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
     // TODO: should check for valid URL
     @undoBatch
     makeLinkToURL = (target: string) => {
-        ((this.view as any)?.TextView as FormattedTextBox).makeLinkAnchor(undefined, 'onRadd:rightight', target, target);
+        this.TextView?.makeLinkAnchor(undefined, 'onRadd:rightight', target, target);
     };
 
     @undoBatch
@@ -597,12 +595,12 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
         if (this.view) {
             const linkAnchor = this.view.state.selection.$from.nodeAfter?.marks.find(m => m.type === this.view!.state.schema.marks.linkAnchor);
             if (linkAnchor) {
-                const allAnchors = linkAnchor.attrs.allAnchors.slice();
-                this.TextView.RemoveAnchorFromSelection(allAnchors);
+                const allAnchors = (linkAnchor.attrs.allAnchors as { href: string; title: string; linkId: string; targetId: string; }[]).slice();
+                this.TextView?.RemoveAnchorFromSelection(allAnchors);
                 // bcz: Argh ... this will remove the link from the document even it's anchored somewhere else in the text which happens if only part of the anchor text was selected.
                 allAnchors
-                    .filter((aref: any) => aref?.href.indexOf(Doc.localServerPath()) === 0)
-                    .forEach((aref: any) => {
+                    .filter(aref => aref?.href.indexOf(Doc.localServerPath()) === 0)
+                    .forEach(aref => {
                         const anchorId = aref.href.replace(Doc.localServerPath(), '').split('?')[0];
                         anchorId && DocServer.GetRefField(anchorId).then(linkDoc => Doc.DeleteLink?.(linkDoc as Doc));
                     });
@@ -629,7 +627,7 @@ export class ButtonDropdown extends ObservableReactComponent<ButtonDropdownProps
     @observable private showDropdown: boolean = false;
     private ref: HTMLDivElement | null = null;
 
-    constructor(props: any) {
+    constructor(props: ButtonDropdownProps) {
         super(props);
         makeObservable(this);
     }
@@ -683,7 +681,6 @@ export class ButtonDropdown extends ObservableReactComponent<ButtonDropdownProps
                     <>
                         {this._props.button}
                         {
-                            // eslint-disable-next-line jsx-a11y/control-has-associated-label
                             <button type="button" className="dropdown-button antimodeMenu-button" key="antimodebutton" onPointerDown={this.onDropdownClick}>
                                 <FontAwesomeIcon icon="caret-down" size="sm" />
                             </button>
@@ -697,12 +694,12 @@ export class ButtonDropdown extends ObservableReactComponent<ButtonDropdownProps
 }
 
 interface RichTextMenuPluginProps {
-    editorProps: any;
+    editorProps: FormattedTextBoxProps;
 }
 export class RichTextMenuPlugin extends React.Component<RichTextMenuPluginProps> {
     // eslint-disable-next-line react/no-unused-class-component-methods
-    update(view: EditorView, lastState: EditorState | undefined) {
-        RichTextMenu.Instance?.updateMenu(view, lastState, this.props.editorProps, (view as any).TextView?.layoutDoc);
+    update(view: EditorView & {TextView ?: FormattedTextBox}, lastState: EditorState | undefined) {
+        RichTextMenu.Instance?.updateMenu(view, lastState, this.props.editorProps, view.TextView?.layoutDoc);
     }
     render() {
         return null;
-- 
cgit v1.2.3-70-g09d2


From 4574b7f03ccc85c4bebdbfd9475788456086704f Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 8 Aug 2024 12:27:40 -0400
Subject: many changes to add typing in place of 'any's etc

---
 package-lock.json                                  | 4932 ++++++++++----------
 package.json                                       |    3 +
 src/ClientUtils.ts                                 |   75 +-
 src/JSZipUtils.js                                  |   10 +-
 src/client/DocServer.ts                            |  263 +-
 src/client/Network.ts                              |   27 +-
 src/client/documents/DocUtils.ts                   |   64 +-
 src/client/documents/DocumentTypes.ts              |    1 -
 src/client/documents/Documents.ts                  |   33 +-
 src/client/util/CalendarManager.tsx                |   44 +-
 src/client/util/CaptureManager.tsx                 |   10 +-
 src/client/util/CurrentUserUtils.ts                |   80 +-
 src/client/util/DictationManager.ts                |   43 +-
 src/client/util/DocumentManager.ts                 |   39 +-
 src/client/util/DragManager.ts                     |  103 +-
 src/client/util/DropConverter.ts                   |   13 +-
 src/client/util/GroupManager.tsx                   |   22 +-
 src/client/util/GroupMemberView.tsx                |    2 -
 src/client/util/History.ts                         |    7 +-
 src/client/util/Import & Export/ImageUtils.ts      |    1 +
 .../util/Import & Export/ImportMetadataEntry.tsx   |    2 -
 src/client/util/InteractionUtils.tsx               |   22 +-
 src/client/util/LinkFollower.ts                    |    4 +-
 src/client/util/LinkManager.ts                     |   43 +-
 src/client/util/ProsemirrorCopy/prompt.js          |  179 -
 src/client/util/RTFMarkup.tsx                      |    4 +-
 src/client/util/ReplayMovements.ts                 |   15 +-
 src/client/util/Scripting.ts                       |   34 +-
 src/client/util/ScriptingGlobals.ts                |   42 +-
 src/client/util/SearchUtil.ts                      |    2 +
 src/client/util/SelectionManager.ts                |    2 +-
 src/client/util/SerializationHelper.ts             |   36 +-
 src/client/util/ServerStats.tsx                    |   19 +-
 src/client/util/SettingsManager.tsx                |    2 -
 src/client/util/SharingManager.tsx                 |   23 +-
 src/client/util/SnappingManager.ts                 |    2 +-
 src/client/util/TrackMovements.ts                  |    8 +-
 src/client/util/TypedEvent.ts                      |    2 +-
 src/client/util/UndoManager.ts                     |   34 +-
 src/client/util/reportManager/ReportManager.tsx    |    6 +-
 .../util/reportManager/ReportManagerComponents.tsx |   11 +-
 .../util/reportManager/reportManagerSchema.ts      |   40 +-
 .../util/reportManager/reportManagerUtils.ts       |   16 +-
 src/client/util/request-image-size.ts              |   36 +-
 src/client/views/AntimodeMenu.tsx                  |    2 +-
 src/client/views/ContextMenu.tsx                   |   33 +-
 src/client/views/ContextMenuItem.tsx               |   10 +-
 src/client/views/DashboardView.tsx                 |    6 +-
 src/client/views/FilterPanel.tsx                   |   12 +-
 src/client/views/GestureOverlay.tsx                |   26 +-
 src/client/views/InkTranscription.tsx              |    3 +-
 src/client/views/InkingStroke.tsx                  |   22 +-
 src/client/views/LightboxView.tsx                  |   22 +-
 src/client/views/Main.tsx                          |   18 +-
 src/client/views/MainView.tsx                      |   53 +-
 src/client/views/OverlayView.tsx                   |   21 +-
 src/client/views/ScriptingRepl.tsx                 |   54 +-
 src/client/views/StyleProvider.tsx                 |    6 +-
 src/client/views/ViewBoxInterface.ts               |    3 +
 .../views/collections/CollectionCalendarView.tsx   |    4 +-
 .../views/collections/CollectionCardDeckView.tsx   |   13 +-
 .../views/collections/CollectionCarouselView.tsx   |   16 +-
 .../views/collections/CollectionDockingView.tsx    |   68 +-
 .../collections/CollectionMasonryViewFieldRow.tsx  |   20 +-
 src/client/views/collections/CollectionMenu.tsx    |    4 -
 .../views/collections/CollectionNoteTakingView.tsx |   29 +-
 .../collections/CollectionNoteTakingViewColumn.tsx |   15 +-
 .../views/collections/CollectionPileView.tsx       |   10 +-
 .../collections/CollectionStackedTimeline.tsx      |   21 +-
 .../views/collections/CollectionStackingView.tsx   |   27 +-
 src/client/views/collections/CollectionSubView.tsx |   23 +-
 .../views/collections/CollectionTimeView.tsx       |    8 +-
 .../views/collections/CollectionTreeView.tsx       |   43 +-
 src/client/views/collections/TabDocView.tsx        |   28 +-
 src/client/views/collections/TreeView.tsx          |   86 +-
 .../CollectionFreeFormInfoState.tsx                |   12 +-
 .../CollectionFreeFormPannableContents.tsx         |    4 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   65 +-
 .../collectionLinear/CollectionLinearView.tsx      |   10 +-
 src/client/views/nodes/AudioBox.tsx                |   57 +-
 .../views/nodes/CollectionFreeFormDocumentView.tsx |   24 +-
 src/client/views/nodes/ComparisonBox.tsx           |    7 +-
 src/client/views/nodes/DataVizBox/DataVizBox.tsx   |    8 +-
 .../views/nodes/DataVizBox/SchemaCSVPopUp.tsx      |    2 -
 .../views/nodes/DataVizBox/components/TableBox.tsx |   56 +-
 src/client/views/nodes/DocumentContentsView.tsx    |   46 +-
 src/client/views/nodes/DocumentLinksButton.tsx     |    4 +-
 src/client/views/nodes/DocumentView.tsx            |   39 +-
 src/client/views/nodes/EquationBox.tsx             |   11 +-
 src/client/views/nodes/FieldView.tsx               |    3 +-
 .../views/nodes/FontIconBox/ButtonInterface.ts     |   12 -
 src/client/views/nodes/FontIconBox/FontIconBox.tsx |   46 +-
 src/client/views/nodes/ImageBox.tsx                |    9 +-
 src/client/views/nodes/KeyValueBox.tsx             |   14 +-
 src/client/views/nodes/KeyValuePair.tsx            |    9 +-
 src/client/views/nodes/LinkBox.tsx                 |   14 +-
 src/client/views/nodes/LinkDocPreview.tsx          |    6 +-
 src/client/views/nodes/LoadingBox.tsx              |    2 +-
 src/client/views/nodes/MapBox/MapBox.tsx           |    8 +-
 src/client/views/nodes/PDFBox.tsx                  |   18 +-
 .../nodes/PhysicsBox/PhysicsSimulationBox.tsx      |   15 +-
 .../views/nodes/RecordingBox/RecordingBox.tsx      |    5 +-
 src/client/views/nodes/ScreenshotBox.tsx           |   35 +-
 src/client/views/nodes/ScriptingBox.tsx            |   96 +-
 src/client/views/nodes/VideoBox.tsx                |   18 +-
 src/client/views/nodes/WebBox.tsx                  |   47 +-
 src/client/views/nodes/WebBoxRenderer.js           |   18 +-
 src/client/views/nodes/audio/AudioWaveform.tsx     |    2 +-
 .../nodes/formattedText/DashDocCommentView.tsx     |   38 +-
 .../views/nodes/formattedText/DashDocView.tsx      |   29 +-
 .../views/nodes/formattedText/DashFieldView.tsx    |   34 +-
 .../views/nodes/formattedText/EquationEditor.tsx   |   17 +-
 .../views/nodes/formattedText/EquationView.tsx     |   22 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |   89 +-
 .../formattedText/FormattedTextBoxComment.tsx      |    4 +-
 .../views/nodes/formattedText/ParagraphNodeSpec.ts |   36 +-
 .../views/nodes/formattedText/RichTextMenu.tsx     |   42 +-
 .../views/nodes/formattedText/RichTextRules.ts     |   56 +-
 src/client/views/nodes/formattedText/marks_rts.ts  |   40 +-
 src/client/views/nodes/formattedText/nodes_rts.ts  |   91 +-
 src/client/views/pdf/GPTPopup/GPTPopup.tsx         |    7 +-
 src/client/views/pdf/PDFViewer.tsx                 |   12 +-
 src/fields/Doc.ts                                  |  160 +-
 src/fields/List.ts                                 |  104 +-
 src/fields/ObjectField.ts                          |   21 +-
 src/fields/Proxy.ts                                |   31 +-
 src/fields/RefField.ts                             |    2 +-
 src/fields/ScriptField.ts                          |   28 +-
 src/fields/util.ts                                 |  132 +-
 src/mobile/ImageUpload.tsx                         |    3 +-
 src/mobile/MobileInterface.tsx                     |    1 -
 src/pen-gestures/GestureUtils.ts                   |    5 +-
 src/server/ApiManagers/GooglePhotosManager.ts      |    6 +-
 src/server/ApiManagers/UploadManager.ts            |   14 +-
 src/server/DashStats.ts                            |    1 +
 src/server/DashUploadUtils.ts                      |   65 +-
 src/server/SharedMediaTypes.ts                     |    4 +-
 src/server/index.ts                                |    1 -
 src/server/websocket.ts                            |    5 +-
 webpack.config.js                                  |    3 +-
 140 files changed, 4387 insertions(+), 4500 deletions(-)
 delete mode 100644 src/client/util/ProsemirrorCopy/prompt.js
 delete mode 100644 src/client/views/nodes/FontIconBox/ButtonInterface.ts

(limited to 'src/client/views/nodes/formattedText/RichTextMenu.tsx')

diff --git a/package-lock.json b/package-lock.json
index 168c6d087..328110401 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -258,6 +258,7 @@
                 "@types/cookie-parser": "^1.4.6",
                 "@types/cookie-session": "^2.0.48",
                 "@types/d3": "^7.4.3",
+                "@types/dom-mediacapture-record": "^1.0.19",
                 "@types/exif": "^0.6.5",
                 "@types/express": "^4.17.21",
                 "@types/express-session": "^1.17.10",
@@ -285,10 +286,12 @@
                 "@types/request": "^2.48.12",
                 "@types/request-promise": "^4.1.51",
                 "@types/shelljs": "^0.8.15",
+                "@types/textarea-caret": "^3.0.3",
                 "@types/textfit": "^2.4.4",
                 "@types/uuid": "^10.0.0",
                 "@types/valid-url": "^1.0.7",
                 "@types/webpack": "^5.28.5",
+                "@types/webscopeio__react-textarea-autocomplete": "^4.7.5",
                 "@types/youtube": "0.0.50",
                 "chai": "^5.0.0",
                 "cross-env": "^7.0.3",
@@ -320,91 +323,91 @@
             }
         },
         "node_modules/@adobe/react-spectrum": {
-            "version": "3.35.1",
-            "resolved": "https://registry.npmjs.org/@adobe/react-spectrum/-/react-spectrum-3.35.1.tgz",
-            "integrity": "sha512-QNhsaEHv5S5Vqsk7b8aCV9F7qAnWw8VJ/Nep/SOjeiJ7vK993jEOetEhSsUIQ8VHsMKs6qkTtZr0/DKoV+Z/9w==",
+            "version": "3.36.1",
+            "resolved": "https://registry.npmjs.org/@adobe/react-spectrum/-/react-spectrum-3.36.1.tgz",
+            "integrity": "sha512-ZDxbCjFBYU3S8iEbsrKoJS5fIf91lpM44nWyY1rKwqD7Lu6Lo0cNX8g44x5pXi+PcMr2KxZOPTj4khfCqMOCvg==",
             "dependencies": {
                 "@internationalized/string": "^3.2.3",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/ssr": "^3.9.4",
-                "@react-aria/utils": "^3.24.1",
-                "@react-aria/visually-hidden": "^3.8.12",
-                "@react-spectrum/actionbar": "^3.4.5",
-                "@react-spectrum/actiongroup": "^3.10.5",
-                "@react-spectrum/avatar": "^3.0.12",
-                "@react-spectrum/badge": "^3.1.13",
-                "@react-spectrum/breadcrumbs": "^3.9.7",
-                "@react-spectrum/button": "^3.16.4",
-                "@react-spectrum/buttongroup": "^3.6.13",
-                "@react-spectrum/calendar": "^3.4.9",
-                "@react-spectrum/checkbox": "^3.9.6",
-                "@react-spectrum/combobox": "^3.12.5",
-                "@react-spectrum/contextualhelp": "^3.6.11",
-                "@react-spectrum/datepicker": "^3.9.6",
-                "@react-spectrum/dialog": "^3.8.11",
-                "@react-spectrum/divider": "^3.5.13",
-                "@react-spectrum/dnd": "^3.3.10",
-                "@react-spectrum/dropzone": "^3.0.1",
-                "@react-spectrum/filetrigger": "^3.0.1",
-                "@react-spectrum/form": "^3.7.6",
-                "@react-spectrum/icon": "^3.7.13",
-                "@react-spectrum/illustratedmessage": "^3.5.1",
-                "@react-spectrum/image": "^3.5.1",
-                "@react-spectrum/inlinealert": "^3.2.5",
-                "@react-spectrum/labeledvalue": "^3.1.14",
-                "@react-spectrum/layout": "^3.6.5",
-                "@react-spectrum/link": "^3.6.7",
-                "@react-spectrum/list": "^3.7.10",
-                "@react-spectrum/listbox": "^3.12.9",
-                "@react-spectrum/menu": "^3.19.1",
-                "@react-spectrum/meter": "^3.5.1",
-                "@react-spectrum/numberfield": "^3.9.3",
-                "@react-spectrum/overlays": "^5.6.1",
-                "@react-spectrum/picker": "^3.14.5",
-                "@react-spectrum/progress": "^3.7.7",
-                "@react-spectrum/provider": "^3.9.7",
-                "@react-spectrum/radio": "^3.7.6",
-                "@react-spectrum/searchfield": "^3.8.6",
-                "@react-spectrum/slider": "^3.6.9",
-                "@react-spectrum/statuslight": "^3.5.13",
-                "@react-spectrum/switch": "^3.5.5",
-                "@react-spectrum/table": "^3.12.10",
-                "@react-spectrum/tabs": "^3.8.10",
-                "@react-spectrum/tag": "^3.2.6",
-                "@react-spectrum/text": "^3.5.5",
-                "@react-spectrum/textfield": "^3.12.1",
-                "@react-spectrum/theme-dark": "^3.5.10",
-                "@react-spectrum/theme-default": "^3.5.10",
-                "@react-spectrum/theme-light": "^3.4.10",
-                "@react-spectrum/tooltip": "^3.6.7",
-                "@react-spectrum/view": "^3.6.10",
-                "@react-spectrum/well": "^3.4.13",
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/data": "^3.11.4",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/ssr": "^3.9.5",
+                "@react-aria/utils": "^3.25.1",
+                "@react-aria/visually-hidden": "^3.8.14",
+                "@react-spectrum/actionbar": "^3.5.1",
+                "@react-spectrum/actiongroup": "^3.10.7",
+                "@react-spectrum/avatar": "^3.0.14",
+                "@react-spectrum/badge": "^3.1.15",
+                "@react-spectrum/breadcrumbs": "^3.9.9",
+                "@react-spectrum/button": "^3.16.6",
+                "@react-spectrum/buttongroup": "^3.6.15",
+                "@react-spectrum/calendar": "^3.4.11",
+                "@react-spectrum/checkbox": "^3.9.8",
+                "@react-spectrum/combobox": "^3.13.1",
+                "@react-spectrum/contextualhelp": "^3.6.13",
+                "@react-spectrum/datepicker": "^3.10.1",
+                "@react-spectrum/dialog": "^3.8.13",
+                "@react-spectrum/divider": "^3.5.15",
+                "@react-spectrum/dnd": "^3.4.1",
+                "@react-spectrum/dropzone": "^3.0.3",
+                "@react-spectrum/filetrigger": "^3.0.3",
+                "@react-spectrum/form": "^3.7.8",
+                "@react-spectrum/icon": "^3.7.15",
+                "@react-spectrum/illustratedmessage": "^3.5.3",
+                "@react-spectrum/image": "^3.5.3",
+                "@react-spectrum/inlinealert": "^3.2.7",
+                "@react-spectrum/labeledvalue": "^3.1.16",
+                "@react-spectrum/layout": "^3.6.7",
+                "@react-spectrum/link": "^3.6.9",
+                "@react-spectrum/list": "^3.8.1",
+                "@react-spectrum/listbox": "^3.13.1",
+                "@react-spectrum/menu": "^3.20.1",
+                "@react-spectrum/meter": "^3.5.3",
+                "@react-spectrum/numberfield": "^3.9.5",
+                "@react-spectrum/overlays": "^5.6.3",
+                "@react-spectrum/picker": "^3.15.1",
+                "@react-spectrum/progress": "^3.7.9",
+                "@react-spectrum/provider": "^3.9.9",
+                "@react-spectrum/radio": "^3.7.8",
+                "@react-spectrum/searchfield": "^3.8.8",
+                "@react-spectrum/slider": "^3.6.11",
+                "@react-spectrum/statuslight": "^3.5.15",
+                "@react-spectrum/switch": "^3.5.7",
+                "@react-spectrum/table": "^3.13.1",
+                "@react-spectrum/tabs": "^3.8.12",
+                "@react-spectrum/tag": "^3.2.8",
+                "@react-spectrum/text": "^3.5.7",
+                "@react-spectrum/textfield": "^3.12.3",
+                "@react-spectrum/theme-dark": "^3.5.12",
+                "@react-spectrum/theme-default": "^3.5.12",
+                "@react-spectrum/theme-light": "^3.4.12",
+                "@react-spectrum/tooltip": "^3.6.9",
+                "@react-spectrum/view": "^3.6.12",
+                "@react-spectrum/well": "^3.4.15",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/data": "^3.11.6",
+                "@react-types/shared": "^3.24.1",
                 "client-only": "^0.0.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@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==",
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/@adobe/react-spectrum-ui/-/react-spectrum-ui-1.2.1.tgz",
+            "integrity": "sha512-wcrbEE2O/9WnEn6avBnaVRRx88S5PLFsPLr4wffzlbMfXeQsy+RMQwaJd3cbzrn18/j04Isit7f7Emfn0dhrJA==",
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@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==",
+            "version": "2.3.5",
+            "resolved": "https://registry.npmjs.org/@adobe/react-spectrum-workflow/-/react-spectrum-workflow-2.3.5.tgz",
+            "integrity": "sha512-b53VIPwPWKb/T5gzE3qs+QlGP5gVrw/LnWV3xMksDU+CRl3rzOKUwxIGiZO8ICyYh1WiyqY4myGlPU/nAynBUg==",
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@ampproject/remapping": {
@@ -544,9 +547,9 @@
             }
         },
         "node_modules/@azure/core-rest-pipeline": {
-            "version": "1.16.2",
-            "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.16.2.tgz",
-            "integrity": "sha512-Hnhm/PG9/SQ07JJyLDv3l9Qr8V3xgAe1hFoBYzt6LaalMxfL/ZqFaZf/bz5VN3pMcleCPwl8ivlS2Fjxq/iC8Q==",
+            "version": "1.16.3",
+            "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.16.3.tgz",
+            "integrity": "sha512-VxLk4AHLyqcHsfKe4MZ6IQ+D+ShuByy+RfStKfSjxJoL3WBWq17VNmrz8aT8etKzqc2nAeIyLxScjpzsS4fz8w==",
             "dependencies": {
                 "@azure/abort-controller": "^2.0.0",
                 "@azure/core-auth": "^1.4.0",
@@ -584,9 +587,9 @@
             }
         },
         "node_modules/@azure/core-util": {
-            "version": "1.9.1",
-            "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.1.tgz",
-            "integrity": "sha512-OLsq0etbHO1MA7j6FouXFghuHrAFGk+5C1imcpQ2e+0oZhYF07WLA+NW2Vqs70R7d+zOAWiWM3tbE1sXcDN66g==",
+            "version": "1.9.2",
+            "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.2.tgz",
+            "integrity": "sha512-l1Qrqhi4x1aekkV+OlcqsJa4AnAkj5p0JV8omgwjaV9OAbP41lvrMvs+CptfetKkeEaGRGSzby7sjPZEX7+kkQ==",
             "dependencies": {
                 "@azure/abort-controller": "^2.0.0",
                 "tslib": "^2.6.2"
@@ -607,9 +610,9 @@
             }
         },
         "node_modules/@azure/core-xml": {
-            "version": "1.4.2",
-            "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.4.2.tgz",
-            "integrity": "sha512-CW3MZhApe/S4iikbYKE7s83fjDBPIr2kpidX+hlGRwh7N4o1nIpQ/PfJTeioqhfqdMvRtheEl+ft64fyTaLNaA==",
+            "version": "1.4.3",
+            "resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.4.3.tgz",
+            "integrity": "sha512-D6G7FEmDiTctPKuWegX2WTrS1enKZwqYwdKTO6ZN6JMigcCehlT0/CYl+zWpI9vQ9frwwp7GQT3/owaEXgnOsA==",
             "dependencies": {
                 "fast-xml-parser": "^4.3.2",
                 "tslib": "^2.6.2"
@@ -619,9 +622,9 @@
             }
         },
         "node_modules/@azure/logger": {
-            "version": "1.1.3",
-            "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.3.tgz",
-            "integrity": "sha512-J8/cIKNQB1Fc9fuYqBVnrppiUtW+5WWJPCj/tAokC5LdSTwkWWttN+jsRgw9BLYD7JDBx7PceiqOBxJJ1tQz3Q==",
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.4.tgz",
+            "integrity": "sha512-4IXXzcCdLdlXuCG+8UKEwLA1T1NHqUfanhXYHiQTn+6sfWCZXduqbtXDGceg3Ce5QxTGo7EqmbV6Bi+aqKuClQ==",
             "dependencies": {
                 "tslib": "^2.6.2"
             },
@@ -630,9 +633,9 @@
             }
         },
         "node_modules/@azure/storage-blob": {
-            "version": "12.23.0",
-            "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.23.0.tgz",
-            "integrity": "sha512-c1KJ5R5hqR/HtvmFtTn/Y1BNMq45NUBp0LZH7yF8WFMET+wmESgEr0FVTu/Z5NonmfUjbgJZG5Nh8xHc5RdWGQ==",
+            "version": "12.24.0",
+            "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.24.0.tgz",
+            "integrity": "sha512-l8cmWM4C7RoNCBOImoFMxhTXe1Lr+8uQ/IgnhRNMpfoA9bAFWoLG4XrWm6O5rKXortreVQuD+fc1hbzWklOZbw==",
             "dependencies": {
                 "@azure/abort-controller": "^1.0.0",
                 "@azure/core-auth": "^1.4.0",
@@ -641,7 +644,7 @@
                 "@azure/core-lro": "^2.2.0",
                 "@azure/core-paging": "^1.1.1",
                 "@azure/core-rest-pipeline": "^1.10.1",
-                "@azure/core-tracing": "^1.0.0",
+                "@azure/core-tracing": "^1.1.2",
                 "@azure/core-util": "^1.6.1",
                 "@azure/core-xml": "^1.3.2",
                 "@azure/logger": "^1.0.0",
@@ -665,29 +668,29 @@
             }
         },
         "node_modules/@babel/compat-data": {
-            "version": "7.24.9",
-            "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz",
-            "integrity": "sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==",
+            "version": "7.25.2",
+            "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz",
+            "integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==",
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/core": {
-            "version": "7.24.9",
-            "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz",
-            "integrity": "sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==",
+            "version": "7.25.2",
+            "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz",
+            "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==",
             "peer": true,
             "dependencies": {
                 "@ampproject/remapping": "^2.2.0",
                 "@babel/code-frame": "^7.24.7",
-                "@babel/generator": "^7.24.9",
-                "@babel/helper-compilation-targets": "^7.24.8",
-                "@babel/helper-module-transforms": "^7.24.9",
-                "@babel/helpers": "^7.24.8",
-                "@babel/parser": "^7.24.8",
-                "@babel/template": "^7.24.7",
-                "@babel/traverse": "^7.24.8",
-                "@babel/types": "^7.24.9",
+                "@babel/generator": "^7.25.0",
+                "@babel/helper-compilation-targets": "^7.25.2",
+                "@babel/helper-module-transforms": "^7.25.2",
+                "@babel/helpers": "^7.25.0",
+                "@babel/parser": "^7.25.0",
+                "@babel/template": "^7.25.0",
+                "@babel/traverse": "^7.25.2",
+                "@babel/types": "^7.25.2",
                 "convert-source-map": "^2.0.0",
                 "debug": "^4.1.0",
                 "gensync": "^1.0.0-beta.2",
@@ -703,11 +706,11 @@
             }
         },
         "node_modules/@babel/generator": {
-            "version": "7.24.10",
-            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz",
-            "integrity": "sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==",
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz",
+            "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==",
             "dependencies": {
-                "@babel/types": "^7.24.9",
+                "@babel/types": "^7.25.0",
                 "@jridgewell/gen-mapping": "^0.3.5",
                 "@jridgewell/trace-mapping": "^0.3.25",
                 "jsesc": "^2.5.1"
@@ -740,11 +743,11 @@
             }
         },
         "node_modules/@babel/helper-compilation-targets": {
-            "version": "7.24.8",
-            "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz",
-            "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==",
+            "version": "7.25.2",
+            "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz",
+            "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==",
             "dependencies": {
-                "@babel/compat-data": "^7.24.8",
+                "@babel/compat-data": "^7.25.2",
                 "@babel/helper-validator-option": "^7.24.8",
                 "browserslist": "^4.23.1",
                 "lru-cache": "^5.1.1",
@@ -755,18 +758,16 @@
             }
         },
         "node_modules/@babel/helper-create-class-features-plugin": {
-            "version": "7.24.8",
-            "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.8.tgz",
-            "integrity": "sha512-4f6Oqnmyp2PP3olgUMmOwC3akxSm5aBYraQ6YDdKy7NcAMkDECHWG0DEnV6M2UAkERgIBhYt8S27rURPg7SxWA==",
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.0.tgz",
+            "integrity": "sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==",
             "dependencies": {
                 "@babel/helper-annotate-as-pure": "^7.24.7",
-                "@babel/helper-environment-visitor": "^7.24.7",
-                "@babel/helper-function-name": "^7.24.7",
                 "@babel/helper-member-expression-to-functions": "^7.24.8",
                 "@babel/helper-optimise-call-expression": "^7.24.7",
-                "@babel/helper-replace-supers": "^7.24.7",
+                "@babel/helper-replace-supers": "^7.25.0",
                 "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
-                "@babel/helper-split-export-declaration": "^7.24.7",
+                "@babel/traverse": "^7.25.0",
                 "semver": "^6.3.1"
             },
             "engines": {
@@ -777,9 +778,9 @@
             }
         },
         "node_modules/@babel/helper-create-regexp-features-plugin": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz",
-            "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==",
+            "version": "7.25.2",
+            "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz",
+            "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==",
             "dependencies": {
                 "@babel/helper-annotate-as-pure": "^7.24.7",
                 "regexpu-core": "^5.3.1",
@@ -807,40 +808,6 @@
                 "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
             }
         },
-        "node_modules/@babel/helper-environment-visitor": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz",
-            "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==",
-            "dependencies": {
-                "@babel/types": "^7.24.7"
-            },
-            "engines": {
-                "node": ">=6.9.0"
-            }
-        },
-        "node_modules/@babel/helper-function-name": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz",
-            "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==",
-            "dependencies": {
-                "@babel/template": "^7.24.7",
-                "@babel/types": "^7.24.7"
-            },
-            "engines": {
-                "node": ">=6.9.0"
-            }
-        },
-        "node_modules/@babel/helper-hoist-variables": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz",
-            "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==",
-            "dependencies": {
-                "@babel/types": "^7.24.7"
-            },
-            "engines": {
-                "node": ">=6.9.0"
-            }
-        },
         "node_modules/@babel/helper-member-expression-to-functions": {
             "version": "7.24.8",
             "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz",
@@ -866,15 +833,14 @@
             }
         },
         "node_modules/@babel/helper-module-transforms": {
-            "version": "7.24.9",
-            "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz",
-            "integrity": "sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==",
+            "version": "7.25.2",
+            "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz",
+            "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==",
             "dependencies": {
-                "@babel/helper-environment-visitor": "^7.24.7",
                 "@babel/helper-module-imports": "^7.24.7",
                 "@babel/helper-simple-access": "^7.24.7",
-                "@babel/helper-split-export-declaration": "^7.24.7",
-                "@babel/helper-validator-identifier": "^7.24.7"
+                "@babel/helper-validator-identifier": "^7.24.7",
+                "@babel/traverse": "^7.25.2"
             },
             "engines": {
                 "node": ">=6.9.0"
@@ -903,13 +869,13 @@
             }
         },
         "node_modules/@babel/helper-remap-async-to-generator": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz",
-            "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==",
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz",
+            "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==",
             "dependencies": {
                 "@babel/helper-annotate-as-pure": "^7.24.7",
-                "@babel/helper-environment-visitor": "^7.24.7",
-                "@babel/helper-wrap-function": "^7.24.7"
+                "@babel/helper-wrap-function": "^7.25.0",
+                "@babel/traverse": "^7.25.0"
             },
             "engines": {
                 "node": ">=6.9.0"
@@ -919,13 +885,13 @@
             }
         },
         "node_modules/@babel/helper-replace-supers": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz",
-            "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==",
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz",
+            "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==",
             "dependencies": {
-                "@babel/helper-environment-visitor": "^7.24.7",
-                "@babel/helper-member-expression-to-functions": "^7.24.7",
-                "@babel/helper-optimise-call-expression": "^7.24.7"
+                "@babel/helper-member-expression-to-functions": "^7.24.8",
+                "@babel/helper-optimise-call-expression": "^7.24.7",
+                "@babel/traverse": "^7.25.0"
             },
             "engines": {
                 "node": ">=6.9.0"
@@ -958,17 +924,6 @@
                 "node": ">=6.9.0"
             }
         },
-        "node_modules/@babel/helper-split-export-declaration": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz",
-            "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==",
-            "dependencies": {
-                "@babel/types": "^7.24.7"
-            },
-            "engines": {
-                "node": ">=6.9.0"
-            }
-        },
         "node_modules/@babel/helper-string-parser": {
             "version": "7.24.8",
             "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
@@ -994,27 +949,26 @@
             }
         },
         "node_modules/@babel/helper-wrap-function": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz",
-            "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==",
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz",
+            "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==",
             "dependencies": {
-                "@babel/helper-function-name": "^7.24.7",
-                "@babel/template": "^7.24.7",
-                "@babel/traverse": "^7.24.7",
-                "@babel/types": "^7.24.7"
+                "@babel/template": "^7.25.0",
+                "@babel/traverse": "^7.25.0",
+                "@babel/types": "^7.25.0"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/helpers": {
-            "version": "7.24.8",
-            "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz",
-            "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==",
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz",
+            "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==",
             "peer": true,
             "dependencies": {
-                "@babel/template": "^7.24.7",
-                "@babel/types": "^7.24.8"
+                "@babel/template": "^7.25.0",
+                "@babel/types": "^7.25.0"
             },
             "engines": {
                 "node": ">=6.9.0"
@@ -1035,9 +989,12 @@
             }
         },
         "node_modules/@babel/parser": {
-            "version": "7.24.8",
-            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz",
-            "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==",
+            "version": "7.25.3",
+            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz",
+            "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==",
+            "dependencies": {
+                "@babel/types": "^7.25.2"
+            },
             "bin": {
                 "parser": "bin/babel-parser.js"
             },
@@ -1046,12 +1003,26 @@
             }
         },
         "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz",
-            "integrity": "sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==",
+            "version": "7.25.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz",
+            "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==",
             "dependencies": {
-                "@babel/helper-environment-visitor": "^7.24.7",
-                "@babel/helper-plugin-utils": "^7.24.7"
+                "@babel/helper-plugin-utils": "^7.24.8",
+                "@babel/traverse": "^7.25.3"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
+        "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz",
+            "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==",
+            "dependencies": {
+                "@babel/helper-plugin-utils": "^7.24.8"
             },
             "engines": {
                 "node": ">=6.9.0"
@@ -1061,11 +1032,11 @@
             }
         },
         "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz",
-            "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==",
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz",
+            "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==",
             "dependencies": {
-                "@babel/helper-plugin-utils": "^7.24.7"
+                "@babel/helper-plugin-utils": "^7.24.8"
             },
             "engines": {
                 "node": ">=6.9.0"
@@ -1091,12 +1062,12 @@
             }
         },
         "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz",
-            "integrity": "sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==",
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz",
+            "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==",
             "dependencies": {
-                "@babel/helper-environment-visitor": "^7.24.7",
-                "@babel/helper-plugin-utils": "^7.24.7"
+                "@babel/helper-plugin-utils": "^7.24.8",
+                "@babel/traverse": "^7.25.0"
             },
             "engines": {
                 "node": ">=6.9.0"
@@ -1362,14 +1333,14 @@
             }
         },
         "node_modules/@babel/plugin-transform-async-generator-functions": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz",
-            "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==",
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.0.tgz",
+            "integrity": "sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==",
             "dependencies": {
-                "@babel/helper-environment-visitor": "^7.24.7",
-                "@babel/helper-plugin-utils": "^7.24.7",
-                "@babel/helper-remap-async-to-generator": "^7.24.7",
-                "@babel/plugin-syntax-async-generators": "^7.8.4"
+                "@babel/helper-plugin-utils": "^7.24.8",
+                "@babel/helper-remap-async-to-generator": "^7.25.0",
+                "@babel/plugin-syntax-async-generators": "^7.8.4",
+                "@babel/traverse": "^7.25.0"
             },
             "engines": {
                 "node": ">=6.9.0"
@@ -1409,11 +1380,11 @@
             }
         },
         "node_modules/@babel/plugin-transform-block-scoping": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz",
-            "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==",
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz",
+            "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==",
             "dependencies": {
-                "@babel/helper-plugin-utils": "^7.24.7"
+                "@babel/helper-plugin-utils": "^7.24.8"
             },
             "engines": {
                 "node": ">=6.9.0"
@@ -1454,17 +1425,15 @@
             }
         },
         "node_modules/@babel/plugin-transform-classes": {
-            "version": "7.24.8",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.8.tgz",
-            "integrity": "sha512-VXy91c47uujj758ud9wx+OMgheXm4qJfyhj1P18YvlrQkNOSrwsteHk+EFS3OMGfhMhpZa0A+81eE7G4QC+3CA==",
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.0.tgz",
+            "integrity": "sha512-xyi6qjr/fYU304fiRwFbekzkqVJZ6A7hOjWZd+89FVcBqPV3S9Wuozz82xdpLspckeaafntbzglaW4pqpzvtSw==",
             "dependencies": {
                 "@babel/helper-annotate-as-pure": "^7.24.7",
                 "@babel/helper-compilation-targets": "^7.24.8",
-                "@babel/helper-environment-visitor": "^7.24.7",
-                "@babel/helper-function-name": "^7.24.7",
                 "@babel/helper-plugin-utils": "^7.24.8",
-                "@babel/helper-replace-supers": "^7.24.7",
-                "@babel/helper-split-export-declaration": "^7.24.7",
+                "@babel/helper-replace-supers": "^7.25.0",
+                "@babel/traverse": "^7.25.0",
                 "globals": "^11.1.0"
             },
             "engines": {
@@ -1540,6 +1509,21 @@
                 "@babel/core": "^7.0.0-0"
             }
         },
+        "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz",
+            "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==",
+            "dependencies": {
+                "@babel/helper-create-regexp-features-plugin": "^7.25.0",
+                "@babel/helper-plugin-utils": "^7.24.8"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            },
+            "peerDependencies": {
+                "@babel/core": "^7.0.0"
+            }
+        },
         "node_modules/@babel/plugin-transform-dynamic-import": {
             "version": "7.24.7",
             "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz",
@@ -1601,13 +1585,13 @@
             }
         },
         "node_modules/@babel/plugin-transform-function-name": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz",
-            "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==",
+            "version": "7.25.1",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz",
+            "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==",
             "dependencies": {
-                "@babel/helper-compilation-targets": "^7.24.7",
-                "@babel/helper-function-name": "^7.24.7",
-                "@babel/helper-plugin-utils": "^7.24.7"
+                "@babel/helper-compilation-targets": "^7.24.8",
+                "@babel/helper-plugin-utils": "^7.24.8",
+                "@babel/traverse": "^7.25.1"
             },
             "engines": {
                 "node": ">=6.9.0"
@@ -1632,11 +1616,11 @@
             }
         },
         "node_modules/@babel/plugin-transform-literals": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz",
-            "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==",
+            "version": "7.25.2",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz",
+            "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==",
             "dependencies": {
-                "@babel/helper-plugin-utils": "^7.24.7"
+                "@babel/helper-plugin-utils": "^7.24.8"
             },
             "engines": {
                 "node": ">=6.9.0"
@@ -1706,14 +1690,14 @@
             }
         },
         "node_modules/@babel/plugin-transform-modules-systemjs": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz",
-            "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==",
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz",
+            "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==",
             "dependencies": {
-                "@babel/helper-hoist-variables": "^7.24.7",
-                "@babel/helper-module-transforms": "^7.24.7",
-                "@babel/helper-plugin-utils": "^7.24.7",
-                "@babel/helper-validator-identifier": "^7.24.7"
+                "@babel/helper-module-transforms": "^7.25.0",
+                "@babel/helper-plugin-utils": "^7.24.8",
+                "@babel/helper-validator-identifier": "^7.24.7",
+                "@babel/traverse": "^7.25.0"
             },
             "engines": {
                 "node": ">=6.9.0"
@@ -1934,15 +1918,15 @@
             }
         },
         "node_modules/@babel/plugin-transform-react-jsx": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.24.7.tgz",
-            "integrity": "sha512-+Dj06GDZEFRYvclU6k4bme55GKBEWUmByM/eoKuqg4zTNQHiApWRhQph5fxQB2wAEFvRzL1tOEj1RJ19wJrhoA==",
+            "version": "7.25.2",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.2.tgz",
+            "integrity": "sha512-KQsqEAVBpU82NM/B/N9j9WOdphom1SZH3R+2V7INrQUH+V9EBFwZsEJl8eBIVeQE62FxJCc70jzEZwqU7RcVqA==",
             "dependencies": {
                 "@babel/helper-annotate-as-pure": "^7.24.7",
                 "@babel/helper-module-imports": "^7.24.7",
-                "@babel/helper-plugin-utils": "^7.24.7",
+                "@babel/helper-plugin-utils": "^7.24.8",
                 "@babel/plugin-syntax-jsx": "^7.24.7",
-                "@babel/types": "^7.24.7"
+                "@babel/types": "^7.25.2"
             },
             "engines": {
                 "node": ">=6.9.0"
@@ -2140,18 +2124,19 @@
             }
         },
         "node_modules/@babel/preset-env": {
-            "version": "7.24.8",
-            "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.8.tgz",
-            "integrity": "sha512-vObvMZB6hNWuDxhSaEPTKCwcqkAIuDtE+bQGn4XMXne1DSLzFVY8Vmj1bm+mUQXYNN8NmaQEO+r8MMbzPr1jBQ==",
+            "version": "7.25.3",
+            "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.3.tgz",
+            "integrity": "sha512-QsYW7UeAaXvLPX9tdVliMJE7MD7M6MLYVTovRTIwhoYQVFHR1rM4wO8wqAezYi3/BpSD+NzVCZ69R6smWiIi8g==",
             "dependencies": {
-                "@babel/compat-data": "^7.24.8",
-                "@babel/helper-compilation-targets": "^7.24.8",
+                "@babel/compat-data": "^7.25.2",
+                "@babel/helper-compilation-targets": "^7.25.2",
                 "@babel/helper-plugin-utils": "^7.24.8",
                 "@babel/helper-validator-option": "^7.24.8",
-                "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7",
-                "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7",
+                "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3",
+                "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0",
+                "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0",
                 "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7",
-                "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7",
+                "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0",
                 "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
                 "@babel/plugin-syntax-async-generators": "^7.8.4",
                 "@babel/plugin-syntax-class-properties": "^7.12.13",
@@ -2172,29 +2157,30 @@
                 "@babel/plugin-syntax-top-level-await": "^7.14.5",
                 "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
                 "@babel/plugin-transform-arrow-functions": "^7.24.7",
-                "@babel/plugin-transform-async-generator-functions": "^7.24.7",
+                "@babel/plugin-transform-async-generator-functions": "^7.25.0",
                 "@babel/plugin-transform-async-to-generator": "^7.24.7",
                 "@babel/plugin-transform-block-scoped-functions": "^7.24.7",
-                "@babel/plugin-transform-block-scoping": "^7.24.7",
+                "@babel/plugin-transform-block-scoping": "^7.25.0",
                 "@babel/plugin-transform-class-properties": "^7.24.7",
                 "@babel/plugin-transform-class-static-block": "^7.24.7",
-                "@babel/plugin-transform-classes": "^7.24.8",
+                "@babel/plugin-transform-classes": "^7.25.0",
                 "@babel/plugin-transform-computed-properties": "^7.24.7",
                 "@babel/plugin-transform-destructuring": "^7.24.8",
                 "@babel/plugin-transform-dotall-regex": "^7.24.7",
                 "@babel/plugin-transform-duplicate-keys": "^7.24.7",
+                "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0",
                 "@babel/plugin-transform-dynamic-import": "^7.24.7",
                 "@babel/plugin-transform-exponentiation-operator": "^7.24.7",
                 "@babel/plugin-transform-export-namespace-from": "^7.24.7",
                 "@babel/plugin-transform-for-of": "^7.24.7",
-                "@babel/plugin-transform-function-name": "^7.24.7",
+                "@babel/plugin-transform-function-name": "^7.25.1",
                 "@babel/plugin-transform-json-strings": "^7.24.7",
-                "@babel/plugin-transform-literals": "^7.24.7",
+                "@babel/plugin-transform-literals": "^7.25.2",
                 "@babel/plugin-transform-logical-assignment-operators": "^7.24.7",
                 "@babel/plugin-transform-member-expression-literals": "^7.24.7",
                 "@babel/plugin-transform-modules-amd": "^7.24.7",
                 "@babel/plugin-transform-modules-commonjs": "^7.24.8",
-                "@babel/plugin-transform-modules-systemjs": "^7.24.7",
+                "@babel/plugin-transform-modules-systemjs": "^7.25.0",
                 "@babel/plugin-transform-modules-umd": "^7.24.7",
                 "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7",
                 "@babel/plugin-transform-new-target": "^7.24.7",
@@ -2271,9 +2257,9 @@
             "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA=="
         },
         "node_modules/@babel/runtime": {
-            "version": "7.24.8",
-            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz",
-            "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==",
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz",
+            "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==",
             "dependencies": {
                 "regenerator-runtime": "^0.14.0"
             },
@@ -2282,9 +2268,9 @@
             }
         },
         "node_modules/@babel/runtime-corejs3": {
-            "version": "7.24.8",
-            "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.8.tgz",
-            "integrity": "sha512-DXG/BhegtMHhnN7YPIvxWd303/9aXvYFD1TjNL3CD6tUrhI2LVsg3Lck0aql5TRH29n4sj3emcROypkZVUfSuA==",
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.25.0.tgz",
+            "integrity": "sha512-BOehWE7MgQ8W8Qn0CQnMtg2tHPHPulcS/5AVpFvs2KCK1ET+0WqZqPvnpRpFN81gYoFopdIEJX9Sgjw3ZBccPg==",
             "dependencies": {
                 "core-js-pure": "^3.30.2",
                 "regenerator-runtime": "^0.14.0"
@@ -2294,31 +2280,28 @@
             }
         },
         "node_modules/@babel/template": {
-            "version": "7.24.7",
-            "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz",
-            "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==",
+            "version": "7.25.0",
+            "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz",
+            "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==",
             "dependencies": {
                 "@babel/code-frame": "^7.24.7",
-                "@babel/parser": "^7.24.7",
-                "@babel/types": "^7.24.7"
+                "@babel/parser": "^7.25.0",
+                "@babel/types": "^7.25.0"
             },
             "engines": {
                 "node": ">=6.9.0"
             }
         },
         "node_modules/@babel/traverse": {
-            "version": "7.24.8",
-            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz",
-            "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==",
+            "version": "7.25.3",
+            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz",
+            "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==",
             "dependencies": {
                 "@babel/code-frame": "^7.24.7",
-                "@babel/generator": "^7.24.8",
-                "@babel/helper-environment-visitor": "^7.24.7",
-                "@babel/helper-function-name": "^7.24.7",
-                "@babel/helper-hoist-variables": "^7.24.7",
-                "@babel/helper-split-export-declaration": "^7.24.7",
-                "@babel/parser": "^7.24.8",
-                "@babel/types": "^7.24.8",
+                "@babel/generator": "^7.25.0",
+                "@babel/parser": "^7.25.3",
+                "@babel/template": "^7.25.0",
+                "@babel/types": "^7.25.2",
                 "debug": "^4.3.1",
                 "globals": "^11.1.0"
             },
@@ -2335,9 +2318,9 @@
             }
         },
         "node_modules/@babel/types": {
-            "version": "7.24.9",
-            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz",
-            "integrity": "sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==",
+            "version": "7.25.2",
+            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz",
+            "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==",
             "dependencies": {
                 "@babel/helper-string-parser": "^7.24.8",
                 "@babel/helper-validator-identifier": "^7.24.7",
@@ -2411,9 +2394,9 @@
             "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
         },
         "node_modules/@emotion/cache": {
-            "version": "11.13.0",
-            "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.0.tgz",
-            "integrity": "sha512-hPV345J/tH0Cwk2wnU/3PBzORQ9HeX+kQSbwI+jslzpRCHE6fSGTohswksA/Ensr8znPzwfzKZCmAM9Lmlhp7g==",
+            "version": "11.13.1",
+            "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz",
+            "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==",
             "dependencies": {
                 "@emotion/memoize": "^0.9.0",
                 "@emotion/sheet": "^1.4.0",
@@ -2637,9 +2620,9 @@
             }
         },
         "node_modules/@eslint/js": {
-            "version": "9.7.0",
-            "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.7.0.tgz",
-            "integrity": "sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==",
+            "version": "9.8.0",
+            "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.8.0.tgz",
+            "integrity": "sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==",
             "dev": true,
             "engines": {
                 "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2673,29 +2656,29 @@
             }
         },
         "node_modules/@floating-ui/core": {
-            "version": "1.6.5",
-            "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz",
-            "integrity": "sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA==",
+            "version": "1.6.7",
+            "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.7.tgz",
+            "integrity": "sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==",
             "dependencies": {
-                "@floating-ui/utils": "^0.2.5"
+                "@floating-ui/utils": "^0.2.7"
             }
         },
         "node_modules/@floating-ui/dom": {
-            "version": "1.6.8",
-            "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz",
-            "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==",
+            "version": "1.6.10",
+            "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.10.tgz",
+            "integrity": "sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==",
             "dependencies": {
                 "@floating-ui/core": "^1.6.0",
-                "@floating-ui/utils": "^0.2.5"
+                "@floating-ui/utils": "^0.2.7"
             }
         },
         "node_modules/@floating-ui/react": {
-            "version": "0.26.20",
-            "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.20.tgz",
-            "integrity": "sha512-RixKJJG92fcIsVoqrFr4Onpzh7hlOx4U7NV4aLhMLmtvjZ5oTB/WzXaANYUZATKqXvvW7t9sCxtzejip26N5Ag==",
+            "version": "0.26.22",
+            "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.22.tgz",
+            "integrity": "sha512-LNv4azPt8SpT4WW7Kku5JNVjLk2GcS0bGGjFTAgqOONRFo9r/aaGHHPpdiIuQbB1t8shmWyWqTTUDmZ9fcNshg==",
             "dependencies": {
                 "@floating-ui/react-dom": "^2.1.1",
-                "@floating-ui/utils": "^0.2.5",
+                "@floating-ui/utils": "^0.2.7",
                 "tabbable": "^6.0.0"
             },
             "peerDependencies": {
@@ -2716,9 +2699,9 @@
             }
         },
         "node_modules/@floating-ui/utils": {
-            "version": "0.2.5",
-            "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz",
-            "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ=="
+            "version": "0.2.7",
+            "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.7.tgz",
+            "integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA=="
         },
         "node_modules/@formatjs/ecma402-abstract": {
             "version": "2.0.0",
@@ -2933,9 +2916,9 @@
             }
         },
         "node_modules/@internationalized/date": {
-            "version": "3.5.4",
-            "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.5.4.tgz",
-            "integrity": "sha512-qoVJVro+O0rBaw+8HPjUB1iH8Ihf8oziEnqMnvhJUSuVIrHOuZ6eNLHNvzXJKUvAtaDiqMnRlg8Z2mgh09BlUw==",
+            "version": "3.5.5",
+            "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.5.5.tgz",
+            "integrity": "sha512-H+CfYvOZ0LTJeeLOqm19E3uj/4YjrmOFtBufDHPfvtI80hFAMqtrp7oCACpe4Cil5l8S0Qu/9dYfZc/5lY8WQQ==",
             "dependencies": {
                 "@swc/helpers": "^0.5.0"
             }
@@ -3558,9 +3541,9 @@
             }
         },
         "node_modules/@jsonjoy.com/json-pack": {
-            "version": "1.0.4",
-            "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.0.4.tgz",
-            "integrity": "sha512-aOcSN4MeAtFROysrbqG137b7gaDDSmVrl5mpo6sT/w+kcXpWnzhMjmY/Fh/sDx26NBxyIE7MB1seqLeCAzy9Sg==",
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.0.tgz",
+            "integrity": "sha512-zlQONA+msXPPwHWZMKFVS78ewFczIll5lXiVPwFPCZUsrOKdxc2AvxU1HoNBmMRhqDZUR9HkC3UOm+6pME6Xsg==",
             "dependencies": {
                 "@jsonjoy.com/base64": "^1.1.1",
                 "@jsonjoy.com/util": "^1.1.2",
@@ -3579,9 +3562,9 @@
             }
         },
         "node_modules/@jsonjoy.com/util": {
-            "version": "1.2.0",
-            "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.2.0.tgz",
-            "integrity": "sha512-4B8B+3vFsY4eo33DMKyJPlQ3sBMpPFUZK2dr3O3rXrOGKKbYG44J0XSFkDo1VOQiri5HFEhIeVvItjR2xcazmg==",
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.3.0.tgz",
+            "integrity": "sha512-Cebt4Vk7k1xHy87kHY7KSPLT77A7Ev7IfOblyLZhtYEhrdQ6fX4EoLq3xOQ3O/DRMEh2ok5nyC180E+ABS8Wmw==",
             "engines": {
                 "node": ">=10.0"
             },
@@ -3783,18 +3766,18 @@
             }
         },
         "node_modules/@mui/core-downloads-tracker": {
-            "version": "5.16.4",
-            "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.4.tgz",
-            "integrity": "sha512-rNdHXhclwjEZnK+//3SR43YRx0VtjdHnUFhMSGYmAMJve+KiwEja/41EYh8V3pZKqF2geKyfcFUenTfDTYUR4w==",
+            "version": "5.16.6",
+            "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.6.tgz",
+            "integrity": "sha512-kytg6LheUG42V8H/o/Ptz3olSO5kUXW9zF0ox18VnblX6bO2yif1FPItgc3ey1t5ansb1+gbe7SatntqusQupg==",
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/mui-org"
             }
         },
         "node_modules/@mui/icons-material": {
-            "version": "5.16.4",
-            "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.4.tgz",
-            "integrity": "sha512-j9/CWctv6TH6Dou2uR2EH7UOgu79CW/YcozxCYVLJ7l03pCsiOlJ5sBArnWJxJ+nGkFwyL/1d1k8JEPMDR125A==",
+            "version": "5.16.6",
+            "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.6.tgz",
+            "integrity": "sha512-ceNGjoXheH9wbIFa1JHmSc9QVjJUvh18KvHrR4/FkJCSi9HXJ+9ee1kUhCOEFfuxNF8UB6WWVrIUOUgRd70t0A==",
             "dependencies": {
                 "@babel/runtime": "^7.23.9"
             },
@@ -3817,15 +3800,15 @@
             }
         },
         "node_modules/@mui/material": {
-            "version": "5.16.4",
-            "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.4.tgz",
-            "integrity": "sha512-dBnh3/zRYgEVIS3OE4oTbujse3gifA0qLMmuUk13ywsDCbngJsdgwW5LuYeiT5pfA8PGPGSqM7mxNytYXgiMCw==",
+            "version": "5.16.6",
+            "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.6.tgz",
+            "integrity": "sha512-0LUIKBOIjiFfzzFNxXZBRAyr9UQfmTAFzbt6ziOU2FDXhorNN2o3N9/32mNJbCA8zJo2FqFU6d3dtoqUDyIEfA==",
             "dependencies": {
                 "@babel/runtime": "^7.23.9",
-                "@mui/core-downloads-tracker": "^5.16.4",
-                "@mui/system": "^5.16.4",
+                "@mui/core-downloads-tracker": "^5.16.6",
+                "@mui/system": "^5.16.6",
                 "@mui/types": "^7.2.15",
-                "@mui/utils": "^5.16.4",
+                "@mui/utils": "^5.16.6",
                 "@popperjs/core": "^2.11.8",
                 "@types/react-transition-group": "^4.4.10",
                 "clsx": "^2.1.0",
@@ -3861,12 +3844,12 @@
             }
         },
         "node_modules/@mui/private-theming": {
-            "version": "5.16.4",
-            "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.4.tgz",
-            "integrity": "sha512-ZsAm8cq31SJ37SVWLRlu02v9SRthxnfQofaiv14L5Bht51B0dz6yQEoVU/V8UduZDCCIrWkBHuReVfKhE/UuXA==",
+            "version": "5.16.6",
+            "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.6.tgz",
+            "integrity": "sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==",
             "dependencies": {
                 "@babel/runtime": "^7.23.9",
-                "@mui/utils": "^5.16.4",
+                "@mui/utils": "^5.16.6",
                 "prop-types": "^15.8.1"
             },
             "engines": {
@@ -3887,9 +3870,9 @@
             }
         },
         "node_modules/@mui/styled-engine": {
-            "version": "5.16.4",
-            "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.4.tgz",
-            "integrity": "sha512-0+mnkf+UiAmTVB8PZFqOhqf729Yh0Cxq29/5cA3VAyDVTRIUUQ8FXQhiAhUIbijFmM72rY80ahFPXIm4WDbzcA==",
+            "version": "5.16.6",
+            "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.6.tgz",
+            "integrity": "sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g==",
             "dependencies": {
                 "@babel/runtime": "^7.23.9",
                 "@emotion/cache": "^11.11.0",
@@ -3918,15 +3901,15 @@
             }
         },
         "node_modules/@mui/system": {
-            "version": "5.16.4",
-            "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.4.tgz",
-            "integrity": "sha512-ET1Ujl2/8hbsD611/mqUuNArMCGv/fIWO/f8B3ZqF5iyPHM2aS74vhTNyjytncc4i6dYwGxNk+tLa7GwjNS0/w==",
+            "version": "5.16.6",
+            "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.6.tgz",
+            "integrity": "sha512-5xgyJjBIMPw8HIaZpfbGAaFYPwImQn7Nyh+wwKWhvkoIeDosQ1ZMVrbTclefi7G8hNmqhip04duYwYpbBFnBgw==",
             "dependencies": {
                 "@babel/runtime": "^7.23.9",
-                "@mui/private-theming": "^5.16.4",
-                "@mui/styled-engine": "^5.16.4",
+                "@mui/private-theming": "^5.16.6",
+                "@mui/styled-engine": "^5.16.6",
                 "@mui/types": "^7.2.15",
-                "@mui/utils": "^5.16.4",
+                "@mui/utils": "^5.16.6",
                 "clsx": "^2.1.0",
                 "csstype": "^3.1.3",
                 "prop-types": "^15.8.1"
@@ -3970,11 +3953,12 @@
             }
         },
         "node_modules/@mui/utils": {
-            "version": "5.16.4",
-            "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.4.tgz",
-            "integrity": "sha512-nlppYwq10TBIFqp7qxY0SvbACOXeOjeVL3pOcDsK0FT8XjrEXh9/+lkg8AEIzD16z7YfiJDQjaJG2OLkE7BxNg==",
+            "version": "5.16.6",
+            "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz",
+            "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==",
             "dependencies": {
                 "@babel/runtime": "^7.23.9",
+                "@mui/types": "^7.2.15",
                 "@types/prop-types": "^15.7.12",
                 "clsx": "^2.1.1",
                 "prop-types": "^15.8.1",
@@ -4148,372 +4132,387 @@
             }
         },
         "node_modules/@react-aria/actiongroup": {
-            "version": "3.7.5",
-            "resolved": "https://registry.npmjs.org/@react-aria/actiongroup/-/actiongroup-3.7.5.tgz",
-            "integrity": "sha512-asJk6WN6MhtwqWzVx7zkakhTbrpk1XhJbxF2piGlk2pTCh8zUCnMjvFAmMdQN+voj5lEW4/CZNfrblNDwzCimQ==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/list": "^3.10.5",
-                "@react-types/actiongroup": "^3.4.9",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.7.7",
+            "resolved": "https://registry.npmjs.org/@react-aria/actiongroup/-/actiongroup-3.7.7.tgz",
+            "integrity": "sha512-qkbCnMYt32ZWN8X7ycup/kbdaQLENJ+uzy3gRI5VY06RwN+btdvT8seZl1xR0n7qfdDCZxmd5WaKbXA0gl3bBA==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/list": "^3.10.7",
+                "@react-types/actiongroup": "^3.4.11",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/breadcrumbs": {
-            "version": "3.5.13",
-            "resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.13.tgz",
-            "integrity": "sha512-G1Gqf/P6kVdfs94ovwP18fTWuIxadIQgHsXS08JEVcFVYMjb9YjqnEBaohUxD1tq2WldMbYw53ahQblT4NTG+g==",
-            "dependencies": {
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/link": "^3.7.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-types/breadcrumbs": "^3.7.5",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.5.15",
+            "resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.15.tgz",
+            "integrity": "sha512-KJ7678hwKbacz6dyY4aOJlgtV91PtuSnlWGR+AsK88WwHhpjjTjLLTSRepjbQ35GuQuoYokM4mmfaS/I0nblhw==",
+            "dependencies": {
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/link": "^3.7.3",
+                "@react-aria/utils": "^3.25.1",
+                "@react-types/breadcrumbs": "^3.7.7",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/button": {
-            "version": "3.9.5",
-            "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.9.5.tgz",
-            "integrity": "sha512-dgcYR6j8WDOMLKuVrtxzx4jIC05cVKDzc+HnPO8lNkBAOfjcuN5tkGRtIjLtqjMvpZHhQT5aDbgFpIaZzxgFIg==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/toggle": "^3.7.4",
-                "@react-types/button": "^3.9.4",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.9.7",
+            "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.9.7.tgz",
+            "integrity": "sha512-xwE6uatbbn3KbNSc0dyDnOo539HJM2cqCPfjiQGt8O9cFbpQSmx76Fj4WotU3BwT7ZVbcAC8D206CgF1C2cDcQ==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/toggle": "^3.7.6",
+                "@react-types/button": "^3.9.6",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/calendar": {
-            "version": "3.5.8",
-            "resolved": "https://registry.npmjs.org/@react-aria/calendar/-/calendar-3.5.8.tgz",
-            "integrity": "sha512-Whlp4CeAA5/ZkzrAHUv73kgIRYjw088eYGSc+cvSOCxfrc/2XkBm9rNrnSBv0DvhJ8AG0Fjz3vYakTmF3BgZBw==",
+            "version": "3.5.10",
+            "resolved": "https://registry.npmjs.org/@react-aria/calendar/-/calendar-3.5.10.tgz",
+            "integrity": "sha512-5PokdIHAH+CAd6vMHFW9mg77I5tC0FQglYsCEI9ikhCnL5xlt3FmJjLtOs3UJQaWgrd4cdVd0oINpPafJ9ydhA==",
             "dependencies": {
-                "@internationalized/date": "^3.5.4",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
+                "@internationalized/date": "^3.5.5",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
                 "@react-aria/live-announcer": "^3.3.4",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/calendar": "^3.5.1",
-                "@react-types/button": "^3.9.4",
-                "@react-types/calendar": "^3.4.6",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/calendar": "^3.5.3",
+                "@react-types/button": "^3.9.6",
+                "@react-types/calendar": "^3.4.8",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/checkbox": {
-            "version": "3.14.3",
-            "resolved": "https://registry.npmjs.org/@react-aria/checkbox/-/checkbox-3.14.3.tgz",
-            "integrity": "sha512-EtBJL6iu0gvrw3A4R7UeVLR6diaVk/mh4kFBc7c8hQjpEJweRr4hmJT3hrNg3MBcTWLxFiMEXPGgWEwXDBygtA==",
-            "dependencies": {
-                "@react-aria/form": "^3.0.5",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/label": "^3.7.8",
-                "@react-aria/toggle": "^3.10.4",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/checkbox": "^3.6.5",
-                "@react-stately/form": "^3.0.3",
-                "@react-stately/toggle": "^3.7.4",
-                "@react-types/checkbox": "^3.8.1",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.14.5",
+            "resolved": "https://registry.npmjs.org/@react-aria/checkbox/-/checkbox-3.14.5.tgz",
+            "integrity": "sha512-On8m66CNi1LvbDeDo355au0K66ayIjo0nDe4oe85aNsR/owyzz8hXNPAFuh98owQVMsKt4596FZICAVSMzzhJg==",
+            "dependencies": {
+                "@react-aria/form": "^3.0.7",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/label": "^3.7.10",
+                "@react-aria/toggle": "^3.10.6",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/checkbox": "^3.6.7",
+                "@react-stately/form": "^3.0.5",
+                "@react-stately/toggle": "^3.7.6",
+                "@react-types/checkbox": "^3.8.3",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
+            }
+        },
+        "node_modules/@react-aria/collections": {
+            "version": "3.0.0-alpha.3",
+            "resolved": "https://registry.npmjs.org/@react-aria/collections/-/collections-3.0.0-alpha.3.tgz",
+            "integrity": "sha512-SKsoQrCuz4zIVMwKGz0WcFoRbIP0H8+eRU2XzjmWX9KlRdrfeqIBOxuiU8XO3or0aHdbBI/bC/YtCjVzix5Lrg==",
+            "dependencies": {
+                "@react-aria/ssr": "^3.9.5",
+                "@react-aria/utils": "^3.25.1",
+                "@react-types/shared": "^3.24.1",
+                "@swc/helpers": "^0.5.0",
+                "use-sync-external-store": "^1.2.0"
+            },
+            "peerDependencies": {
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/color": {
-            "version": "3.0.0-beta.33",
-            "resolved": "https://registry.npmjs.org/@react-aria/color/-/color-3.0.0-beta.33.tgz",
-            "integrity": "sha512-nhqnIHYm5p6MbuF3cC6lnqzG7MjwBsBd0DtpO+ByFYO+zxpMMbeC5R+1SFxvapR4uqmAzTotbtiUCGsG+SUaIg==",
-            "dependencies": {
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/numberfield": "^3.11.3",
-                "@react-aria/slider": "^3.7.8",
-                "@react-aria/spinbutton": "^3.6.5",
-                "@react-aria/textfield": "^3.14.5",
-                "@react-aria/utils": "^3.24.1",
-                "@react-aria/visually-hidden": "^3.8.12",
-                "@react-stately/color": "^3.6.1",
-                "@react-stately/form": "^3.0.3",
-                "@react-types/color": "3.0.0-beta.25",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.0.0-rc.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/color/-/color-3.0.0-rc.1.tgz",
+            "integrity": "sha512-oP9PE0Xpo9uQ/TtH1x8iWhsjtk4OTIoTFdQZyoDsj8d84sqRv6Og9ajBZ/VTaneNK1n4NrPSx+qWfXu+SrWlDg==",
+            "dependencies": {
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/numberfield": "^3.11.5",
+                "@react-aria/slider": "^3.7.10",
+                "@react-aria/spinbutton": "^3.6.7",
+                "@react-aria/textfield": "^3.14.7",
+                "@react-aria/utils": "^3.25.1",
+                "@react-aria/visually-hidden": "^3.8.14",
+                "@react-stately/color": "^3.7.1",
+                "@react-stately/form": "^3.0.5",
+                "@react-types/color": "3.0.0-rc.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/combobox": {
-            "version": "3.9.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.9.1.tgz",
-            "integrity": "sha512-SpK92dCmT8qn8aEcUAihRQrBb5LZUhwIbDExFII8PvUvEFy/PoQHXIo3j1V29WkutDBDpMvBv/6XRCHGXPqrhQ==",
+            "version": "3.10.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.10.1.tgz",
+            "integrity": "sha512-B0zjX66HEqjPFnunYR0quAqwVJ6U0ez1eqBp25/611Dtzh3JHUovQmTE0xGGTjRe6N6qJg0VHVr2eRO/D0A+Lw==",
             "dependencies": {
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/listbox": "^3.12.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/listbox": "^3.13.1",
                 "@react-aria/live-announcer": "^3.3.4",
-                "@react-aria/menu": "^3.14.1",
-                "@react-aria/overlays": "^3.22.1",
-                "@react-aria/selection": "^3.18.1",
-                "@react-aria/textfield": "^3.14.5",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/combobox": "^3.8.4",
-                "@react-stately/form": "^3.0.3",
-                "@react-types/button": "^3.9.4",
-                "@react-types/combobox": "^3.11.1",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/menu": "^3.15.1",
+                "@react-aria/overlays": "^3.23.1",
+                "@react-aria/selection": "^3.19.1",
+                "@react-aria/textfield": "^3.14.7",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/combobox": "^3.9.1",
+                "@react-stately/form": "^3.0.5",
+                "@react-types/button": "^3.9.6",
+                "@react-types/combobox": "^3.12.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/datepicker": {
-            "version": "3.10.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.10.1.tgz",
-            "integrity": "sha512-4HZL593nrNMa1GjBmWEN/OTvNS6d3/16G1YJWlqiUlv11ADulSbqBIjMmkgwrJVFcjrgqtXFy+yyrTA/oq94Zw==",
+            "version": "3.11.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.11.1.tgz",
+            "integrity": "sha512-yEEuDt/ynt7bTfd/9RD1EiLPysWhbgSYSpn5PHVz7I2XORvNPpyamyAgz3+oFiLFLC/zy0qrG7e6V1rvI1NBzw==",
             "dependencies": {
-                "@internationalized/date": "^3.5.4",
+                "@internationalized/date": "^3.5.5",
                 "@internationalized/number": "^3.5.3",
                 "@internationalized/string": "^3.2.3",
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/form": "^3.0.5",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/label": "^3.7.8",
-                "@react-aria/spinbutton": "^3.6.5",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/datepicker": "^3.9.4",
-                "@react-stately/form": "^3.0.3",
-                "@react-types/button": "^3.9.4",
-                "@react-types/calendar": "^3.4.6",
-                "@react-types/datepicker": "^3.7.4",
-                "@react-types/dialog": "^3.5.10",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/form": "^3.0.7",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/label": "^3.7.10",
+                "@react-aria/spinbutton": "^3.6.7",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/datepicker": "^3.10.1",
+                "@react-stately/form": "^3.0.5",
+                "@react-types/button": "^3.9.6",
+                "@react-types/calendar": "^3.4.8",
+                "@react-types/datepicker": "^3.8.1",
+                "@react-types/dialog": "^3.5.12",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/dialog": {
-            "version": "3.5.14",
-            "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.14.tgz",
-            "integrity": "sha512-oqDCjQ8hxe3GStf48XWBf2CliEnxlR9GgSYPHJPUc69WBj68D9rVcCW3kogJnLAnwIyf3FnzbX4wSjvUa88sAQ==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/overlays": "^3.22.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-types/dialog": "^3.5.10",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.5.16",
+            "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.16.tgz",
+            "integrity": "sha512-2clBSQQaoqCjAUkHnMA/noZ1ZnFbEVU67fL9M1QfokezAyLAlyCyD9XSed6+Td/Ncj80N3/Lax65XAlvWCyOlg==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/overlays": "^3.23.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-types/dialog": "^3.5.12",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/dnd": {
-            "version": "3.6.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.6.1.tgz",
-            "integrity": "sha512-6WnujUTD+cIYZVF/B+uXdHyJ+WSpbYa8jH282epvY4FUAq1qLmen12/HHcoj/5dswKQe8X6EM3OhkQM89d9vFw==",
+            "version": "3.7.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.7.1.tgz",
+            "integrity": "sha512-p3/pc8p2fGd4s+Qj4SfRPJjZFStuuXqRNyDQxd9AAFYUWcCQxwDOqtiTZmfvs7Hvl0PUuysHW6Q5v7ABRjVr7w==",
             "dependencies": {
                 "@internationalized/string": "^3.2.3",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
                 "@react-aria/live-announcer": "^3.3.4",
-                "@react-aria/overlays": "^3.22.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/dnd": "^3.3.1",
-                "@react-types/button": "^3.9.4",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/overlays": "^3.23.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/dnd": "^3.4.1",
+                "@react-types/button": "^3.9.6",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/focus": {
-            "version": "3.17.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.17.1.tgz",
-            "integrity": "sha512-FLTySoSNqX++u0nWZJPPN5etXY0WBxaIe/YuL/GTEeuqUIuC/2bJSaw5hlsM6T2yjy6Y/VAxBcKSdAFUlU6njQ==",
+            "version": "3.18.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.18.1.tgz",
+            "integrity": "sha512-N0Cy61WCIv+57mbqC7hiZAsB+3rF5n4JKabxUmg/2RTJL6lq7hJ5N4gx75ymKxkN8GnVDwt4pKZah48Wopa5jw==",
             "dependencies": {
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0",
                 "clsx": "^2.0.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/form": {
-            "version": "3.0.5",
-            "resolved": "https://registry.npmjs.org/@react-aria/form/-/form-3.0.5.tgz",
-            "integrity": "sha512-n290jRwrrRXO3fS82MyWR+OKN7yznVesy5Q10IclSTVYHHI3VI53xtAPr/WzNjJR1um8aLhOcDNFKwnNIUUCsQ==",
+            "version": "3.0.7",
+            "resolved": "https://registry.npmjs.org/@react-aria/form/-/form-3.0.7.tgz",
+            "integrity": "sha512-VIsKP/KytJPOLRQl0NxWWS1bQELPBuW3vRjmmhBrtgPFmp0uCLhjPBkP6A4uIVj1E/JtAocyHN3DNq4+IJGQCg==",
             "dependencies": {
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/form": "^3.0.3",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/form": "^3.0.5",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/grid": {
-            "version": "3.9.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.9.1.tgz",
-            "integrity": "sha512-fGEZqAEaS8mqzV/II3N4ndoNWegIcbh+L3PmKbXdpKKUP8VgMs/WY5rYl5WAF0f5RoFwXqx3ibDLeR9tKj/bOg==",
+            "version": "3.10.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.10.1.tgz",
+            "integrity": "sha512-7dSgiYVQapBtPV4SIit+9fJ1qoEjtp+PXffJkWAPtGbg/jJ4b0jcVzykH7ARD4w/6jAJN/oVSfrKZqFPoLAd9w==",
             "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
                 "@react-aria/live-announcer": "^3.3.4",
-                "@react-aria/selection": "^3.18.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/grid": "^3.8.7",
-                "@react-stately/selection": "^3.15.1",
-                "@react-stately/virtualizer": "^3.7.1",
-                "@react-types/checkbox": "^3.8.1",
-                "@react-types/grid": "^3.2.6",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/selection": "^3.19.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/grid": "^3.9.1",
+                "@react-stately/selection": "^3.16.1",
+                "@react-types/checkbox": "^3.8.3",
+                "@react-types/grid": "^3.2.8",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/gridlist": {
-            "version": "3.8.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/gridlist/-/gridlist-3.8.1.tgz",
-            "integrity": "sha512-vVPkkA+Ct0NDcpnNm/tnYaBumg0fP9pXxsPLqL1rxvsTyj1PaIpFTZ4corabPTbTDExZwUSTS3LG1n+o1OvBtQ==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/grid": "^3.9.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/selection": "^3.18.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/list": "^3.10.5",
-                "@react-stately/tree": "^3.8.1",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.9.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/gridlist/-/gridlist-3.9.1.tgz",
+            "integrity": "sha512-cue2KCI4WyVmL3j9tZx7xG7gUJ7UyRbawzRTcocJukOmpeoyRaw/robrIYK2Pd//GhRbIMAoo4iOyZk5j7vEww==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/grid": "^3.10.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/selection": "^3.19.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/list": "^3.10.7",
+                "@react-stately/tree": "^3.8.3",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/i18n": {
-            "version": "3.11.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.11.1.tgz",
-            "integrity": "sha512-vuiBHw1kZruNMYeKkTGGnmPyMnM5T+gT8bz97H1FqIq1hQ6OPzmtBZ6W6l6OIMjeHI5oJo4utTwfZl495GALFQ==",
+            "version": "3.12.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.12.1.tgz",
+            "integrity": "sha512-0q3gyogF9Ekah+9LOo6tcfshxsk2Ope+KdbtFHJVhznedMxn6RpHGcVur5ImbQ1dYafA5CmjBUGJW70b56+BGA==",
             "dependencies": {
-                "@internationalized/date": "^3.5.4",
+                "@internationalized/date": "^3.5.5",
                 "@internationalized/message": "^3.1.4",
                 "@internationalized/number": "^3.5.3",
                 "@internationalized/string": "^3.2.3",
-                "@react-aria/ssr": "^3.9.4",
-                "@react-aria/utils": "^3.24.1",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/ssr": "^3.9.5",
+                "@react-aria/utils": "^3.25.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/interactions": {
-            "version": "3.21.3",
-            "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.21.3.tgz",
-            "integrity": "sha512-BWIuf4qCs5FreDJ9AguawLVS0lV9UU+sK4CCnbCNNmYqOWY+1+gRXCsnOM32K+oMESBxilAjdHW5n1hsMqYMpA==",
+            "version": "3.22.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.22.1.tgz",
+            "integrity": "sha512-5TLzQaDAQQ5C70yG8GInbO4wIylKY67RfTIIwQPGR/4n5OIjbUD8BOj3NuSsuZ/frUPaBXo1VEBBmSO23fxkjw==",
             "dependencies": {
-                "@react-aria/ssr": "^3.9.4",
-                "@react-aria/utils": "^3.24.1",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/ssr": "^3.9.5",
+                "@react-aria/utils": "^3.25.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/label": {
-            "version": "3.7.8",
-            "resolved": "https://registry.npmjs.org/@react-aria/label/-/label-3.7.8.tgz",
-            "integrity": "sha512-MzgTm5+suPA3KX7Ug6ZBK2NX9cin/RFLsv1BdafJ6CZpmUSpWnGE/yQfYUB7csN7j31OsZrD3/P56eShYWAQfg==",
+            "version": "3.7.10",
+            "resolved": "https://registry.npmjs.org/@react-aria/label/-/label-3.7.10.tgz",
+            "integrity": "sha512-e5XVHA+OUK0aIwr4nHcnIj0z1kUryGaJWYYD2OGkkIltyUCKmwpRqdx8LQYbO4HGsJhvC3hJgidFdGcQwHHPYw==",
             "dependencies": {
-                "@react-aria/utils": "^3.24.1",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/link": {
-            "version": "3.7.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/link/-/link-3.7.1.tgz",
-            "integrity": "sha512-a4IaV50P3fXc7DQvEIPYkJJv26JknFbRzFT5MJOMgtzuhyJoQdILEUK6XHYjcSSNCA7uLgzpojArVk5Hz3lCpw==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-types/link": "^3.5.5",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.7.3",
+            "resolved": "https://registry.npmjs.org/@react-aria/link/-/link-3.7.3.tgz",
+            "integrity": "sha512-dOwzxzo7LF4djBfRC8GcIhuTpDkNUIMT6ykQRV1a3749kgrr10YLascsO/l66k60i2k0T2oClkzfefYEK6WZeA==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-types/link": "^3.5.7",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/listbox": {
-            "version": "3.12.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.12.1.tgz",
-            "integrity": "sha512-7JiUp0NGykbv/HgSpmTY1wqhuf/RmjFxs1HZcNaTv8A+DlzgJYc7yQqFjP3ZA/z5RvJFuuIxggIYmgIFjaRYdA==",
-            "dependencies": {
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/label": "^3.7.8",
-                "@react-aria/selection": "^3.18.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/list": "^3.10.5",
-                "@react-types/listbox": "^3.4.9",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.13.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.13.1.tgz",
+            "integrity": "sha512-b5Nu+5d5shJbxpy4s6OXvMlMzm+PVbs3L6CtoHlsKe8cAlSWD340vPHCOGYLwZApIBewepOBvRWgeAF8IDI04w==",
+            "dependencies": {
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/label": "^3.7.10",
+                "@react-aria/selection": "^3.19.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/list": "^3.10.7",
+                "@react-types/listbox": "^3.5.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/live-announcer": {
@@ -4525,237 +4524,237 @@
             }
         },
         "node_modules/@react-aria/menu": {
-            "version": "3.14.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/menu/-/menu-3.14.1.tgz",
-            "integrity": "sha512-BYliRb38uAzq05UOFcD5XkjA5foQoXRbcH3ZufBsc4kvh79BcP1PMW6KsXKGJ7dC/PJWUwCui6QL1kUg8PqMHA==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/overlays": "^3.22.1",
-                "@react-aria/selection": "^3.18.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/menu": "^3.7.1",
-                "@react-stately/tree": "^3.8.1",
-                "@react-types/button": "^3.9.4",
-                "@react-types/menu": "^3.9.9",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.15.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/menu/-/menu-3.15.1.tgz",
+            "integrity": "sha512-ZBTMZiJ17j6t7epcsjd0joAzsMKO31KLJHPtWAEfk1JkBxrMoirISPN8O1CeK/uBX++VaWSrDZfFe1EjrOwKuA==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/overlays": "^3.23.1",
+                "@react-aria/selection": "^3.19.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/menu": "^3.8.1",
+                "@react-stately/tree": "^3.8.3",
+                "@react-types/button": "^3.9.6",
+                "@react-types/menu": "^3.9.11",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/meter": {
-            "version": "3.4.13",
-            "resolved": "https://registry.npmjs.org/@react-aria/meter/-/meter-3.4.13.tgz",
-            "integrity": "sha512-oG6KvHQM3ri93XkYQkgEaMKSMO9KNDVpcW1MUqFfqyUXHFBRZRrJB4BTXMZ4nyjheFVQjVboU51fRwoLjOzThg==",
+            "version": "3.4.15",
+            "resolved": "https://registry.npmjs.org/@react-aria/meter/-/meter-3.4.15.tgz",
+            "integrity": "sha512-OUAzgmfiyEvBF+h9NlG7s8jvrGNTqj/zAWyUWEh5FMEjKFrDfni6awwFoRs164QqmUvRBNC0/eKv3Ghd2GIkRA==",
             "dependencies": {
-                "@react-aria/progress": "^3.4.13",
-                "@react-types/meter": "^3.4.1",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/progress": "^3.4.15",
+                "@react-types/meter": "^3.4.3",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/numberfield": {
-            "version": "3.11.3",
-            "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.11.3.tgz",
-            "integrity": "sha512-QQ9ZTzBbRI8d9ksaBWm6YVXbgv+5zzUsdxVxwzJVXLznvivoORB8rpdFJzUEWVCo25lzoBxluCEPYtLOxP1B0w==",
-            "dependencies": {
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/spinbutton": "^3.6.5",
-                "@react-aria/textfield": "^3.14.5",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/form": "^3.0.3",
-                "@react-stately/numberfield": "^3.9.3",
-                "@react-types/button": "^3.9.4",
-                "@react-types/numberfield": "^3.8.3",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.11.5",
+            "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.11.5.tgz",
+            "integrity": "sha512-cfJzU7SWsksKiLjfubSj5lR18ebQ7IbYaMQZbxdpZSPOANHIiktaxjPK4Nz7cqZ+HZ/6tQEirpY0iqpLx35CSw==",
+            "dependencies": {
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/spinbutton": "^3.6.7",
+                "@react-aria/textfield": "^3.14.7",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/form": "^3.0.5",
+                "@react-stately/numberfield": "^3.9.5",
+                "@react-types/button": "^3.9.6",
+                "@react-types/numberfield": "^3.8.5",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/overlays": {
-            "version": "3.22.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.22.1.tgz",
-            "integrity": "sha512-GHiFMWO4EQ6+j6b5QCnNoOYiyx1Gk8ZiwLzzglCI4q1NY5AG2EAmfU4Z1+Gtrf2S5Y0zHbumC7rs9GnPoGLUYg==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/ssr": "^3.9.4",
-                "@react-aria/utils": "^3.24.1",
-                "@react-aria/visually-hidden": "^3.8.12",
-                "@react-stately/overlays": "^3.6.7",
-                "@react-types/button": "^3.9.4",
-                "@react-types/overlays": "^3.8.7",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.23.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.23.1.tgz",
+            "integrity": "sha512-qNV3pGThvRXjhdHCfqN9Eg4uD+nFm2DoK6d5e9LFd1+xCkKbT88afDBIcLmeG7fgfmukb1sNmzCJQJt8Svk54g==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/ssr": "^3.9.5",
+                "@react-aria/utils": "^3.25.1",
+                "@react-aria/visually-hidden": "^3.8.14",
+                "@react-stately/overlays": "^3.6.9",
+                "@react-types/button": "^3.9.6",
+                "@react-types/overlays": "^3.8.9",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/progress": {
-            "version": "3.4.13",
-            "resolved": "https://registry.npmjs.org/@react-aria/progress/-/progress-3.4.13.tgz",
-            "integrity": "sha512-YBV9bOO5JzKvG8QCI0IAA00o6FczMgIDiK8Q9p5gKorFMatFUdRayxlbIPoYHMi+PguLil0jHgC7eOyaUcrZ0g==",
-            "dependencies": {
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/label": "^3.7.8",
-                "@react-aria/utils": "^3.24.1",
-                "@react-types/progress": "^3.5.4",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.4.15",
+            "resolved": "https://registry.npmjs.org/@react-aria/progress/-/progress-3.4.15.tgz",
+            "integrity": "sha512-wlx8pgEet3mlq5Skjy7yV1DfQiEg79tZtojpb5YGN2dIAH8sxClrKOSJRVce0fy9IXVCKrQxjQNXPNUIojK5Rg==",
+            "dependencies": {
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/label": "^3.7.10",
+                "@react-aria/utils": "^3.25.1",
+                "@react-types/progress": "^3.5.6",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/radio": {
-            "version": "3.10.4",
-            "resolved": "https://registry.npmjs.org/@react-aria/radio/-/radio-3.10.4.tgz",
-            "integrity": "sha512-3fmoMcQtCpgjTwJReFjnvIE/C7zOZeCeWUn4JKDqz9s1ILYsC3Rk5zZ4q66tFn6v+IQnecrKT52wH6+hlVLwTA==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/form": "^3.0.5",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/label": "^3.7.8",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/radio": "^3.10.4",
-                "@react-types/radio": "^3.8.1",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.10.6",
+            "resolved": "https://registry.npmjs.org/@react-aria/radio/-/radio-3.10.6.tgz",
+            "integrity": "sha512-Cr7kiTUWw+HOEdFHztqrFlSXvwuzOCTMbwNkziTyc9fualIX6UDilykND2ctfBgkM4qH7SgQt+SxAIwTdevsKg==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/form": "^3.0.7",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/label": "^3.7.10",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/radio": "^3.10.6",
+                "@react-types/radio": "^3.8.3",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/searchfield": {
-            "version": "3.7.5",
-            "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.7.5.tgz",
-            "integrity": "sha512-h1sMUOWjhevaKKUHab/luHbM6yiyeN57L4RxZU0IIc9Ww0h5Rp2GUuKZA3pcdPiExHje0aijcImL3wBHEbKAzw==",
-            "dependencies": {
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/textfield": "^3.14.5",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/searchfield": "^3.5.3",
-                "@react-types/button": "^3.9.4",
-                "@react-types/searchfield": "^3.5.5",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.7.7",
+            "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.7.7.tgz",
+            "integrity": "sha512-2f087PCR8X5LYyLnvjCIOV27xjjTCkDFPnQaC7XSPCfzDYGM8utCR56JfZMqHnjcMnVNoiEg7EjSBBrh7I2bnQ==",
+            "dependencies": {
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/textfield": "^3.14.7",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/searchfield": "^3.5.5",
+                "@react-types/button": "^3.9.6",
+                "@react-types/searchfield": "^3.5.7",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/select": {
-            "version": "3.14.5",
-            "resolved": "https://registry.npmjs.org/@react-aria/select/-/select-3.14.5.tgz",
-            "integrity": "sha512-s8jixBuTUNdKWRHe2tIJqp55ORHeUObGMw1s7PQRRVrrHPdNSYseAOI9B2W7qpl3hKhvjJg40UW+45mcb1WKbw==",
-            "dependencies": {
-                "@react-aria/form": "^3.0.5",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/label": "^3.7.8",
-                "@react-aria/listbox": "^3.12.1",
-                "@react-aria/menu": "^3.14.1",
-                "@react-aria/selection": "^3.18.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-aria/visually-hidden": "^3.8.12",
-                "@react-stately/select": "^3.6.4",
-                "@react-types/button": "^3.9.4",
-                "@react-types/select": "^3.9.4",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.14.7",
+            "resolved": "https://registry.npmjs.org/@react-aria/select/-/select-3.14.7.tgz",
+            "integrity": "sha512-qZy5oX6P8SGrdv4bHb8iVMIVv+vLuo7UwOJtsQ1FUORIsZmBEz0RyfgYdzlueMcZNoQ9JgLYtrK2e0h6AmJOlg==",
+            "dependencies": {
+                "@react-aria/form": "^3.0.7",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/label": "^3.7.10",
+                "@react-aria/listbox": "^3.13.1",
+                "@react-aria/menu": "^3.15.1",
+                "@react-aria/selection": "^3.19.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-aria/visually-hidden": "^3.8.14",
+                "@react-stately/select": "^3.6.6",
+                "@react-types/button": "^3.9.6",
+                "@react-types/select": "^3.9.6",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/selection": {
-            "version": "3.18.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/selection/-/selection-3.18.1.tgz",
-            "integrity": "sha512-GSqN2jX6lh7v+ldqhVjAXDcrWS3N4IsKXxO6L6Ygsye86Q9q9Mq9twWDWWu5IjHD6LoVZLUBCMO+ENGbOkyqeQ==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/selection": "^3.15.1",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.19.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/selection/-/selection-3.19.1.tgz",
+            "integrity": "sha512-mbExvq2Omi60sTWFGjwcNz1ja2P8VDsxWAqSypHRTyqXhtgqbv8V/v8Gp+7BmVPH1YHcbhztl6rvUZTDOSszzw==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/selection": "^3.16.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/separator": {
-            "version": "3.3.13",
-            "resolved": "https://registry.npmjs.org/@react-aria/separator/-/separator-3.3.13.tgz",
-            "integrity": "sha512-hofA6JCPnAOqSE9vxnq7Dkazr7Kb2A0I5sR16fOG7ddjYRc/YEY5Nv7MWfKUGU0kNFHkgNjsDAILERtLechzeA==",
+            "version": "3.4.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/separator/-/separator-3.4.1.tgz",
+            "integrity": "sha512-bZ+GQ936Y+WXAtsQjJdEMgYeqmqjhU90+wOlRGjmGdwf+/ht2yzBpeRuHEYUbE6F0iis/YoVc+b8ppAtPna/kA==",
             "dependencies": {
-                "@react-aria/utils": "^3.24.1",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/slider": {
-            "version": "3.7.8",
-            "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.7.8.tgz",
-            "integrity": "sha512-MYvPcM0K8jxEJJicUK2+WxUkBIM/mquBxOTOSSIL3CszA80nXIGVnLlCUnQV3LOUzpWtabbWaZokSPtGgOgQOw==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/label": "^3.7.8",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/slider": "^3.5.4",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/slider": "^3.7.3",
+            "version": "3.7.10",
+            "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.7.10.tgz",
+            "integrity": "sha512-QmBn87sDkncS/uhcrH0MxUN7bcEo8cHYcWk+gk7mibdIpyxyVDPKh7v7ZsosmAJLzjS0yb2ec1/Q5Oldfg1k/A==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/label": "^3.7.10",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/slider": "^3.5.6",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/slider": "^3.7.5",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/spinbutton": {
-            "version": "3.6.5",
-            "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.6.5.tgz",
-            "integrity": "sha512-0aACBarF/Xr/7ixzjVBTQ0NBwwwsoGkf5v6AVFVMTC0uYMXHTALvRs+ULHjHMa5e/cX/aPlEvaVT7jfSs+Xy9Q==",
+            "version": "3.6.7",
+            "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.6.7.tgz",
+            "integrity": "sha512-OCimp4yXoFIgh6WAMOls5DDDRDRO75ZFic3YA6wLWTRNHxo1Lj8S90i1A6pakY6bi4hdBCKmj4DnFSNKAw1iWg==",
             "dependencies": {
-                "@react-aria/i18n": "^3.11.1",
+                "@react-aria/i18n": "^3.12.1",
                 "@react-aria/live-announcer": "^3.3.4",
-                "@react-aria/utils": "^3.24.1",
-                "@react-types/button": "^3.9.4",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-types/button": "^3.9.6",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/ssr": {
-            "version": "3.9.4",
-            "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.4.tgz",
-            "integrity": "sha512-4jmAigVq409qcJvQyuorsmBR4+9r3+JEC60wC+Y0MZV0HCtTmm8D9guYXlJMdx0SSkgj0hHAyFm/HvPNFofCoQ==",
+            "version": "3.9.5",
+            "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.5.tgz",
+            "integrity": "sha512-xEwGKoysu+oXulibNUSkXf8itW0npHHTa6c4AyYeZIJyRoegeteYuFpZUBPtIDE8RfHdNsSmE1ssOkxRnwbkuQ==",
             "dependencies": {
                 "@swc/helpers": "^0.5.0"
             },
@@ -4763,220 +4762,221 @@
                 "node": ">= 12"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/switch": {
-            "version": "3.6.4",
-            "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.6.4.tgz",
-            "integrity": "sha512-2nVqz4ZuJyof47IpGSt3oZRmp+EdS8wzeDYgf42WHQXrx4uEOk1mdLJ20+NnsYhj/2NHZsvXVrjBeKMjlMs+0w==",
+            "version": "3.6.6",
+            "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.6.6.tgz",
+            "integrity": "sha512-+dZOX1utODlx5dC90DtwnXd9nvln9HxMffBj/gmMT1/cD/RmXfjvymfjTsTMwvHhqCew9yfpvod0ZWwj3BkLGw==",
             "dependencies": {
-                "@react-aria/toggle": "^3.10.4",
-                "@react-stately/toggle": "^3.7.4",
-                "@react-types/switch": "^3.5.3",
+                "@react-aria/toggle": "^3.10.6",
+                "@react-stately/toggle": "^3.7.6",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/switch": "^3.5.5",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/table": {
-            "version": "3.14.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/table/-/table-3.14.1.tgz",
-            "integrity": "sha512-WaPgQe4zQF5OaluO5rm+Y2nEoFR63vsLd4BT4yjK1uaFhKhDY2Zk+1SCVQvBLLKS4WK9dhP05nrNzT0vp/ZPOw==",
+            "version": "3.15.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/table/-/table-3.15.1.tgz",
+            "integrity": "sha512-jVDLxp6Y/9M6y45c1I6u6msJ9dBg2I7Cu/FlSaK6HthTpN23UXuGw1oWuAjbfqi31nVXHWBwjCZkGKTdMjLf5A==",
             "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/grid": "^3.9.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/grid": "^3.10.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
                 "@react-aria/live-announcer": "^3.3.4",
-                "@react-aria/utils": "^3.24.1",
-                "@react-aria/visually-hidden": "^3.8.12",
-                "@react-stately/collections": "^3.10.7",
+                "@react-aria/utils": "^3.25.1",
+                "@react-aria/visually-hidden": "^3.8.14",
+                "@react-stately/collections": "^3.10.9",
                 "@react-stately/flags": "^3.0.3",
-                "@react-stately/table": "^3.11.8",
-                "@react-stately/virtualizer": "^3.7.1",
-                "@react-types/checkbox": "^3.8.1",
-                "@react-types/grid": "^3.2.6",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/table": "^3.9.5",
+                "@react-stately/table": "^3.12.1",
+                "@react-types/checkbox": "^3.8.3",
+                "@react-types/grid": "^3.2.8",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/table": "^3.10.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/tabs": {
-            "version": "3.9.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/tabs/-/tabs-3.9.1.tgz",
-            "integrity": "sha512-S5v/0sRcOaSXaJYZuuy1ZVzYc7JD4sDyseG1133GjyuNjJOFHgoWMb+b4uxNIJbZxnLgynn/ZDBZSO+qU+fIxw==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/selection": "^3.18.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/tabs": "^3.6.6",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/tabs": "^3.3.7",
+            "version": "3.9.3",
+            "resolved": "https://registry.npmjs.org/@react-aria/tabs/-/tabs-3.9.3.tgz",
+            "integrity": "sha512-J1KOCdx4eSyMMeNCvO8BIz8E8xez12B+cYbM4BbJzWlcfMboGYUnM0lvI8QSpFPa/H9LkAhp7BJnl9IZeIBzoA==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/selection": "^3.19.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/tabs": "^3.6.8",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/tabs": "^3.3.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/tag": {
-            "version": "3.4.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/tag/-/tag-3.4.1.tgz",
-            "integrity": "sha512-gcIGPYZ2OBwMT4IHnlczEezKlxr0KRPL/mSfm2Q91GE027ZGOJnqusH9az6DX1qxrQx8x3vRdqYT2KmuefkrBQ==",
-            "dependencies": {
-                "@react-aria/gridlist": "^3.8.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/label": "^3.7.8",
-                "@react-aria/selection": "^3.18.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/list": "^3.10.5",
-                "@react-types/button": "^3.9.4",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.4.3",
+            "resolved": "https://registry.npmjs.org/@react-aria/tag/-/tag-3.4.3.tgz",
+            "integrity": "sha512-BqXKazX9YHvt6+qzGTu770V0FqGVefzz03hmnV2IVb+zYchXBv3WYbWVy46s/D5zTePOAXdpitQHxqy5rh+hgw==",
+            "dependencies": {
+                "@react-aria/gridlist": "^3.9.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/label": "^3.7.10",
+                "@react-aria/selection": "^3.19.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/list": "^3.10.7",
+                "@react-types/button": "^3.9.6",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/textfield": {
-            "version": "3.14.5",
-            "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.14.5.tgz",
-            "integrity": "sha512-hj7H+66BjB1iTKKaFXwSZBZg88YT+wZboEXZ0DNdQB2ytzoz/g045wBItUuNi4ZjXI3P+0AOZznVMYadWBAmiA==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/form": "^3.0.5",
-                "@react-aria/label": "^3.7.8",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/form": "^3.0.3",
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/textfield": "^3.9.3",
+            "version": "3.14.7",
+            "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.14.7.tgz",
+            "integrity": "sha512-1cWCG6vkjlwJuRTXKbKl9P0Q/0Li5pnMafZqDDWfDOlkS5dFGxYG6QFfoaYp7N6XMoNkXiculnCssfrQ+8hWgA==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/form": "^3.0.7",
+                "@react-aria/label": "^3.7.10",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/form": "^3.0.5",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/textfield": "^3.9.5",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/toggle": {
-            "version": "3.10.4",
-            "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.10.4.tgz",
-            "integrity": "sha512-bRk+CdB8QzrSyGNjENXiTWxfzYKRw753iwQXsEAU7agPCUdB8cZJyrhbaUoD0rwczzTp2zDbZ9rRbUPdsBE2YQ==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/toggle": "^3.7.4",
-                "@react-types/checkbox": "^3.8.1",
+            "version": "3.10.6",
+            "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.10.6.tgz",
+            "integrity": "sha512-AGlbtB1b8grrtjbiW5Au0LKYzxR83RHbHhaUkFwajyYRGyuEzr3Y03OiveoPB+DayA8Gz3H1ZVmW++8JZQOWHw==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/toggle": "^3.7.6",
+                "@react-types/checkbox": "^3.8.3",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/toolbar": {
-            "version": "3.0.0-beta.5",
-            "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.5.tgz",
-            "integrity": "sha512-c8spY7aeLI6L+ygdXvEbAzaT41vExsxZ1Ld0t7BB+6iEF3nyBNJHshjkgdR7nv8FLgNk0no4tj0GTq4Jj4UqHQ==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.0.0-beta.7",
+            "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.7.tgz",
+            "integrity": "sha512-PKaXD2qiWcVOn/bX07ipamTc6OlqypqcQRGG7WUL0ZXWfV6AfL7GFPS1B2Jh7Etetq68Ynyuo6R4jT4Jypsjdg==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/tooltip": {
-            "version": "3.7.4",
-            "resolved": "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.7.4.tgz",
-            "integrity": "sha512-+XRx4HlLYqWY3fB8Z60bQi/rbWDIGlFUtXYbtoa1J+EyRWfhpvsYImP8qeeNO/vgjUtDy1j9oKa8p6App9mBMQ==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/tooltip": "^3.4.9",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/tooltip": "^3.4.9",
+            "version": "3.7.6",
+            "resolved": "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.7.6.tgz",
+            "integrity": "sha512-JvRAMTcMju/KBOtISjVKKtIDzG3J1r6xK+mZTvu6ArM7DdeMBM5A8Lwk0bJ8dhr+YybiM9rR3hoZv3/E7IIYVw==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/tooltip": "^3.4.11",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/tooltip": "^3.4.11",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/tree": {
-            "version": "3.0.0-alpha.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/tree/-/tree-3.0.0-alpha.1.tgz",
-            "integrity": "sha512-CucyeJ4VeAvWO5UJHt/l9JO65CVtsOVUctMOVNCQS77Isqp3olX9pvfD3LXt8fD5Ph2g0Q/b7siVpX5ieVB32g==",
-            "dependencies": {
-                "@react-aria/gridlist": "^3.8.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/selection": "^3.18.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/tree": "^3.8.1",
-                "@react-types/button": "^3.9.4",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.0.0-alpha.3",
+            "resolved": "https://registry.npmjs.org/@react-aria/tree/-/tree-3.0.0-alpha.3.tgz",
+            "integrity": "sha512-o/9B+PVSUYxDM1KxQ/Pl1CytPtIagyidmasd10266hWfwzvPA0ZyakBwIEFj+ROnr9buAdP+A4sOTRo+a6g+YQ==",
+            "dependencies": {
+                "@react-aria/gridlist": "^3.9.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/selection": "^3.19.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/tree": "^3.8.3",
+                "@react-types/button": "^3.9.6",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/utils": {
-            "version": "3.24.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.24.1.tgz",
-            "integrity": "sha512-O3s9qhPMd6n42x9sKeJ3lhu5V1Tlnzhu6Yk8QOvDuXf7UGuUjXf9mzfHJt1dYzID4l9Fwm8toczBzPM9t0jc8Q==",
+            "version": "3.25.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.25.1.tgz",
+            "integrity": "sha512-5Uj864e7T5+yj78ZfLnfHqmypLiqW2mN+nsdslog2z5ssunTqjolVeM15ootXskjISlZ7MojLpq97kIC4nlnAw==",
             "dependencies": {
-                "@react-aria/ssr": "^3.9.4",
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/ssr": "^3.9.5",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0",
                 "clsx": "^2.0.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/virtualizer": {
-            "version": "3.10.1",
-            "resolved": "https://registry.npmjs.org/@react-aria/virtualizer/-/virtualizer-3.10.1.tgz",
-            "integrity": "sha512-y34w+n/B3nwwj18QHIZlkNj5Fn2rt5CbQE4BBWAM8jYZ5ypwF77i2toxhGTuk1Oo1/hgTX7JYIgDIAQbNraBcg==",
-            "dependencies": {
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/virtualizer": "^3.7.1",
-                "@react-types/shared": "^3.23.1",
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/virtualizer/-/virtualizer-4.0.1.tgz",
+            "integrity": "sha512-JZ6X0l38ZwBU/JgeLwkDA8mknRxqO1nYSVaPZHgOg8fd9BzMRWBjse7VW+Uf09P0uAEFElwlB+RY8UDx+W/Fmg==",
+            "dependencies": {
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-stately/virtualizer": "^4.0.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-aria/visually-hidden": {
-            "version": "3.8.12",
-            "resolved": "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.12.tgz",
-            "integrity": "sha512-Bawm+2Cmw3Xrlr7ARzl2RLtKh0lNUdJ0eNqzWcyx4c0VHUAWtThmH5l+HRqFUGzzutFZVo89SAy40BAbd0gjVw==",
+            "version": "3.8.14",
+            "resolved": "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.14.tgz",
+            "integrity": "sha512-DV3yagbAgO4ywQTq6D/AxcIaTC8c77r/SxlIMhQBMQ6vScJWTCh6zFG55wmLe3NKqvRrowv1OstlmYfZQ4v/XA==",
             "dependencies": {
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-google-maps/api": {
@@ -5007,1114 +5007,1118 @@
             "integrity": "sha512-x9ibmsP0ZVqzyCo1Pitbw+4b6iEXRw/r1TCy3vOUR3eKrzWLnHYZMR325BkZW2r8fnuWE/V3Fp4QZOP9qYORCw=="
         },
         "node_modules/@react-spectrum/actionbar": {
-            "version": "3.4.5",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/actionbar/-/actionbar-3.4.5.tgz",
-            "integrity": "sha512-9+b3B5he/zwyk+1pHc5l8/q6mBy+zKkphha2kBScbj/2XRHTwwlcamBJMANMYfVirQT9UP5FHGhHV6OiRgZLrA==",
+            "version": "3.5.1",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/actionbar/-/actionbar-3.5.1.tgz",
+            "integrity": "sha512-yPqUjIbRaUPZtips+FXYNCNv5Yyqcd5MjN238C6kUXoEOMNRfXiO3QLO7JRMywwi4EWPz4GjH+329/VoV+iXsw==",
             "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
                 "@react-aria/live-announcer": "^3.3.4",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/actiongroup": "^3.10.5",
-                "@react-spectrum/button": "^3.16.4",
-                "@react-spectrum/overlays": "^5.6.1",
-                "@react-spectrum/text": "^3.5.5",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/collections": "^3.10.7",
-                "@react-types/actionbar": "^3.1.7",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/actiongroup": "^3.10.7",
+                "@react-spectrum/button": "^3.16.6",
+                "@react-spectrum/overlays": "^5.6.3",
+                "@react-spectrum/text": "^3.5.7",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/collections": "^3.10.9",
+                "@react-types/actionbar": "^3.1.9",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/actiongroup": {
-            "version": "3.10.5",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/actiongroup/-/actiongroup-3.10.5.tgz",
-            "integrity": "sha512-KHSuZvCD5XyOA4wz2iu85JQem2Y01pniWTfhzGLPfJG+1OdOCt+C0mO/jU0DL4NM6UwzdLy4JfvUij/xBsLrRw==",
-            "dependencies": {
-                "@react-aria/actiongroup": "^3.7.5",
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/button": "^3.16.4",
-                "@react-spectrum/menu": "^3.19.1",
-                "@react-spectrum/text": "^3.5.5",
-                "@react-spectrum/tooltip": "^3.6.7",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/list": "^3.10.5",
-                "@react-types/actiongroup": "^3.4.9",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
-                "@spectrum-icons/workflow": "^4.2.12",
+            "version": "3.10.7",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/actiongroup/-/actiongroup-3.10.7.tgz",
+            "integrity": "sha512-IJqr+TOEZRPWJ+9OSGZvZBPQZG/mp++2awKIVPJzOCWOWu81oIu8fMRgnuQev+RoAJWKBXR1sh5EPMmLJHSzqA==",
+            "dependencies": {
+                "@react-aria/actiongroup": "^3.7.7",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/button": "^3.16.6",
+                "@react-spectrum/menu": "^3.20.1",
+                "@react-spectrum/text": "^3.5.7",
+                "@react-spectrum/tooltip": "^3.6.9",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/list": "^3.10.7",
+                "@react-types/actiongroup": "^3.4.11",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
+                "@spectrum-icons/workflow": "^4.2.14",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.2.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/avatar": {
-            "version": "3.0.12",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/avatar/-/avatar-3.0.12.tgz",
-            "integrity": "sha512-H5dZG+mPiSHlST2TBMfMR7mOf+g5C0i9Q2+aMMQ8khphXLFL4fj5GqxgEE7Mi5efS+raofwXJ/dM+AedsSl6WQ==",
-            "dependencies": {
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/avatar": "^3.0.7",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.0.14",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/avatar/-/avatar-3.0.14.tgz",
+            "integrity": "sha512-QQRRQEO4mHdW9UtXomEJw9gAfOliqhMaYMJYWlwytCAipErrllae7U9VK0AaECokfNBib3Klhp8b/4VtLKr+dw==",
+            "dependencies": {
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/avatar": "^3.0.9",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.2.1",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/badge": {
-            "version": "3.1.13",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/badge/-/badge-3.1.13.tgz",
-            "integrity": "sha512-zfsmbw3hxYWxuySQZTMNkxI5vD1XktHNIBqDUYNaDu8A+GVaORI9pcrua4T2YXyQrw1hYXbqVAmeISJYURajjA==",
-            "dependencies": {
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/text": "^3.5.5",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/badge": "^3.1.9",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.1.15",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/badge/-/badge-3.1.15.tgz",
+            "integrity": "sha512-fCjEXw5ej0GzXTk7g3PkhPKj0sS1mQ6XtrhGIwM1g78AYdv0+no7Zsew1ojRQJpOhWDqJPj2QNRJplouGTI3uA==",
+            "dependencies": {
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/text": "^3.5.7",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/badge": "^3.1.11",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/breadcrumbs": {
-            "version": "3.9.7",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/breadcrumbs/-/breadcrumbs-3.9.7.tgz",
-            "integrity": "sha512-1wA9cgSugaplYmT4z/WiUAZsOcXPWN+8sx43Wc5foS3qUSOLpW4+43sjDTVmzVlbXYuZ4byxf1nrXZNEqCWZXA==",
-            "dependencies": {
-                "@react-aria/breadcrumbs": "^3.5.13",
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/button": "^3.16.4",
-                "@react-spectrum/menu": "^3.19.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/collections": "^3.10.7",
-                "@react-types/breadcrumbs": "^3.7.5",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
+            "version": "3.9.9",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/breadcrumbs/-/breadcrumbs-3.9.9.tgz",
+            "integrity": "sha512-JQ9OGQJTV68ZxCc7cNNa1ob5G+AAXYD3BjAd81ZfUwxjzEnHPXu/FJWHC7H8zaCGno6Pqq8nhgBHNR1TBiQqGw==",
+            "dependencies": {
+                "@react-aria/breadcrumbs": "^3.5.15",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/button": "^3.16.6",
+                "@react-spectrum/menu": "^3.20.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/collections": "^3.10.9",
+                "@react-types/breadcrumbs": "^3.7.7",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/button": {
-            "version": "3.16.4",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/button/-/button-3.16.4.tgz",
-            "integrity": "sha512-ksPZkmhkz8fJuu+cC9GM5e1pJ0d2sWmkU9sqKn5SNfWh9ngemgvShtkqkuQoz6ThH+MI3n/n4JhFd+UhJ/lILA==",
-            "dependencies": {
-                "@react-aria/button": "^3.9.5",
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/progress": "^3.7.7",
-                "@react-spectrum/text": "^3.5.5",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/toggle": "^3.7.4",
-                "@react-types/button": "^3.9.4",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
+            "version": "3.16.6",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/button/-/button-3.16.6.tgz",
+            "integrity": "sha512-dNJldfq9xQ1pN29km0+vTmhlmRpx8ZXF5K/1edvdLpPtpI3a6iJIBxGh8v4uQFNaAN3Er7mdHdvguHkPsnTD3w==",
+            "dependencies": {
+                "@react-aria/button": "^3.9.7",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/progress": "^3.7.9",
+                "@react-spectrum/text": "^3.5.7",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/toggle": "^3.7.6",
+                "@react-types/button": "^3.9.6",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/buttongroup": {
-            "version": "3.6.13",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/buttongroup/-/buttongroup-3.6.13.tgz",
-            "integrity": "sha512-QUNTtDMiY/ydrpUYq8fO0kkssdnTEJsIxlfhbQa3ZEpEObjgt9XbAehNKPelWATwLNQ/gY8o21m9GT1m7J/8zg==",
-            "dependencies": {
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/buttongroup": "^3.3.9",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.6.15",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/buttongroup/-/buttongroup-3.6.15.tgz",
+            "integrity": "sha512-QelfmkrH1bWDGTJyVRQxOVSJsn1dv3aNGlgd3u9HvBDQyZItRl+qiflOCZnrtPgX7SBUBVxGooW+3/AunIBkrw==",
+            "dependencies": {
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/buttongroup": "^3.3.11",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/calendar": {
-            "version": "3.4.9",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/calendar/-/calendar-3.4.9.tgz",
-            "integrity": "sha512-5546bmMQ/v3dscTDFx0llEQ3jA23vkcjbiY7hIad5a9bpXHPQSuIeREelFPtsVUzsD3f3v2BL2nDAt6SPLVqCA==",
-            "dependencies": {
-                "@internationalized/date": "^3.5.4",
-                "@react-aria/calendar": "^3.5.8",
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-aria/visually-hidden": "^3.8.12",
-                "@react-spectrum/button": "^3.16.4",
-                "@react-spectrum/label": "^3.16.6",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/calendar": "^3.5.1",
-                "@react-types/button": "^3.9.4",
-                "@react-types/calendar": "^3.4.6",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
+            "version": "3.4.11",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/calendar/-/calendar-3.4.11.tgz",
+            "integrity": "sha512-NZZvdWDOhkNphUa4if1gM4x+tUDZb7fiMoTjp0/RSN2VaBl8Z5tt6R5hP9IAWvjfyPH8rv2zI40yO6ts/QCgcg==",
+            "dependencies": {
+                "@internationalized/date": "^3.5.5",
+                "@react-aria/calendar": "^3.5.10",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-aria/visually-hidden": "^3.8.14",
+                "@react-spectrum/button": "^3.16.6",
+                "@react-spectrum/label": "^3.16.8",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/calendar": "^3.5.3",
+                "@react-types/button": "^3.9.6",
+                "@react-types/calendar": "^3.4.8",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/checkbox": {
-            "version": "3.9.6",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/checkbox/-/checkbox-3.9.6.tgz",
-            "integrity": "sha512-aU4bDFwaiC2hpqOFv9vbUw20V6VlMO7pn1P8Q/qUfNxWVzPY03rJC0Gqcq8NQy2zofmm4tDBJKKOF1F4amGTyw==",
-            "dependencies": {
-                "@react-aria/checkbox": "^3.14.3",
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-spectrum/form": "^3.7.6",
-                "@react-spectrum/label": "^3.16.6",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/checkbox": "^3.6.5",
-                "@react-stately/toggle": "^3.7.4",
-                "@react-types/checkbox": "^3.8.1",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
+            "version": "3.9.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/checkbox/-/checkbox-3.9.8.tgz",
+            "integrity": "sha512-qOwzemGpa+Qj9ZmwDhFtCd0OkqCY+c6yw8iggCfA0A+jrreSexkOAtUo6JIGg6Vsh44oqM44PKKMgvbpW1LXJw==",
+            "dependencies": {
+                "@react-aria/checkbox": "^3.14.5",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-spectrum/form": "^3.7.8",
+                "@react-spectrum/label": "^3.16.8",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/checkbox": "^3.6.7",
+                "@react-stately/toggle": "^3.7.6",
+                "@react-types/checkbox": "^3.8.3",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0",
-                "react-aria-components": "^1.2.1"
+                "react-aria-components": "^1.3.1"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/combobox": {
-            "version": "3.12.5",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/combobox/-/combobox-3.12.5.tgz",
-            "integrity": "sha512-S6TA8FrPm0ibLkeulki2S0DsUqy/hEcTVTvvic7qIRyURN/J+DQMQDWmy+Zzz9mxJr8qdJAoWSArBVWtxKhMKg==",
-            "dependencies": {
-                "@react-aria/button": "^3.9.5",
-                "@react-aria/combobox": "^3.9.1",
-                "@react-aria/dialog": "^3.5.14",
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/form": "^3.0.5",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/label": "^3.7.8",
-                "@react-aria/overlays": "^3.22.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/button": "^3.16.4",
-                "@react-spectrum/form": "^3.7.6",
-                "@react-spectrum/label": "^3.16.6",
-                "@react-spectrum/listbox": "^3.12.9",
-                "@react-spectrum/overlays": "^5.6.1",
-                "@react-spectrum/progress": "^3.7.7",
-                "@react-spectrum/textfield": "^3.12.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/combobox": "^3.8.4",
-                "@react-types/button": "^3.9.4",
-                "@react-types/combobox": "^3.11.1",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
+            "version": "3.13.1",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/combobox/-/combobox-3.13.1.tgz",
+            "integrity": "sha512-p6Wt8TCvaE/ljDpRZQEuGjxvFkXiIwElz3Fq/qoV6qhdeXbm8GxEwkfzpcBk2SgvjVAAWgQYcmUJVav+R5J0/g==",
+            "dependencies": {
+                "@react-aria/button": "^3.9.7",
+                "@react-aria/combobox": "^3.10.1",
+                "@react-aria/dialog": "^3.5.16",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/form": "^3.0.7",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/label": "^3.7.10",
+                "@react-aria/overlays": "^3.23.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/button": "^3.16.6",
+                "@react-spectrum/form": "^3.7.8",
+                "@react-spectrum/label": "^3.16.8",
+                "@react-spectrum/listbox": "^3.13.1",
+                "@react-spectrum/overlays": "^5.6.3",
+                "@react-spectrum/progress": "^3.7.9",
+                "@react-spectrum/textfield": "^3.12.3",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/combobox": "^3.9.1",
+                "@react-types/button": "^3.9.6",
+                "@react-types/combobox": "^3.12.1",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/contextualhelp": {
-            "version": "3.6.11",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/contextualhelp/-/contextualhelp-3.6.11.tgz",
-            "integrity": "sha512-mQimyXdwXyZWFWO/7BdHZ46YzCQThjnHGGMmlv2y+YfqaOqoP3UTQb4D6noSbV1M6zKJgMq5timhVo81Sujk9Q==",
-            "dependencies": {
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/button": "^3.16.4",
-                "@react-spectrum/dialog": "^3.8.11",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/contextualhelp": "^3.2.10",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/workflow": "^4.2.12",
+            "version": "3.6.13",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/contextualhelp/-/contextualhelp-3.6.13.tgz",
+            "integrity": "sha512-tSY2l9v+kTvMfL6Alu8AoDSqXLCX0lqi8wuQxOVOHvbKEYf9BnRdlHQ5ILLHpt9eFxriVnsQcIbR6sGdoOi2pw==",
+            "dependencies": {
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/button": "^3.16.6",
+                "@react-spectrum/dialog": "^3.8.13",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/contextualhelp": "^3.2.12",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/workflow": "^4.2.14",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/datepicker": {
-            "version": "3.9.6",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/datepicker/-/datepicker-3.9.6.tgz",
-            "integrity": "sha512-MeLle/V2t3dBe7wq/qkc39hJyV6NTZncCZnBfPHnTcLXeZl8sfTf4rt11JS3Y4JOOtM3jiuw1oMpZ7wv+h6hOA==",
-            "dependencies": {
-                "@internationalized/date": "^3.5.4",
-                "@react-aria/datepicker": "^3.10.1",
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/button": "^3.16.4",
-                "@react-spectrum/calendar": "^3.4.9",
-                "@react-spectrum/dialog": "^3.8.11",
-                "@react-spectrum/form": "^3.7.6",
-                "@react-spectrum/label": "^3.16.6",
-                "@react-spectrum/layout": "^3.6.5",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-spectrum/view": "^3.6.10",
-                "@react-stately/datepicker": "^3.9.4",
-                "@react-types/datepicker": "^3.7.4",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
-                "@spectrum-icons/workflow": "^4.2.12",
+            "version": "3.10.1",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/datepicker/-/datepicker-3.10.1.tgz",
+            "integrity": "sha512-+cmnSGSMrMiO94q1KOM3rCIUeFQouwJ8SbECxMQQDAGINHbhQxlceW4sKl0SldpXzS2yVINKj17rjFAbOvxEHw==",
+            "dependencies": {
+                "@internationalized/date": "^3.5.5",
+                "@react-aria/datepicker": "^3.11.1",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/button": "^3.16.6",
+                "@react-spectrum/calendar": "^3.4.11",
+                "@react-spectrum/dialog": "^3.8.13",
+                "@react-spectrum/form": "^3.7.8",
+                "@react-spectrum/label": "^3.16.8",
+                "@react-spectrum/layout": "^3.6.7",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-spectrum/view": "^3.6.12",
+                "@react-stately/datepicker": "^3.10.1",
+                "@react-types/datepicker": "^3.8.1",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
+                "@spectrum-icons/workflow": "^4.2.14",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/dialog": {
-            "version": "3.8.11",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/dialog/-/dialog-3.8.11.tgz",
-            "integrity": "sha512-/ng49paipA3MHC5nVbfDlZL6QXFJWCrSDgQ4fXon5q6gB+94d2DvkZ+CvnLZ5oo0Bpkws/vT3jxcG0hsBz1f6g==",
-            "dependencies": {
-                "@react-aria/dialog": "^3.5.14",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/overlays": "^3.22.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/button": "^3.16.4",
-                "@react-spectrum/buttongroup": "^3.6.13",
-                "@react-spectrum/divider": "^3.5.13",
-                "@react-spectrum/layout": "^3.6.5",
-                "@react-spectrum/overlays": "^5.6.1",
-                "@react-spectrum/text": "^3.5.5",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-spectrum/view": "^3.6.10",
-                "@react-stately/overlays": "^3.6.7",
-                "@react-types/button": "^3.9.4",
-                "@react-types/dialog": "^3.5.10",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
+            "version": "3.8.13",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/dialog/-/dialog-3.8.13.tgz",
+            "integrity": "sha512-BbmBKRVcSOZhV01xCl/MJTG2D+dctDMs/8/SOpM//BXzvlDIGXHRVJiYcPKCGe4Egt+6mNCjY/xvvfqxOXRNhw==",
+            "dependencies": {
+                "@react-aria/dialog": "^3.5.16",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/overlays": "^3.23.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/button": "^3.16.6",
+                "@react-spectrum/buttongroup": "^3.6.15",
+                "@react-spectrum/divider": "^3.5.15",
+                "@react-spectrum/layout": "^3.6.7",
+                "@react-spectrum/overlays": "^5.6.3",
+                "@react-spectrum/text": "^3.5.7",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-spectrum/view": "^3.6.12",
+                "@react-stately/overlays": "^3.6.9",
+                "@react-types/button": "^3.9.6",
+                "@react-types/dialog": "^3.5.12",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/divider": {
-            "version": "3.5.13",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/divider/-/divider-3.5.13.tgz",
-            "integrity": "sha512-7LoOTj+qs3yTBZiWudgU5TpzLREApMt0rwzalyq9ORRQrE8C0YXUxlSLPizyUmQeP4Rj8p3lCdUNWAe1cAn1tQ==",
-            "dependencies": {
-                "@react-aria/separator": "^3.3.13",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/divider": "^3.3.9",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.5.15",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/divider/-/divider-3.5.15.tgz",
+            "integrity": "sha512-bL0pwPup9VL7W4faxvHonChx8eEbBUhX67/V47wR21q4PmnuP3bOVZ6U3qqCbhA+R246zsyxlBouX3mL6QuKvg==",
+            "dependencies": {
+                "@react-aria/separator": "^3.4.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/divider": "^3.3.11",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/dnd": {
-            "version": "3.3.10",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/dnd/-/dnd-3.3.10.tgz",
-            "integrity": "sha512-Qp+Fp6BnMgrp5G18IAcbEUetf2YWelRugYJr8TH8h236n8lariyUpri1Mj604DV/UqNoK6f6k6ocY8JBmvOd9Q==",
+            "version": "3.4.1",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/dnd/-/dnd-3.4.1.tgz",
+            "integrity": "sha512-sg99ExYMmm5sb8EWsTJRUK6efb41t+s7Ih19M/iamfhwSaypAZaMbfP1zjtFbUqC9GtEALteZpt5OqVRkiKlvQ==",
             "dependencies": {
-                "@react-aria/dnd": "^3.6.1",
-                "@react-stately/dnd": "^3.3.1",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/dnd": "^3.7.1",
+                "@react-stately/dnd": "^3.4.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/dropzone": {
-            "version": "3.0.1",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/dropzone/-/dropzone-3.0.1.tgz",
-            "integrity": "sha512-8hEu6mF1ExJMc+Pv5lk3YHz3yZcRy4FkjKgBMXWWn8kxT2DEIK5hONspECBmlsNtUHuk1QQFFSISMGgsMZFQVw==",
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/dropzone/-/dropzone-3.0.3.tgz",
+            "integrity": "sha512-YtX4W9RtAaQwk2RbLmW/GjJ9DimqwGUSYaWAb9+LaoMBiUvEtJsy7m22frtph8wp62crQR1S/u16sTnqq8tlzQ==",
             "dependencies": {
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0",
-                "react-aria-components": "^1.2.1"
+                "react-aria-components": "^1.3.1"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/filetrigger": {
-            "version": "3.0.1",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/filetrigger/-/filetrigger-3.0.1.tgz",
-            "integrity": "sha512-9PfhjeGdHjyumlzdvrFNumKnGeaK41kYragnDMSD3KNH0XWu2kVUTB7eUbA9d6FLL/+g8tyPx+wDo0ZJW79Fpg==",
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/filetrigger/-/filetrigger-3.0.3.tgz",
+            "integrity": "sha512-6bWa7ENBaj/oM0JkXd2Q7fzZg/gL23fitK1nVyRfFw9BHfgqCSZwMM2exBJjtX+Az6II4LjhY9cSbL28i9EsGw==",
             "dependencies": {
                 "@swc/helpers": "^0.5.0",
-                "react-aria-components": "^1.2.1"
+                "react-aria-components": "^1.3.1"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/form": {
-            "version": "3.7.6",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/form/-/form-3.7.6.tgz",
-            "integrity": "sha512-uh/r3d3haWGjdxh++HCCbezWRiw7PGDStvOHEVLCVz/cN0lrUb77dwx5E4jMvY+oLkaBv05R3UtdMxNdXV1DZQ==",
-            "dependencies": {
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/form": "^3.0.3",
-                "@react-types/form": "^3.7.4",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.7.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/form/-/form-3.7.8.tgz",
+            "integrity": "sha512-FAsSOhltgBCnqLXsdTeYaDUQo7TU9GT/byCgKs0+FK9RKPQMtwYRCHDmoEOoWVhIlH6jiOTT6UXxRP+uGJiSAg==",
+            "dependencies": {
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/form": "^3.0.5",
+                "@react-types/form": "^3.7.6",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/icon": {
-            "version": "3.7.13",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/icon/-/icon-3.7.13.tgz",
-            "integrity": "sha512-hbd1OZ2UOOZ807zkU/ay8TWQOSnB56cj9HHm3FzUBjpTwpt849Pvk4TBO5K2SAmuQi4gslmvFGmd8BoOEoEcjg==",
+            "version": "3.7.15",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/icon/-/icon-3.7.15.tgz",
+            "integrity": "sha512-b8VouL33orbT6wUxsgvmaPrNOXftagVE4BNLbOFhBik98ycy8H+KajCII5ZnTM8O4+9f9lDyO8D0R8n5VeOaiA==",
             "dependencies": {
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/illustratedmessage": {
-            "version": "3.5.1",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/illustratedmessage/-/illustratedmessage-3.5.1.tgz",
-            "integrity": "sha512-HpTueLW3duV1TE3sYw5WeBaGECqS0RVEXr2UaXDXSLteY238Oc7prli2qPk2xaGeRKgh97jsfySDBOvedCuZJQ==",
-            "dependencies": {
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/layout": "^3.6.5",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/illustratedmessage": "^3.3.9",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.5.3",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/illustratedmessage/-/illustratedmessage-3.5.3.tgz",
+            "integrity": "sha512-2f5P9s8TWLRWDOdk84aqWkyNhgT8PZfAdbMLpzrzra0QM5FYwABbMDcjtVaprFq55KqPk9iLwGSb0Avk3T+aDA==",
+            "dependencies": {
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/layout": "^3.6.7",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/illustratedmessage": "^3.3.11",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/image": {
-            "version": "3.5.1",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/image/-/image-3.5.1.tgz",
-            "integrity": "sha512-MFl2WkMT224L4v1M9n4ZGkkXhBqecQ6uWZfxHBURrTXFMgPq5sxWY7qw42pc3mAX339kNiLZXTCTA5mKyiqxnQ==",
+            "version": "3.5.3",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/image/-/image-3.5.3.tgz",
+            "integrity": "sha512-8ZUkWXH9tnR+ZnxEeMEflo/nMRNFn60VpXOt9hfJlXbhwUKD4eO3TFA14QQXr407XSZwt9d7CGkT4urw4lxtmA==",
             "dependencies": {
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/image": "^3.4.1",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/image": "^3.4.3",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/inlinealert": {
-            "version": "3.2.5",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/inlinealert/-/inlinealert-3.2.5.tgz",
-            "integrity": "sha512-D9EF8pIQME6GHpvk7HR8/Qr3g79l78EsvczL0wGOzdcMt+LoV9F6RNJSobrI+dgzX0RcbqRyWsdCixboFrfefg==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/layout": "^3.6.5",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
+            "version": "3.2.7",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/inlinealert/-/inlinealert-3.2.7.tgz",
+            "integrity": "sha512-jWO7gNx3rulFA0lkvcv/czNdGZRmG77Jo8aAe2ku/96WvJc9h4ZNyTVu7F+8W5iR+I1Ige1D6UHB9dJCTZlfHQ==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/layout": "^3.6.7",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/label": {
-            "version": "3.16.6",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/label/-/label-3.16.6.tgz",
-            "integrity": "sha512-RF1YqQOKpDYqnSxM+TK/4gZGBsoKjfaZYsOvjya90LvUO8/2Va8Ux0bwHlqtOxu46yjxPLflpt0u9rl9ce+Ubg==",
-            "dependencies": {
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/form": "^3.7.6",
-                "@react-spectrum/layout": "^3.6.5",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/label": "^3.9.3",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
+            "version": "3.16.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/label/-/label-3.16.8.tgz",
+            "integrity": "sha512-2qIju/PZNzwTviR1OiiT8SR+aZdkBCI+S0GfT/FABjkmxJvm+lWxIhc+okr9CRGgEzCYnq9b3S5PfPIupLh8ew==",
+            "dependencies": {
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/form": "^3.7.8",
+                "@react-spectrum/layout": "^3.6.7",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/label": "^3.9.5",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/labeledvalue": {
-            "version": "3.1.14",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/labeledvalue/-/labeledvalue-3.1.14.tgz",
-            "integrity": "sha512-JeZHCRRmSPShgOozHs31+e0NnN4S3+SP0NpPGFUo0itPHvOcJSV9aoRCefdMTdXbUupIi5h1EM5Ty0owdy8y0w==",
-            "dependencies": {
-                "@internationalized/date": "^3.5.4",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/label": "^3.16.6",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.1.16",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/labeledvalue/-/labeledvalue-3.1.16.tgz",
+            "integrity": "sha512-ZzrGErsGvnndVpL9MMdanYpmL4I97enWU7tQ6w17TUvmb6pG4VIKUVepPMpw9sn9VcEc44dY56nDqH9m+uR35g==",
+            "dependencies": {
+                "@internationalized/date": "^3.5.5",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/label": "^3.16.8",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/layout": {
-            "version": "3.6.5",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/layout/-/layout-3.6.5.tgz",
-            "integrity": "sha512-kl/vZue7ZQZtkypPeOPZ3WENk4Mn9aYsjSBFZP+3GVRGPi0GBlhVOSicraio7UD3oGz1Xkhy5WZg01s3zQC0zg==",
-            "dependencies": {
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/layout": "^3.3.15",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.6.7",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/layout/-/layout-3.6.7.tgz",
+            "integrity": "sha512-EheC/J99qt2GpVq05UqPk9iH9PImH9SHXmikNqf/pckKH2Xh/EUY9t5ab+oOYq0N9JbdLp9a38AvuL9KyTJAFQ==",
+            "dependencies": {
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/layout": "^3.3.17",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/link": {
-            "version": "3.6.7",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/link/-/link-3.6.7.tgz",
-            "integrity": "sha512-g9yWHXO8OdoOnUH0xAIek5wDHDi0gYmEL3hqqKwzfMvkmQQCQjVS+D/9IlkxKT5LaumUiHdHDiA2PL1voPUh0g==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/link": "^3.7.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/link": "^3.5.5",
+            "version": "3.6.9",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/link/-/link-3.6.9.tgz",
+            "integrity": "sha512-eZDGvH8R1GKQVnlk5h1T6utKO/i3xFEhqC8cI/B5Pwh3WwVB9fSwUljzf9Cb3dqfSMTFXH3GrPmF1XVfRIliFg==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/link": "^3.7.3",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/link": "^3.5.7",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/list": {
-            "version": "3.7.10",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/list/-/list-3.7.10.tgz",
-            "integrity": "sha512-UxS+pXgJGaTeLP+KQdq7IQsaJN1tq6tpqFXFKXdrXGnLZPd9GtBT3zYP2Rnb9r/6Vm67D+pewF6tVKLzctE1sw==",
-            "dependencies": {
-                "@react-aria/button": "^3.9.5",
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/gridlist": "^3.8.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-aria/virtualizer": "^3.10.1",
-                "@react-aria/visually-hidden": "^3.8.12",
-                "@react-spectrum/checkbox": "^3.9.6",
-                "@react-spectrum/dnd": "^3.3.10",
-                "@react-spectrum/layout": "^3.6.5",
-                "@react-spectrum/progress": "^3.7.7",
-                "@react-spectrum/text": "^3.5.5",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/layout": "^3.13.9",
-                "@react-stately/list": "^3.10.5",
-                "@react-types/grid": "^3.2.6",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
+            "version": "3.8.1",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/list/-/list-3.8.1.tgz",
+            "integrity": "sha512-8gSq7cMtVwrPA7DMCg2b9PEYcT8IAmpsKREtAWGOZtzT0xgm8xdEwMUAbhbiDmE1Nbuupe+0vDl2XkUjlrdmXw==",
+            "dependencies": {
+                "@react-aria/button": "^3.9.7",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/gridlist": "^3.9.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/selection": "^3.19.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-aria/virtualizer": "^4.0.1",
+                "@react-aria/visually-hidden": "^3.8.14",
+                "@react-spectrum/checkbox": "^3.9.8",
+                "@react-spectrum/dnd": "^3.4.1",
+                "@react-spectrum/layout": "^3.6.7",
+                "@react-spectrum/progress": "^3.7.9",
+                "@react-spectrum/text": "^3.5.7",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/layout": "^4.0.1",
+                "@react-stately/list": "^3.10.7",
+                "@react-stately/virtualizer": "^4.0.1",
+                "@react-types/grid": "^3.2.8",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0",
                 "react-transition-group": "^4.4.5"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.2.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/listbox": {
-            "version": "3.12.9",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/listbox/-/listbox-3.12.9.tgz",
-            "integrity": "sha512-9adZJtEtAVwNtJEU70edZOlx+LfBOeVpWCOXoAJ+5iU+rNrQER7bEpFj15GlJOL+vcwFuCPoIsDBKSxygJANLw==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/listbox": "^3.12.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-aria/virtualizer": "^3.10.1",
-                "@react-spectrum/layout": "^3.6.5",
-                "@react-spectrum/progress": "^3.7.7",
-                "@react-spectrum/text": "^3.5.5",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/layout": "^3.13.9",
-                "@react-stately/list": "^3.10.5",
-                "@react-stately/virtualizer": "^3.7.1",
-                "@react-types/listbox": "^3.4.9",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
+            "version": "3.13.1",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/listbox/-/listbox-3.13.1.tgz",
+            "integrity": "sha512-VaLxXVMMDltrQclfWUZJcpq/0u4Ijm2vr1S1L4ype2VF2S8X2gKiwnfsMfzjhxmfSvjKr1vH+kxRC45sDuFdWA==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/listbox": "^3.13.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-aria/virtualizer": "^4.0.1",
+                "@react-spectrum/layout": "^3.6.7",
+                "@react-spectrum/progress": "^3.7.9",
+                "@react-spectrum/text": "^3.5.7",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/layout": "^4.0.1",
+                "@react-stately/list": "^3.10.7",
+                "@react-stately/virtualizer": "^4.0.1",
+                "@react-types/listbox": "^3.5.1",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.2.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/menu": {
-            "version": "3.19.1",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/menu/-/menu-3.19.1.tgz",
-            "integrity": "sha512-/bpqSPef1UvoaIwd5GVrqMt8LiByi5rV9yh0K+SSzZ5uY/w4zRQN9y14XnLf4P53R67DpSqAqk3JoWOLFj0Zcg==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/menu": "^3.14.1",
-                "@react-aria/overlays": "^3.22.1",
-                "@react-aria/separator": "^3.3.13",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/button": "^3.16.4",
-                "@react-spectrum/layout": "^3.6.5",
-                "@react-spectrum/overlays": "^5.6.1",
-                "@react-spectrum/text": "^3.5.5",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/menu": "^3.7.1",
-                "@react-stately/overlays": "^3.6.7",
-                "@react-stately/tree": "^3.8.1",
-                "@react-types/menu": "^3.9.9",
-                "@react-types/overlays": "^3.8.7",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
-                "@spectrum-icons/workflow": "^4.2.12",
+            "version": "3.20.1",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/menu/-/menu-3.20.1.tgz",
+            "integrity": "sha512-lIkL14tJaZh3Ago2x8EMcLlyGBMRquDz0OsqgMHeHwQOtUOnIY31JdrWNBdSYWgASZDytrKJSU4e5gXRMCYNEw==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/menu": "^3.15.1",
+                "@react-aria/overlays": "^3.23.1",
+                "@react-aria/separator": "^3.4.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/button": "^3.16.6",
+                "@react-spectrum/layout": "^3.6.7",
+                "@react-spectrum/overlays": "^5.6.3",
+                "@react-spectrum/text": "^3.5.7",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/menu": "^3.8.1",
+                "@react-stately/overlays": "^3.6.9",
+                "@react-stately/tree": "^3.8.3",
+                "@react-types/menu": "^3.9.11",
+                "@react-types/overlays": "^3.8.9",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
+                "@spectrum-icons/workflow": "^4.2.14",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/meter": {
-            "version": "3.5.1",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/meter/-/meter-3.5.1.tgz",
-            "integrity": "sha512-xmQwPDmT8hfkEuyUrijpe2xXyzWlFErrnKpQIf49Lql/GudeGHIvtekx3Qj2kvhwLpHKeOOECk35PufCJmwF2A==",
-            "dependencies": {
-                "@react-aria/meter": "^3.4.13",
-                "@react-spectrum/progress": "^3.7.7",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/meter": "^3.4.1",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.5.3",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/meter/-/meter-3.5.3.tgz",
+            "integrity": "sha512-mfsF+O4MkjaMGBQRT80zn5yd1TXtBF/aqtW2nrGFKxE/sRGJ6mWuqEuPheL+jEuQwcnAanQBk03+yaSUgYPW8Q==",
+            "dependencies": {
+                "@react-aria/meter": "^3.4.15",
+                "@react-spectrum/progress": "^3.7.9",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/meter": "^3.4.3",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/numberfield": {
-            "version": "3.9.3",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/numberfield/-/numberfield-3.9.3.tgz",
-            "integrity": "sha512-t3LllH5NkaqlwkvfFVizmzp4+MhMCqooLlUsBIbDgqyNCWEbxiC16ZqPOPkZkBDFio1aKX0zzSb9SiuUFw2ZwA==",
-            "dependencies": {
-                "@react-aria/button": "^3.9.5",
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/numberfield": "^3.11.3",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/form": "^3.7.6",
-                "@react-spectrum/label": "^3.16.6",
-                "@react-spectrum/textfield": "^3.12.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/numberfield": "^3.9.3",
-                "@react-types/button": "^3.9.4",
-                "@react-types/numberfield": "^3.8.3",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
-                "@spectrum-icons/workflow": "^4.2.12",
+            "version": "3.9.5",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/numberfield/-/numberfield-3.9.5.tgz",
+            "integrity": "sha512-fmaeAarm3ay7PpbrvvIrKkHdEMSKsuRyjcfkSjLCpkkI2D2sg2iJBtlbD+FypwvkpMJh/Lk6UPpirNgsX/+kcw==",
+            "dependencies": {
+                "@react-aria/button": "^3.9.7",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/numberfield": "^3.11.5",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/form": "^3.7.8",
+                "@react-spectrum/label": "^3.16.8",
+                "@react-spectrum/textfield": "^3.12.3",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/numberfield": "^3.9.5",
+                "@react-types/button": "^3.9.6",
+                "@react-types/numberfield": "^3.8.5",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
+                "@spectrum-icons/workflow": "^4.2.14",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/overlays": {
-            "version": "5.6.1",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/overlays/-/overlays-5.6.1.tgz",
-            "integrity": "sha512-ABacMG1V6gHCHHHtD01xt9RjTCu51Kytr/oHdUPEFd5Zvh8m/O7j3IQI4nSj5a5kDoj73NAkENq9Cq12gjwL4g==",
-            "dependencies": {
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/overlays": "^3.22.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/overlays": "^3.6.7",
-                "@react-types/overlays": "^3.8.7",
-                "@react-types/shared": "^3.23.1",
+            "version": "5.6.3",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/overlays/-/overlays-5.6.3.tgz",
+            "integrity": "sha512-EUnpn99fx3nmBQAUc1Cxgf75Ro1Cg1rey1SC/TIVllhz2D3tSOsDD22I/eWXMEdBNS+IeSFzbEGApOvJrp4RKQ==",
+            "dependencies": {
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/overlays": "^3.23.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/overlays": "^3.6.9",
+                "@react-types/overlays": "^3.8.9",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0",
                 "react-transition-group": "^4.4.5"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/picker": {
-            "version": "3.14.5",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/picker/-/picker-3.14.5.tgz",
-            "integrity": "sha512-FBCMibgStP62XKS2yJWHtn+XOLsxuzs0pl0jHkozuBaqC42H6fkDcINgQ08wbS2PlEEJSOYIkeL3LXFcxuewEA==",
-            "dependencies": {
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/select": "^3.14.5",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/button": "^3.16.4",
-                "@react-spectrum/form": "^3.7.6",
-                "@react-spectrum/label": "^3.16.6",
-                "@react-spectrum/listbox": "^3.12.9",
-                "@react-spectrum/overlays": "^5.6.1",
-                "@react-spectrum/progress": "^3.7.7",
-                "@react-spectrum/text": "^3.5.5",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/select": "^3.6.4",
-                "@react-types/select": "^3.9.4",
-                "@react-types/shared": "^3.23.1",
-                "@spectrum-icons/ui": "^3.6.7",
+            "version": "3.15.1",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/picker/-/picker-3.15.1.tgz",
+            "integrity": "sha512-vsTRw7U7d1TppJwJtwXfZ75WgUf87nIDOhNrqykVvCXxt7C9DTJ8OwJPBfOl88ImfT4U1f6ldr681uC4VU7lIA==",
+            "dependencies": {
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/select": "^3.14.7",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/button": "^3.16.6",
+                "@react-spectrum/form": "^3.7.8",
+                "@react-spectrum/label": "^3.16.8",
+                "@react-spectrum/listbox": "^3.13.1",
+                "@react-spectrum/overlays": "^5.6.3",
+                "@react-spectrum/progress": "^3.7.9",
+                "@react-spectrum/text": "^3.5.7",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/select": "^3.6.6",
+                "@react-types/select": "^3.9.6",
+                "@react-types/shared": "^3.24.1",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.1.4",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/progress": {
-            "version": "3.7.7",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/progress/-/progress-3.7.7.tgz",
-            "integrity": "sha512-FI/oc9hEQqbv00VJbaxqFTncBDDbxWN9cbvNNrPoROBQWL3NgB3tvEqY/fm5IXtDeFEV/U+tSm8BnZTGn6Mdxg==",
-            "dependencies": {
-                "@react-aria/progress": "^3.4.13",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/progress": "^3.5.4",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.7.9",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/progress/-/progress-3.7.9.tgz",
+            "integrity": "sha512-C6sozAPqupK1geqhmbS9K28b5xW2ZdIiBrk1XGjIiBuAqQZhvqFxCliwr2pbjWPcOGLQJrgc8dGWUuvZXUtGXQ==",
+            "dependencies": {
+                "@react-aria/progress": "^3.4.15",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/progress": "^3.5.6",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/provider": {
-            "version": "3.9.7",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/provider/-/provider-3.9.7.tgz",
-            "integrity": "sha512-VRu8cOWrLJU/Krulo8njfPCMeJT+uu1k9GjFZ9Cw88mHGW7a3MK54IzI5p2evLPab7pgplPIoJcv3bC2XB+DAA==",
-            "dependencies": {
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/overlays": "^3.22.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/provider": "^3.8.1",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.9.9",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/provider/-/provider-3.9.9.tgz",
+            "integrity": "sha512-sVgIG0MZ/4KCrJgWjOGyEdP5nhl8fXxp6L1s7SWyzWT/e6ypD0Og9hkQo/yY2XHP2hI4ZiZ4Psc1H4olsrp5lw==",
+            "dependencies": {
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/overlays": "^3.23.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/provider": "^3.8.3",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0",
                 "clsx": "^2.0.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/radio": {
-            "version": "3.7.6",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/radio/-/radio-3.7.6.tgz",
-            "integrity": "sha512-KRtipJfIkRWbnvhS/zZ7j3ltEQXrQeVNhmIWChuP+sC5hdA3N8llMgf30Xa9PqtFhGH4CvUlXC9NA/rhLWnm4w==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/radio": "^3.10.4",
-                "@react-spectrum/form": "^3.7.6",
-                "@react-spectrum/label": "^3.16.6",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/radio": "^3.10.4",
-                "@react-types/radio": "^3.8.1",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.7.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/radio/-/radio-3.7.8.tgz",
+            "integrity": "sha512-H11U3Hf15wVhp8hoyYR2bUKgKyyihhjPw40rf2ZESnS/FEeOifVQtzr6UbEKqb1qC/LX5YhuHjUyXv+j4DuVeA==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/radio": "^3.10.6",
+                "@react-spectrum/form": "^3.7.8",
+                "@react-spectrum/label": "^3.16.8",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/radio": "^3.10.6",
+                "@react-types/radio": "^3.8.3",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/searchfield": {
-            "version": "3.8.6",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/searchfield/-/searchfield-3.8.6.tgz",
-            "integrity": "sha512-RU928ZeQsqPGMsNVtoLvahHmuRC3OAW9im5W0/CVgglINn2IapF2U0oxHVw6ymzx1NyCYrYR8pO9skMF0E68/Q==",
-            "dependencies": {
-                "@react-aria/searchfield": "^3.7.5",
-                "@react-spectrum/button": "^3.16.4",
-                "@react-spectrum/form": "^3.7.6",
-                "@react-spectrum/textfield": "^3.12.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/searchfield": "^3.5.3",
-                "@react-types/searchfield": "^3.5.5",
-                "@react-types/textfield": "^3.9.3",
-                "@spectrum-icons/ui": "^3.6.7",
+            "version": "3.8.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/searchfield/-/searchfield-3.8.8.tgz",
+            "integrity": "sha512-HR0lQNNzjNyi12bEJ39U/rASZpQuHIpUq9A3DzarRMARrHLmidHzH4F7zu9I4k3GTFm/mL+j2q44EJIP2GqtQQ==",
+            "dependencies": {
+                "@react-aria/searchfield": "^3.7.7",
+                "@react-spectrum/button": "^3.16.6",
+                "@react-spectrum/form": "^3.7.8",
+                "@react-spectrum/textfield": "^3.12.3",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/searchfield": "^3.5.5",
+                "@react-types/searchfield": "^3.5.7",
+                "@react-types/textfield": "^3.9.5",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/slider": {
-            "version": "3.6.9",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/slider/-/slider-3.6.9.tgz",
-            "integrity": "sha512-2X6qxlyObfowb8uZQ8UXEozozcfGLzhQI9BS9DS9Kste/REXMTcRDzFygP1D1HdkvRaWmYRNoYhi/Jl2Kkw7Eg==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/slider": "^3.7.8",
-                "@react-aria/utils": "^3.24.1",
-                "@react-aria/visually-hidden": "^3.8.12",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/slider": "^3.5.4",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/slider": "^3.7.3",
+            "version": "3.6.11",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/slider/-/slider-3.6.11.tgz",
+            "integrity": "sha512-Rz8yzQKZTO+PBjnEwRCd+dxIMo/A7Qsj1Vs3sVowSlmLeq6qHeLajdTbe2SN95pUC/b6n+tkNxMyy2bzsW2VlQ==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/slider": "^3.7.10",
+                "@react-aria/utils": "^3.25.1",
+                "@react-aria/visually-hidden": "^3.8.14",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/slider": "^3.5.6",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/slider": "^3.7.5",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/statuslight": {
-            "version": "3.5.13",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/statuslight/-/statuslight-3.5.13.tgz",
-            "integrity": "sha512-FvvsDVs9lapRf5zmOq3g8ZRpAxOTVRfhG9WyehIqgaRPtqqNpQhAGSXWz0ErXF3zV8AwVvjD70g0atcDCoDeBQ==",
-            "dependencies": {
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/statuslight": "^3.3.9",
+            "version": "3.5.15",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/statuslight/-/statuslight-3.5.15.tgz",
+            "integrity": "sha512-gTv4HvnJNcNBTJs3Xw6ki984A7Z58CE2jlKEJ9+PrOJY+cckjeocfWR1XqQsJHCaNuGC9LYhzuJsqsPnqxFNZA==",
+            "dependencies": {
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/statuslight": "^3.3.11",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/switch": {
-            "version": "3.5.5",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/switch/-/switch-3.5.5.tgz",
-            "integrity": "sha512-IIVctsGXnChqMlvf2/pMRkI84vyjf0gMsBXEgky8h8s4i91wxQvl6800/4I9rCSQdAAnQYb+Nd3St8Ik7BupQg==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/switch": "^3.6.4",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/toggle": "^3.7.4",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/switch": "^3.5.3",
+            "version": "3.5.7",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/switch/-/switch-3.5.7.tgz",
+            "integrity": "sha512-tXkUadG3VeCGskROYUdFjYNSsQ9G1D72hCG7LoXusIUqYzvNz3xlm3TSP1LOF/lq+WGhPxhhV5LkA1HqN+ZeeA==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/switch": "^3.6.6",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/toggle": "^3.7.6",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/switch": "^3.5.5",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/table": {
-            "version": "3.12.10",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/table/-/table-3.12.10.tgz",
-            "integrity": "sha512-a9Qa/1uuoChRez6GncmYdkDgSS4MDXzV4Cl/BrO44Dnph1ygXiJGmBgAvmtevcbndfuERGHoIYqzklIr6veArg==",
-            "dependencies": {
-                "@react-aria/button": "^3.9.5",
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/overlays": "^3.22.1",
-                "@react-aria/table": "^3.14.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-aria/virtualizer": "^3.10.1",
-                "@react-aria/visually-hidden": "^3.8.12",
-                "@react-spectrum/checkbox": "^3.9.6",
-                "@react-spectrum/dnd": "^3.3.10",
-                "@react-spectrum/layout": "^3.6.5",
-                "@react-spectrum/menu": "^3.19.1",
-                "@react-spectrum/progress": "^3.7.7",
-                "@react-spectrum/tooltip": "^3.6.7",
-                "@react-spectrum/utils": "^3.11.7",
+            "version": "3.13.1",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/table/-/table-3.13.1.tgz",
+            "integrity": "sha512-CnxgizMey9sdAL3iyMCX0BGim+USgeKtss8ZIzWIhGmrUBpoQy32ZedXpcN7UwBIScWYo1b44fyNxw6z44K6Dw==",
+            "dependencies": {
+                "@react-aria/button": "^3.9.7",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/overlays": "^3.23.1",
+                "@react-aria/selection": "^3.19.1",
+                "@react-aria/table": "^3.15.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-aria/virtualizer": "^4.0.1",
+                "@react-aria/visually-hidden": "^3.8.14",
+                "@react-spectrum/checkbox": "^3.9.8",
+                "@react-spectrum/dnd": "^3.4.1",
+                "@react-spectrum/layout": "^3.6.7",
+                "@react-spectrum/menu": "^3.20.1",
+                "@react-spectrum/progress": "^3.7.9",
+                "@react-spectrum/tooltip": "^3.6.9",
+                "@react-spectrum/utils": "^3.11.9",
                 "@react-stately/flags": "^3.0.3",
-                "@react-stately/layout": "^3.13.9",
-                "@react-stately/table": "^3.11.8",
-                "@react-stately/virtualizer": "^3.7.1",
-                "@react-types/grid": "^3.2.6",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/table": "^3.9.5",
-                "@spectrum-icons/ui": "^3.6.7",
+                "@react-stately/layout": "^4.0.1",
+                "@react-stately/table": "^3.12.1",
+                "@react-stately/virtualizer": "^4.0.1",
+                "@react-types/grid": "^3.2.8",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/table": "^3.10.1",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/tabs": {
-            "version": "3.8.10",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/tabs/-/tabs-3.8.10.tgz",
-            "integrity": "sha512-LoNkxalAbOjKgbF/x3NU5zhvhUgAEqJvEwzKLVSr+KDQlMAFe9LZ+HOH2NRiWR8ak9BkW3RR6C8cGo7G7fdrfA==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/tabs": "^3.9.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/picker": "^3.14.5",
-                "@react-spectrum/text": "^3.5.5",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/list": "^3.10.5",
-                "@react-stately/tabs": "^3.6.6",
-                "@react-types/select": "^3.9.4",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/tabs": "^3.3.7",
+            "version": "3.8.12",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/tabs/-/tabs-3.8.12.tgz",
+            "integrity": "sha512-tvHEzV5Web6D98vLNbWVwrGGNKx/n6NeuYB6QX88lA8Pp0M9XCuQ6S6548Zk/eUHS0eExi60yX+AcPn1mZTtNQ==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/tabs": "^3.9.3",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/picker": "^3.15.1",
+                "@react-spectrum/text": "^3.5.7",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/list": "^3.10.7",
+                "@react-stately/tabs": "^3.6.8",
+                "@react-types/select": "^3.9.6",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/tabs": "^3.3.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/tag": {
-            "version": "3.2.6",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/tag/-/tag-3.2.6.tgz",
-            "integrity": "sha512-OSGIL2fYLMmiPRCEGvdrQVazS6/S0nhzf/FO52pAAjDZHkd4RDlHHY00Yv/2GPJKroa4e5jdyd5NHCxlW5Vbaw==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/selection": "^3.18.1",
-                "@react-aria/tag": "^3.4.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/button": "^3.16.4",
-                "@react-spectrum/form": "^3.7.6",
-                "@react-spectrum/label": "^3.16.6",
-                "@react-spectrum/text": "^3.5.5",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/list": "^3.10.5",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.2.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/tag/-/tag-3.2.8.tgz",
+            "integrity": "sha512-cZO745mdjwoSvEoBjWTREdZiOshuGq8jm+1XuO6eWGcxCsktU6ToPjz7wrmHi6kE4fuhXj/UxcyA+8IXSL1mhw==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/selection": "^3.19.1",
+                "@react-aria/tag": "^3.4.3",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/button": "^3.16.6",
+                "@react-spectrum/form": "^3.7.8",
+                "@react-spectrum/label": "^3.16.8",
+                "@react-spectrum/text": "^3.5.7",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/list": "^3.10.7",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/text": {
-            "version": "3.5.5",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/text/-/text-3.5.5.tgz",
-            "integrity": "sha512-MSRMUNWjuqjAH0eRjSw0fOCvM7haqgfy3HgwHpB5czpeUtR1p22e+UWA9gHior7S57zrQN1WotpeWZ1AmnzvWg==",
-            "dependencies": {
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/text": "^3.3.9",
+            "version": "3.5.7",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/text/-/text-3.5.7.tgz",
+            "integrity": "sha512-Tvnto3UrWEc4iBiKYAFH9X6GzLwwzy4uWxRaPiZ3uu+I+JCd/Sz+mjdk5lOLtpPA78xtPkHO/I/iGijk4ag6mg==",
+            "dependencies": {
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/text": "^3.3.11",
                 "@swc/helpers": "^0.5.0",
-                "react-aria-components": "^1.2.1"
+                "react-aria-components": "^1.3.1"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/textfield": {
-            "version": "3.12.1",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/textfield/-/textfield-3.12.1.tgz",
-            "integrity": "sha512-ehvStKrduGo71SfEieodw6NHBDvyE5wYYZh1uLwbde9hjfyOf2q56lfMdSQiBSJ5pDnpS0ToLpoomoPz315u+Q==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/textfield": "^3.14.5",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/form": "^3.7.6",
-                "@react-spectrum/label": "^3.16.6",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/textfield": "^3.9.3",
-                "@spectrum-icons/ui": "^3.6.7",
+            "version": "3.12.3",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/textfield/-/textfield-3.12.3.tgz",
+            "integrity": "sha512-1NUTA/Wo8cPLmKcQymgzVBd37Q1mLf358stV4MxLqKjnPT+rGHBTflhV1cmRpLbWdXYnyPSEXyZx12YXctauKg==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/textfield": "^3.14.7",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/form": "^3.7.8",
+                "@react-spectrum/label": "^3.16.8",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/textfield": "^3.9.5",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/theme-dark": {
-            "version": "3.5.10",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/theme-dark/-/theme-dark-3.5.10.tgz",
-            "integrity": "sha512-xDzuWY9Vtd0X7Ww5fBvhbTq7oM0PiNtKlT+cPVnKm4YmJB5RvVG/m6jYF4/9GN36NAyiRnNRdBCs7SUuKEfTkA==",
+            "version": "3.5.12",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/theme-dark/-/theme-dark-3.5.12.tgz",
+            "integrity": "sha512-WLicILM0CDx3peenTZC9JQ7uhmZee2IiQtYMjYXGzCzHD3WG+X6OodpXG0VgtzHhb8lmtbzwxvGGPJlCPJIzqw==",
             "dependencies": {
-                "@react-types/provider": "^3.8.1",
+                "@react-types/provider": "^3.8.3",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/theme-default": {
-            "version": "3.5.10",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/theme-default/-/theme-default-3.5.10.tgz",
-            "integrity": "sha512-qCGce11d5p0Ce4nSz25vRYoMZycb8oxbgMUM9YXXHgUBDbRRB/s0JNUXxlyikENtaNWiCyeWzVm80bJKmmIijw==",
+            "version": "3.5.12",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/theme-default/-/theme-default-3.5.12.tgz",
+            "integrity": "sha512-bGtwv0NirmYIC4/4Tkkikn7yqKMITY8VKGEY8105EpiDZX+/8tr4dwypWi/EE0OMF8kTCW61zu5aScrNUQfGew==",
             "dependencies": {
-                "@react-types/provider": "^3.8.1",
+                "@react-types/provider": "^3.8.3",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/theme-light": {
-            "version": "3.4.10",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/theme-light/-/theme-light-3.4.10.tgz",
-            "integrity": "sha512-MKHxBlfawja16hBlcBTFD72B+luPwhCG/pTY35WMy+gCVWUeYEwJU8ijOhG7A7a7KkrLpHgebpHojxEXYkmFIA==",
+            "version": "3.4.12",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/theme-light/-/theme-light-3.4.12.tgz",
+            "integrity": "sha512-KrWYTQFcuKayEIJCdMA5z0Kbd2l4oeT72QSaqV+h2Hi7mnjxM7R16GZgF3swAJOvWEMSqhLLCzr/6P0prRmVmQ==",
             "dependencies": {
-                "@react-types/provider": "^3.8.1",
+                "@react-types/provider": "^3.8.3",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/tooltip": {
-            "version": "3.6.7",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/tooltip/-/tooltip-3.6.7.tgz",
-            "integrity": "sha512-kJDFY7G5MGuKc5e4K24ftYbzFLt9ugO5zbGMAg6Zbz79+ER8jTsbGNVupK3E7m9uSimF/aPRRwf2p8UdoksH6Q==",
-            "dependencies": {
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/overlays": "^3.22.1",
-                "@react-aria/tooltip": "^3.7.4",
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/overlays": "^5.6.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-stately/tooltip": "^3.4.9",
-                "@react-types/overlays": "^3.8.7",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/tooltip": "^3.4.9",
-                "@spectrum-icons/ui": "^3.6.7",
+            "version": "3.6.9",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/tooltip/-/tooltip-3.6.9.tgz",
+            "integrity": "sha512-AVWowYE43ZyOh2tck5TKs7a5a6RaAefeRPiqLpBo8W64TwP07WZgRtUJjLSFrt1AIVwfRyjOiwBiG/Ur896Zfw==",
+            "dependencies": {
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/overlays": "^3.23.1",
+                "@react-aria/tooltip": "^3.7.6",
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/overlays": "^5.6.3",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-stately/tooltip": "^3.4.11",
+                "@react-types/overlays": "^3.8.9",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/tooltip": "^3.4.11",
+                "@spectrum-icons/ui": "^3.6.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/utils": {
-            "version": "3.11.7",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/utils/-/utils-3.11.7.tgz",
-            "integrity": "sha512-o/9zTvUor0EaRwKZWVlgOcyvH+/JIBsNxuvhDgCP5lD868KoZePmx1L64TejUqK/swwH8jr35gyULpYU2kQXRw==",
-            "dependencies": {
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/ssr": "^3.9.4",
-                "@react-aria/utils": "^3.24.1",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.11.9",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/utils/-/utils-3.11.9.tgz",
+            "integrity": "sha512-k+0dwCflYejSix7FaRMp63ptgs/nc9ndOVa1qJVI/VGK+P9alZmqMXUhIztClLCcyFjJrd9O2YIaAEsBCkBNRw==",
+            "dependencies": {
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/ssr": "^3.9.5",
+                "@react-aria/utils": "^3.25.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0",
                 "clsx": "^2.0.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/view": {
-            "version": "3.6.10",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/view/-/view-3.6.10.tgz",
-            "integrity": "sha512-AbvwyORDzntt9XiP9Soc5mCuYsYOJKj+4mwX0ugZZi9I18g1JVeSPnGG/myYdHr2xXNC00pgVILOLA/B0JWMXw==",
-            "dependencies": {
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/view": "^3.4.9",
+            "version": "3.6.12",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/view/-/view-3.6.12.tgz",
+            "integrity": "sha512-zcmeEuOUDC+fGPTyuDZWouFFMm8/58RaHJtSIvrzSCixV3RAfGeWwi6tRCDjSQuYgDBjNvxUMCbYP88CO2FULw==",
+            "dependencies": {
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/view": "^3.4.11",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spectrum/well": {
-            "version": "3.4.13",
-            "resolved": "https://registry.npmjs.org/@react-spectrum/well/-/well-3.4.13.tgz",
-            "integrity": "sha512-zKJsaWnndRvCK4crkZ/Jt5uUk5Jwkx+pRaVu40BEK41aOfavQ44GR90uLogrvDuw2LDZ9mdTj/H7bCVNjkLkgA==",
-            "dependencies": {
-                "@react-aria/utils": "^3.24.1",
-                "@react-spectrum/utils": "^3.11.7",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/well": "^3.3.9",
+            "version": "3.4.15",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/well/-/well-3.4.15.tgz",
+            "integrity": "sha512-bzSIZAtXjHaLzcENYracSDabjQgU1KJAXofQ/YwBqZwMDVsokG+kvR+bfGfW05tldgZH5/7Am9D/pIcSW4qBUQ==",
+            "dependencies": {
+                "@react-aria/utils": "^3.25.1",
+                "@react-spectrum/utils": "^3.11.9",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/well": "^3.3.11",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-spring/animated": {
@@ -6184,127 +6188,127 @@
             }
         },
         "node_modules/@react-stately/calendar": {
-            "version": "3.5.1",
-            "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.5.1.tgz",
-            "integrity": "sha512-7l7QhqGUJ5AzWHfvZzbTe3J4t72Ht5BmhW4hlVI7flQXtfrmYkVtl3ZdytEZkkHmWGYZRW9b4IQTQGZxhtlElA==",
+            "version": "3.5.3",
+            "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.5.3.tgz",
+            "integrity": "sha512-SRwsgszyc9FNcvkjqBe81e/tnjKpRqH+yTYpG0uI9NR1HfyddmhR3Y7QilWPcqQkq4SQb7pL68SkTPH2dX2dng==",
             "dependencies": {
-                "@internationalized/date": "^3.5.4",
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/calendar": "^3.4.6",
-                "@react-types/shared": "^3.23.1",
+                "@internationalized/date": "^3.5.5",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/calendar": "^3.4.8",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/checkbox": {
-            "version": "3.6.5",
-            "resolved": "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.6.5.tgz",
-            "integrity": "sha512-IXV3f9k+LtmfQLE+DKIN41Q5QB/YBLDCB1YVx5PEdRp52S9+EACD5683rjVm8NVRDwjMi2SP6RnFRk7fVb5Azg==",
-            "dependencies": {
-                "@react-stately/form": "^3.0.3",
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/checkbox": "^3.8.1",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.6.7",
+            "resolved": "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.6.7.tgz",
+            "integrity": "sha512-ZOaBNXXazpwkuKj5hk6FtGbXO7HoKEGXvf3p7FcHcIHyiEJ65GBvC7e7HwMc3jYxlBwtbebSpEcf3oFqI5dl3A==",
+            "dependencies": {
+                "@react-stately/form": "^3.0.5",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/checkbox": "^3.8.3",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/collections": {
-            "version": "3.10.7",
-            "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.10.7.tgz",
-            "integrity": "sha512-KRo5O2MWVL8n3aiqb+XR3vP6akmHLhLWYZEmPKjIv0ghQaEebBTrN3wiEjtd6dzllv0QqcWvDLM1LntNfJ2TsA==",
+            "version": "3.10.9",
+            "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.10.9.tgz",
+            "integrity": "sha512-plyrng6hOQMG8LrjArMA6ts/DgWyXln3g90/hFNbqe/hdVYF53sDVsj8Jb+5LtoYTpiAlV6eOvy1XR0vPZUf8w==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/color": {
-            "version": "3.6.1",
-            "resolved": "https://registry.npmjs.org/@react-stately/color/-/color-3.6.1.tgz",
-            "integrity": "sha512-iW0nAhl3+fUBegHMw5EcAbFVDpgwHBrivfC85pVoTM3pyzp66hqNN6R6xWxW6ETyljS8UOer59+/w4GDVGdPig==",
+            "version": "3.7.1",
+            "resolved": "https://registry.npmjs.org/@react-stately/color/-/color-3.7.1.tgz",
+            "integrity": "sha512-pJqM7fZ7+zy8wnzCUkBMkTgmjMs+lBLjQm1k+dFbmXK2SuELiDOQLirrl6j15NVBOKn8avvRHXpAQhGX43GOCQ==",
             "dependencies": {
                 "@internationalized/number": "^3.5.3",
                 "@internationalized/string": "^3.2.3",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-stately/form": "^3.0.3",
-                "@react-stately/numberfield": "^3.9.3",
-                "@react-stately/slider": "^3.5.4",
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/color": "3.0.0-beta.25",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-stately/form": "^3.0.5",
+                "@react-stately/numberfield": "^3.9.5",
+                "@react-stately/slider": "^3.5.6",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/color": "3.0.0-rc.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/combobox": {
-            "version": "3.8.4",
-            "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.8.4.tgz",
-            "integrity": "sha512-iLVGvKRRz0TeJXZhZyK783hveHpYA6xovOSdzSD+WGYpiPXo1QrcrNoH3AE0Z2sHtorU+8nc0j58vh5PB+m2AA==",
-            "dependencies": {
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/form": "^3.0.3",
-                "@react-stately/list": "^3.10.5",
-                "@react-stately/overlays": "^3.6.7",
-                "@react-stately/select": "^3.6.4",
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/combobox": "^3.11.1",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.9.1",
+            "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.9.1.tgz",
+            "integrity": "sha512-jmeKUKs0jK18NwDAlpu79ATufgxrc6Sn3ZMmI8KPVQ5sdPTjNlnDx6gTFyOOIa87axf/c6WYU7v3jxmcp+RDdg==",
+            "dependencies": {
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/form": "^3.0.5",
+                "@react-stately/list": "^3.10.7",
+                "@react-stately/overlays": "^3.6.9",
+                "@react-stately/select": "^3.6.6",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/combobox": "^3.12.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/data": {
-            "version": "3.11.4",
-            "resolved": "https://registry.npmjs.org/@react-stately/data/-/data-3.11.4.tgz",
-            "integrity": "sha512-PbnUQxeE6AznSuEWYnRmrYQ9t5z1Asx98Jtrl96EeA6Iapt9kOjTN9ySqCxtPxMKleb1NIqG3+uHU3veIqmLsg==",
+            "version": "3.11.6",
+            "resolved": "https://registry.npmjs.org/@react-stately/data/-/data-3.11.6.tgz",
+            "integrity": "sha512-S8q1Ejuhijl8SnyVOdDNFrMrWWnLk/Oh1ZT3KHSbTdpfMRtvhi5HukoiP06jlzz75phnpSPQL40npDtUB/kk3Q==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/datepicker": {
-            "version": "3.9.4",
-            "resolved": "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.9.4.tgz",
-            "integrity": "sha512-yBdX01jn6gq4NIVvHIqdjBUPo+WN8Bujc4OnPw+ZnfA4jI0eIgq04pfZ84cp1LVXW0IB0VaCu1AlQ/kvtZjfGA==",
+            "version": "3.10.1",
+            "resolved": "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.10.1.tgz",
+            "integrity": "sha512-KXr5cxLOLUYBf3wlDSKhvshsKOWpdV2flhS075V6dgC/EPBh7igBZGUXJ9AZzndT7Hx1w8v/ul6CIffxEJz1Nw==",
             "dependencies": {
-                "@internationalized/date": "^3.5.4",
+                "@internationalized/date": "^3.5.5",
                 "@internationalized/string": "^3.2.3",
-                "@react-stately/form": "^3.0.3",
-                "@react-stately/overlays": "^3.6.7",
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/datepicker": "^3.7.4",
-                "@react-types/shared": "^3.23.1",
+                "@react-stately/form": "^3.0.5",
+                "@react-stately/overlays": "^3.6.9",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/datepicker": "^3.8.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/dnd": {
-            "version": "3.3.1",
-            "resolved": "https://registry.npmjs.org/@react-stately/dnd/-/dnd-3.3.1.tgz",
-            "integrity": "sha512-I/Ci5xB8hSgAXzoWYWScfMM9UK1MX/eTlARBhiSlfudewweOtNJAI+cXJgU7uiUnGjh4B4v3qDBtlAH1dWDCsw==",
+            "version": "3.4.1",
+            "resolved": "https://registry.npmjs.org/@react-stately/dnd/-/dnd-3.4.1.tgz",
+            "integrity": "sha512-EXPW1vKx3vNpMaXOpPKTOU1T4S+jqjllGFDyWD659Ql0lL9SQ5Y4IU/KmIK3T3yKkjps9xrMmCjLAkb75PH5zg==",
             "dependencies": {
-                "@react-stately/selection": "^3.15.1",
-                "@react-types/shared": "^3.23.1",
+                "@react-stately/selection": "^3.16.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/flags": {
@@ -6316,756 +6320,756 @@
             }
         },
         "node_modules/@react-stately/form": {
-            "version": "3.0.3",
-            "resolved": "https://registry.npmjs.org/@react-stately/form/-/form-3.0.3.tgz",
-            "integrity": "sha512-92YYBvlHEWUGUpXgIaQ48J50jU9XrxfjYIN8BTvvhBHdD63oWgm8DzQnyT/NIAMzdLnhkg7vP+fjG8LjHeyIAg==",
+            "version": "3.0.5",
+            "resolved": "https://registry.npmjs.org/@react-stately/form/-/form-3.0.5.tgz",
+            "integrity": "sha512-J3plwJ63HQz109OdmaTqTA8Qhvl3gcYYK7DtgKyNP6mc/Me2Q4tl2avkWoA+22NRuv5m+J8TpBk4AVHUEOwqeQ==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/grid": {
-            "version": "3.8.7",
-            "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.8.7.tgz",
-            "integrity": "sha512-he3TXCLAhF5C5z1/G4ySzcwyt7PEiWcVIupxebJQqRyFrNWemSuv+7tolnStmG8maMVIyV3P/3j4eRBbdSlOIg==",
-            "dependencies": {
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/selection": "^3.15.1",
-                "@react-types/grid": "^3.2.6",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.9.1",
+            "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.9.1.tgz",
+            "integrity": "sha512-LSVIcXO/cqwG0IgDSk2juDbpARBS1IzGnsTp/8vSOejMxq5MXrwxL5hUcqNczL8Ss6aLpELm42tCS0kPm3cMKw==",
+            "dependencies": {
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/selection": "^3.16.1",
+                "@react-types/grid": "^3.2.8",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/layout": {
-            "version": "3.13.9",
-            "resolved": "https://registry.npmjs.org/@react-stately/layout/-/layout-3.13.9.tgz",
-            "integrity": "sha512-JCj2cnvRbBjah9LFZbBXMdKkoKuEpzn6hvYBw7h0fNIhNGISpiI1TW4ya1X34kD2vcv/3dc31KV/UqmI4hJCQw==",
-            "dependencies": {
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/table": "^3.11.8",
-                "@react-stately/virtualizer": "^3.7.1",
-                "@react-types/grid": "^3.2.6",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/table": "^3.9.5",
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/@react-stately/layout/-/layout-4.0.1.tgz",
+            "integrity": "sha512-4oNYFhQprcwP1fNV/p3dbx1a6lzMGBAKLTdcvtCuBCgclNA3etqjdQAUIZ0Bpq+Z8i9qo3c85oxr6Tr8BKQV4w==",
+            "dependencies": {
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/table": "^3.12.1",
+                "@react-stately/virtualizer": "^4.0.1",
+                "@react-types/grid": "^3.2.8",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/table": "^3.10.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/list": {
-            "version": "3.10.5",
-            "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.10.5.tgz",
-            "integrity": "sha512-fV9plO+6QDHiewsYIhboxcDhF17GO95xepC5ki0bKXo44gr14g/LSo/BMmsaMnV+1BuGdBunB05bO4QOIaigXA==",
-            "dependencies": {
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/selection": "^3.15.1",
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.10.7",
+            "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.10.7.tgz",
+            "integrity": "sha512-W5PG7uG5GQV2Q59vXJE7QLKHZIoUNEx+JmHrBUCMKUgyngSpKIIEDR/R/C1b6ZJ9jMqqZA68Zlnd5iK1/mBi1A==",
+            "dependencies": {
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/selection": "^3.16.1",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/menu": {
-            "version": "3.7.1",
-            "resolved": "https://registry.npmjs.org/@react-stately/menu/-/menu-3.7.1.tgz",
-            "integrity": "sha512-mX1w9HHzt+xal1WIT2xGrTQsoLvDwuB2R1Er1MBABs//MsJzccycatcgV/J/28m6tO5M9iuFQQvLV+i1dCtodg==",
+            "version": "3.8.1",
+            "resolved": "https://registry.npmjs.org/@react-stately/menu/-/menu-3.8.1.tgz",
+            "integrity": "sha512-HzAANHg+QUpyRok0CBIL/5qb+4TARteP0q9av2tKnQWPG91iJw84phJDJrmmY55uFFax4fxBgDM9dy1t12iKgQ==",
             "dependencies": {
-                "@react-stately/overlays": "^3.6.7",
-                "@react-types/menu": "^3.9.9",
-                "@react-types/shared": "^3.23.1",
+                "@react-stately/overlays": "^3.6.9",
+                "@react-types/menu": "^3.9.11",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/numberfield": {
-            "version": "3.9.3",
-            "resolved": "https://registry.npmjs.org/@react-stately/numberfield/-/numberfield-3.9.3.tgz",
-            "integrity": "sha512-UlPTLSabhLEuHtgzM0PgfhtEaHy3yttbzcRb8yHNvGo4KbCHeHpTHd3QghKfTFm024Mug7+mVlWCmMtW0f5ttg==",
+            "version": "3.9.5",
+            "resolved": "https://registry.npmjs.org/@react-stately/numberfield/-/numberfield-3.9.5.tgz",
+            "integrity": "sha512-aWilyzrZOvkgntcXd6Kl+t1QiCbnajUCN8yll6/saByKpfuOf1k6AGYNQBJ0CO/5HyffPPdbFs+45sj4e3cdjA==",
             "dependencies": {
                 "@internationalized/number": "^3.5.3",
-                "@react-stately/form": "^3.0.3",
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/numberfield": "^3.8.3",
+                "@react-stately/form": "^3.0.5",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/numberfield": "^3.8.5",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/overlays": {
-            "version": "3.6.7",
-            "resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.7.tgz",
-            "integrity": "sha512-6zp8v/iNUm6YQap0loaFx6PlvN8C0DgWHNlrlzMtMmNuvjhjR0wYXVaTfNoUZBWj25tlDM81ukXOjpRXg9rLrw==",
+            "version": "3.6.9",
+            "resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.9.tgz",
+            "integrity": "sha512-4chfyzKw7P2UEainm0yzjUgYwG1ovBejN88eTrn+O62x5huuMCwe0cbMxmYh4y7IhRFSee3jIJd0SP0u/+i39w==",
             "dependencies": {
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/overlays": "^3.8.7",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/overlays": "^3.8.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/radio": {
-            "version": "3.10.4",
-            "resolved": "https://registry.npmjs.org/@react-stately/radio/-/radio-3.10.4.tgz",
-            "integrity": "sha512-kCIc7tAl4L7Hu4Wt9l2jaa+MzYmAJm0qmC8G8yPMbExpWbLRu6J8Un80GZu+JxvzgDlqDyrVvyv9zFifwH/NkQ==",
-            "dependencies": {
-                "@react-stately/form": "^3.0.3",
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/radio": "^3.8.1",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.10.6",
+            "resolved": "https://registry.npmjs.org/@react-stately/radio/-/radio-3.10.6.tgz",
+            "integrity": "sha512-wiJuUUQ6LuEv0J1DQtkC0+Sed7tO6y3sIPeB+5uIxIIsUpxvNlDcqr+JOkrQm7gZmkmvcfotb5Gv5PqaIl1zKA==",
+            "dependencies": {
+                "@react-stately/form": "^3.0.5",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/radio": "^3.8.3",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/searchfield": {
-            "version": "3.5.3",
-            "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.5.3.tgz",
-            "integrity": "sha512-H0OvlgwPIFdc471ypw79MDjz3WXaVq9+THaY6JM4DIohEJNN5Dwei7O9g6r6m/GqPXJIn5TT3b74kJ2Osc00YQ==",
+            "version": "3.5.5",
+            "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.5.5.tgz",
+            "integrity": "sha512-rKWIVNbxft5eGGxQ4CtcTKGXm2B1AuYSg6kLRQLq+VYspPNq3wfeMtVBeIdy4LNjWXsTmzs2b3o+zkFYdPqPPw==",
             "dependencies": {
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/searchfield": "^3.5.5",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/searchfield": "^3.5.7",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/select": {
-            "version": "3.6.4",
-            "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.6.4.tgz",
-            "integrity": "sha512-whZgF1N53D0/dS8tOFdrswB0alsk5Q5620HC3z+5f2Hpi8gwgAZ8TYa+2IcmMYRiT+bxVuvEc/NirU9yPmqGbA==",
-            "dependencies": {
-                "@react-stately/form": "^3.0.3",
-                "@react-stately/list": "^3.10.5",
-                "@react-stately/overlays": "^3.6.7",
-                "@react-types/select": "^3.9.4",
-                "@react-types/shared": "^3.23.1",
+            "version": "3.6.6",
+            "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.6.6.tgz",
+            "integrity": "sha512-JEpBosWNSXRexE/iReATei1EiVdTIwOWlLcCGw6K7oC/5/f+OHMsh2Kkt/c/RzM/to3vgR+Wbbqwrb712AWgYQ==",
+            "dependencies": {
+                "@react-stately/form": "^3.0.5",
+                "@react-stately/list": "^3.10.7",
+                "@react-stately/overlays": "^3.6.9",
+                "@react-types/select": "^3.9.6",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/selection": {
-            "version": "3.15.1",
-            "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.15.1.tgz",
-            "integrity": "sha512-6TQnN9L0UY9w19B7xzb1P6mbUVBtW840Cw1SjgNXCB3NPaCf59SwqClYzoj8O2ZFzMe8F/nUJtfU1NS65/OLlw==",
+            "version": "3.16.1",
+            "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.16.1.tgz",
+            "integrity": "sha512-qmnmYaXY7IhhzmIiInec1a/yPxlPSBHka6vrWddvt0S6zN7FU5cv6sm69ONUwYwLKSoaNHgOGvZhmsTzyV0O2A==",
             "dependencies": {
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/shared": "^3.23.1",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/slider": {
-            "version": "3.5.4",
-            "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.5.4.tgz",
-            "integrity": "sha512-Jsf7K17dr93lkNKL9ij8HUcoM1sPbq8TvmibD6DhrK9If2lje+OOL8y4n4qreUnfMT56HCAeS9wCO3fg3eMyrw==",
+            "version": "3.5.6",
+            "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.5.6.tgz",
+            "integrity": "sha512-a7DZgpOVjQyGzMLPiVRCVHISPJX8E3bT+qbZpcRQN+F7T7wReOwUt2I8gQMosnnCGWgU6kdYk8snn0obXe70Fg==",
             "dependencies": {
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/slider": "^3.7.3",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/slider": "^3.7.5",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/table": {
-            "version": "3.11.8",
-            "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.11.8.tgz",
-            "integrity": "sha512-EdyRW3lT1/kAVDp5FkEIi1BQ7tvmD2YgniGdLuW/l9LADo0T+oxZqruv60qpUS6sQap+59Riaxl91ClDxrJnpg==",
+            "version": "3.12.1",
+            "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.12.1.tgz",
+            "integrity": "sha512-Cg3lXrWJNrYkD1gqRclMxq0GGiR+ygxdeAqk2jbbsmHU8RSQuzoO/RtUCw6WAKfQjAq4gE0E60TlAsGgCUdJGA==",
             "dependencies": {
-                "@react-stately/collections": "^3.10.7",
+                "@react-stately/collections": "^3.10.9",
                 "@react-stately/flags": "^3.0.3",
-                "@react-stately/grid": "^3.8.7",
-                "@react-stately/selection": "^3.15.1",
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/grid": "^3.2.6",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/table": "^3.9.5",
+                "@react-stately/grid": "^3.9.1",
+                "@react-stately/selection": "^3.16.1",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/grid": "^3.2.8",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/table": "^3.10.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/tabs": {
-            "version": "3.6.6",
-            "resolved": "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.6.6.tgz",
-            "integrity": "sha512-sOLxorH2uqjAA+v1ppkMCc2YyjgqvSGeBDgtR/lyPSDd4CVMoTExszROX2dqG0c8il9RQvzFuufUtQWMY6PgSA==",
+            "version": "3.6.8",
+            "resolved": "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.6.8.tgz",
+            "integrity": "sha512-pLRwnMmXk/IWvbIJYSO5hm3/PiJ/VzrQlwKr6dlOcrDOSVIZpTjnGWHd6mJSDoPiDyBThlN/k3+2pUFMEOAcfw==",
             "dependencies": {
-                "@react-stately/list": "^3.10.5",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/tabs": "^3.3.7",
+                "@react-stately/list": "^3.10.7",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/tabs": "^3.3.9",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/toggle": {
-            "version": "3.7.4",
-            "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.7.4.tgz",
-            "integrity": "sha512-CoYFe9WrhLkDP4HGDpJYQKwfiYCRBAeoBQHv+JWl5eyK61S8xSwoHsveYuEZ3bowx71zyCnNAqWRrmNOxJ4CKA==",
+            "version": "3.7.6",
+            "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.7.6.tgz",
+            "integrity": "sha512-xRZyrjNVu1VCd1xpg5RwmNYs9fXb+JHChoUaRcBmGCCjsPD0R5uR3iNuE17RXJtWS3/8o9IJVn90+/7NW7boOg==",
             "dependencies": {
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/checkbox": "^3.8.1",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/checkbox": "^3.8.3",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/tooltip": {
-            "version": "3.4.9",
-            "resolved": "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.4.9.tgz",
-            "integrity": "sha512-P7CDJsdoKarz32qFwf3VNS01lyC+63gXpDZG31pUu+EO5BeQd4WKN/AH1Beuswpr4GWzxzFc1aXQgERFGVzraA==",
+            "version": "3.4.11",
+            "resolved": "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.4.11.tgz",
+            "integrity": "sha512-r1ScIXau2LZ/lUUBQ5PI01S2TB2urF2zrPzNM2xgngFLlG2uTyfIgMga6/035quQQKd3Bd0qGigMvTgZ3GRGEg==",
             "dependencies": {
-                "@react-stately/overlays": "^3.6.7",
-                "@react-types/tooltip": "^3.4.9",
+                "@react-stately/overlays": "^3.6.9",
+                "@react-types/tooltip": "^3.4.11",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/tree": {
-            "version": "3.8.1",
-            "resolved": "https://registry.npmjs.org/@react-stately/tree/-/tree-3.8.1.tgz",
-            "integrity": "sha512-LOdkkruJWch3W89h4B/bXhfr0t0t1aRfEp+IMrrwdRAl23NaPqwl5ILHs4Xu5XDHqqhg8co73pHrJwUyiTWEjw==",
+            "version": "3.8.3",
+            "resolved": "https://registry.npmjs.org/@react-stately/tree/-/tree-3.8.3.tgz",
+            "integrity": "sha512-9sRQOxkK7ZMdtSTGHx0sMabHC39PEM4tMl+IdJKkmcp60bfsm3p6LHXhha3E58jwnZaemBfUrlQmTP/E26BbGw==",
             "dependencies": {
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/selection": "^3.15.1",
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/shared": "^3.23.1",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/selection": "^3.16.1",
+                "@react-stately/utils": "^3.10.2",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/utils": {
-            "version": "3.10.1",
-            "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.1.tgz",
-            "integrity": "sha512-VS/EHRyicef25zDZcM/ClpzYMC5i2YGN6uegOeQawmgfGjb02yaCX0F0zR69Pod9m2Hr3wunTbtpgVXvYbZItg==",
+            "version": "3.10.2",
+            "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.2.tgz",
+            "integrity": "sha512-fh6OTQtbeQC0ywp6LJuuKs6tKIgFvt/DlIZEcIpGho6/oZG229UnIk6TUekwxnDbumuYyan6D9EgUtEMmT8UIg==",
             "dependencies": {
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-stately/virtualizer": {
-            "version": "3.7.1",
-            "resolved": "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-3.7.1.tgz",
-            "integrity": "sha512-voHgE6EQ+oZaLv6u2umKxakvIKNkCQuUihqKACTjdslp7SJh4Mvs3oLBI0hf0JOh+rCcFIKDvQtFwy1fXFRYBA==",
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-4.0.1.tgz",
+            "integrity": "sha512-HCje3SlLItQFAiBHH4JZhz74mMCe2g+Q8woJa6kdKlvFqsNdmhtFHuuIr1uW6LWj76j2N0Xaa8Z7fV1f5ovX0Q==",
             "dependencies": {
-                "@react-aria/utils": "^3.24.1",
-                "@react-types/shared": "^3.23.1",
+                "@react-aria/utils": "^3.25.1",
+                "@react-types/shared": "^3.24.1",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/actionbar": {
-            "version": "3.1.7",
-            "resolved": "https://registry.npmjs.org/@react-types/actionbar/-/actionbar-3.1.7.tgz",
-            "integrity": "sha512-yohxM+R9o/HGADL7NdTH9tC9BnWrVYKsutobjWzVQZHGoaHEqBbz03dk3m9UvFMnw7g6kjtGxhOJQpztz7nk3Q==",
+            "version": "3.1.9",
+            "resolved": "https://registry.npmjs.org/@react-types/actionbar/-/actionbar-3.1.9.tgz",
+            "integrity": "sha512-omCribEByWYcDr27W63LpmFq+muACc949UzCcMzlc6fvkKc6Gq+HjRRoTQjX6k8hXXFqEbQoYJFVyRXnig6u5g==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/actiongroup": {
-            "version": "3.4.9",
-            "resolved": "https://registry.npmjs.org/@react-types/actiongroup/-/actiongroup-3.4.9.tgz",
-            "integrity": "sha512-n6lGBLm8HxLguG4om5ysMCexSdMWNhM5L0yGjA4pZxdoKZborPALDN/Ao57svnTwaSJmeExvTwHIFds1yr4AXQ==",
+            "version": "3.4.11",
+            "resolved": "https://registry.npmjs.org/@react-types/actiongroup/-/actiongroup-3.4.11.tgz",
+            "integrity": "sha512-gO/A+nbPoDwovqWlEyILNlfBY1loXFR0+P7OzH+vqppCHFz+Y2dF6Ry2LqUAmE0XPaYLzwg4Y/Nkuc20jIVujQ==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/avatar": {
-            "version": "3.0.7",
-            "resolved": "https://registry.npmjs.org/@react-types/avatar/-/avatar-3.0.7.tgz",
-            "integrity": "sha512-FXws1/o0Vy3yJcBDdKYPElNzpcVjdkck6KHGQyxAkKe7vvtFUcHpzz9fxEO5kRLwTv6j7EahXsJeqsH9TpFWuA==",
+            "version": "3.0.9",
+            "resolved": "https://registry.npmjs.org/@react-types/avatar/-/avatar-3.0.9.tgz",
+            "integrity": "sha512-lvzL0DHUaZxLXci9PbtnSWxO/vrcqyPm5KBq3DwiJ/FreAQZjbk7SfOO8we9mPXbe+XePexK/x9n90BtGMKdLw==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/badge": {
-            "version": "3.1.9",
-            "resolved": "https://registry.npmjs.org/@react-types/badge/-/badge-3.1.9.tgz",
-            "integrity": "sha512-GNvg3cULRiUxXZYmOOIaua0KSL72jnLwv/2LLbQeYQystLaEmsibmdoRvfQN80mEQ1f3WFfhZogiG31+4MS/xg==",
+            "version": "3.1.11",
+            "resolved": "https://registry.npmjs.org/@react-types/badge/-/badge-3.1.11.tgz",
+            "integrity": "sha512-ToIZOT5xRAHqZ9H9v8UkcC+Gds4dKmmIAMb7+aWXGCKIuRlV4wLD1WZJBS9gQlv+WlwvIOEVOgtwktpTrZJW0Q==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/breadcrumbs": {
-            "version": "3.7.5",
-            "resolved": "https://registry.npmjs.org/@react-types/breadcrumbs/-/breadcrumbs-3.7.5.tgz",
-            "integrity": "sha512-lV9IDYsMiu2TgdMIjEmsOE0YWwjb3jhUNK1DCZZfq6uWuiHLgyx2EncazJBUWSjHJ4ta32j7xTuXch+8Ai6u/A==",
+            "version": "3.7.7",
+            "resolved": "https://registry.npmjs.org/@react-types/breadcrumbs/-/breadcrumbs-3.7.7.tgz",
+            "integrity": "sha512-ZmhXwD2LLzfEA2OvOCp/QvXu8A/Edsrn5q0qUDGsmOZj9SCVeT82bIv8P+mQnATM13mi2gyoik6102Jc1OscJA==",
             "dependencies": {
-                "@react-types/link": "^3.5.5",
-                "@react-types/shared": "^3.23.1"
+                "@react-types/link": "^3.5.7",
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/button": {
-            "version": "3.9.4",
-            "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.9.4.tgz",
-            "integrity": "sha512-raeQBJUxBp0axNF74TXB8/H50GY8Q3eV6cEKMbZFP1+Dzr09Ngv0tJBeW0ewAxAguNH5DRoMUAUGIXtSXskVdA==",
+            "version": "3.9.6",
+            "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.9.6.tgz",
+            "integrity": "sha512-8lA+D5JLbNyQikf8M/cPP2cji91aVTcqjrGpDqI7sQnaLFikM8eFR6l1ZWGtZS5MCcbfooko77ha35SYplSQvw==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/buttongroup": {
-            "version": "3.3.9",
-            "resolved": "https://registry.npmjs.org/@react-types/buttongroup/-/buttongroup-3.3.9.tgz",
-            "integrity": "sha512-3hEWI/GOsY8Z3db8gjEXbxl+6E0ioBNMxfN8jIeiNnSWSDG56MLNArJLowylPrwlrp5SnxLh1WBj44OHqEE3Tg==",
+            "version": "3.3.11",
+            "resolved": "https://registry.npmjs.org/@react-types/buttongroup/-/buttongroup-3.3.11.tgz",
+            "integrity": "sha512-29F+GYWdbjuheDZVW9xhju03CQVK401i0DPH7TGqnlNZqteqF/aHqwxRyFT8490ad7og3ZuvXywTBQCwIfbh9Q==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/calendar": {
-            "version": "3.4.6",
-            "resolved": "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.4.6.tgz",
-            "integrity": "sha512-WSntZPwtvsIYWvBQRAPvuCn55UTJBZroTvX0vQvWykJRQnPAI20G1hMQ3dNsnAL+gLZUYxBXn66vphmjUuSYew==",
+            "version": "3.4.8",
+            "resolved": "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.4.8.tgz",
+            "integrity": "sha512-KVampt/X4uJvWU0TsxIdgPdXIAUClGtxcDWHzuFRJ7YUYkA4rH8Lad0kQ1mVehnwOLpuba8j9GCYKorkbln0gw==",
             "dependencies": {
-                "@internationalized/date": "^3.5.4",
-                "@react-types/shared": "^3.23.1"
+                "@internationalized/date": "^3.5.5",
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/checkbox": {
-            "version": "3.8.1",
-            "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.8.1.tgz",
-            "integrity": "sha512-5/oVByPw4MbR/8QSdHCaalmyWC71H/QGgd4aduTJSaNi825o+v/hsN2/CH7Fq9atkLKsC8fvKD00Bj2VGaKriQ==",
+            "version": "3.8.3",
+            "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.8.3.tgz",
+            "integrity": "sha512-f4c1mnLEt0iS1NMkyZXgT3q3AgcxzDk7w6MSONOKydcnh0xG5L2oefY14DhVDLkAuQS7jThlUFwiAs+MxiO3MA==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/color": {
-            "version": "3.0.0-beta.25",
-            "resolved": "https://registry.npmjs.org/@react-types/color/-/color-3.0.0-beta.25.tgz",
-            "integrity": "sha512-D24ASvLeSWouBwOBi4ftUe4/BhrZj5AiHV7tXwrVeMGOy9Z9jyeK65Xysq+R3ecaSONLXsgai5CQMvj13cOacA==",
+            "version": "3.0.0-rc.1",
+            "resolved": "https://registry.npmjs.org/@react-types/color/-/color-3.0.0-rc.1.tgz",
+            "integrity": "sha512-aw6FzrBlZTWKrFaFskM7e3AFICe6JqH10wO0E919goa3LZDDFbyYEwRpatwjIyiZH1elEUkFPgwqpv3ZcPPn8g==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1",
-                "@react-types/slider": "^3.7.3"
+                "@react-types/shared": "^3.24.1",
+                "@react-types/slider": "^3.7.5"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/combobox": {
-            "version": "3.11.1",
-            "resolved": "https://registry.npmjs.org/@react-types/combobox/-/combobox-3.11.1.tgz",
-            "integrity": "sha512-UNc3OHt5cUt5gCTHqhQIqhaWwKCpaNciD8R7eQazmHiA9fq8ROlV+7l3gdNgdhJbTf5Bu/V5ISnN7Y1xwL3zqQ==",
+            "version": "3.12.1",
+            "resolved": "https://registry.npmjs.org/@react-types/combobox/-/combobox-3.12.1.tgz",
+            "integrity": "sha512-bd5YwHZWtgnJx4jGbplWbYzXj7IbO5w3IY5suNR7r891rx6IktquZ8GQwyYH0pQ/x+X5LdK2xI59i6+QC2PmlA==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/contextualhelp": {
-            "version": "3.2.10",
-            "resolved": "https://registry.npmjs.org/@react-types/contextualhelp/-/contextualhelp-3.2.10.tgz",
-            "integrity": "sha512-x4rODNQfAO2YeVumkztTsUieOt4z7OXolZY7BLJgT1qonfPwJGLqf+KUayqXuX9l2CHakcGYDGaUxTUvwINQdw==",
+            "version": "3.2.12",
+            "resolved": "https://registry.npmjs.org/@react-types/contextualhelp/-/contextualhelp-3.2.12.tgz",
+            "integrity": "sha512-5PwE2tajqVYzjatdvux6dpGb8trmqGBDp04nuTn010U+HZhxylAe12iU0/Lz+0M7dWpBlVfusE42TLvZdD5VzA==",
             "dependencies": {
-                "@react-types/overlays": "^3.8.7",
-                "@react-types/shared": "^3.23.1"
+                "@react-types/overlays": "^3.8.9",
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/datepicker": {
-            "version": "3.7.4",
-            "resolved": "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.7.4.tgz",
-            "integrity": "sha512-ZfvgscvNzBJpYyVWg3nstJtA/VlWLwErwSkd1ivZYam859N30w8yH+4qoYLa6FzWLCFlrsRHyvtxlEM7lUAt5A==",
+            "version": "3.8.1",
+            "resolved": "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.8.1.tgz",
+            "integrity": "sha512-ZpxHHVT3rmZ4YsYP4TWCZSMSfOUm+067mZyyGLmvHxg55eYmctiB4uMgrRCqDoeiSiOjtxad0VtpPjf6ftK1GQ==",
             "dependencies": {
-                "@internationalized/date": "^3.5.4",
-                "@react-types/calendar": "^3.4.6",
-                "@react-types/overlays": "^3.8.7",
-                "@react-types/shared": "^3.23.1"
+                "@internationalized/date": "^3.5.5",
+                "@react-types/calendar": "^3.4.8",
+                "@react-types/overlays": "^3.8.9",
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/dialog": {
-            "version": "3.5.10",
-            "resolved": "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.5.10.tgz",
-            "integrity": "sha512-S9ga+edOLNLZw7/zVOnZdT5T40etpzUYBXEKdFPbxyPYnERvRxJAsC1/ASuBU9fQAXMRgLZzADWV+wJoGS/X9g==",
+            "version": "3.5.12",
+            "resolved": "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.5.12.tgz",
+            "integrity": "sha512-JmpQbSpXltqEyYfEwoqDolABIiojeExkqolHNdQlayIsfFuSxZxNwXZPOpz58Ri/iwv21JP7K3QF0Gb2Ohxl9w==",
             "dependencies": {
-                "@react-types/overlays": "^3.8.7",
-                "@react-types/shared": "^3.23.1"
+                "@react-types/overlays": "^3.8.9",
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/divider": {
-            "version": "3.3.9",
-            "resolved": "https://registry.npmjs.org/@react-types/divider/-/divider-3.3.9.tgz",
-            "integrity": "sha512-SQ3XWS16j3VZg3MGByJ1CjWDfARn+viBDay6SibAFzMqlqVbSol2nw1hQ1JPaT3zeW8C/354q+OhBsIFDOaE7w==",
+            "version": "3.3.11",
+            "resolved": "https://registry.npmjs.org/@react-types/divider/-/divider-3.3.11.tgz",
+            "integrity": "sha512-pnyEhIK21K8K10cvkXID1yx4V8jpY5uRO69o8npyq846p7RSercGGGQNE/vPSJXEViZrXTrf2KyNSPFU2x5INw==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/form": {
-            "version": "3.7.4",
-            "resolved": "https://registry.npmjs.org/@react-types/form/-/form-3.7.4.tgz",
-            "integrity": "sha512-HZojAWrb6feYnhDEOy3vBamDVAHDl0l2JQZ7aIDLHmeTAGQC3JNZcm2fLTxqLye46zz8w8l8OHgI+NdD4PHdOw==",
+            "version": "3.7.6",
+            "resolved": "https://registry.npmjs.org/@react-types/form/-/form-3.7.6.tgz",
+            "integrity": "sha512-lhS2y1bVtRnyYjkM+ylJUp2g663ZNbeZxu2o+mFfD5c2wYmVLA58IWR90c7DL8IVUitoANnZ1JPhhXvutiFpQQ==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/grid": {
-            "version": "3.2.6",
-            "resolved": "https://registry.npmjs.org/@react-types/grid/-/grid-3.2.6.tgz",
-            "integrity": "sha512-XfHenL2jEBUYrhKiPdeM24mbLRXUn79wVzzMhrNYh24nBwhsPPpxF+gjFddT3Cy8dt6tRInfT6pMEu9nsXwaHw==",
+            "version": "3.2.8",
+            "resolved": "https://registry.npmjs.org/@react-types/grid/-/grid-3.2.8.tgz",
+            "integrity": "sha512-6PJrpukwMqlv3IhJSDkJuVbhHM8Oe6hd2supWqd9adMXrlSP7QHt9a8SgFcFblCCTx8JzUaA0PvY5sTudcEtOQ==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/illustratedmessage": {
-            "version": "3.3.9",
-            "resolved": "https://registry.npmjs.org/@react-types/illustratedmessage/-/illustratedmessage-3.3.9.tgz",
-            "integrity": "sha512-a/X+sGzUA+pkLkKDZzy/QpUtOY6qtFpsPs6lfY37TLwCEQmS8a1VKrc1ItlQVRgIvwuqJXKvrJpGOAw+RjVwHw==",
+            "version": "3.3.11",
+            "resolved": "https://registry.npmjs.org/@react-types/illustratedmessage/-/illustratedmessage-3.3.11.tgz",
+            "integrity": "sha512-GW3DCRU1YHv1VteVSTOUN3FH4Z5FCm22k5yTjhb8NjNP0eQ/tH3Gu6pZCVKTiqmuC2Z15nXZGdcPMmzKA8915Q==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/image": {
-            "version": "3.4.1",
-            "resolved": "https://registry.npmjs.org/@react-types/image/-/image-3.4.1.tgz",
-            "integrity": "sha512-6vA3vEzjXrr701i1J43DkyPziRN7jfKSdarGDP+61dOcvbiLnuTY9t+r/zXo1SdewbjF5RVliB2ys9Bb654YTg==",
+            "version": "3.4.3",
+            "resolved": "https://registry.npmjs.org/@react-types/image/-/image-3.4.3.tgz",
+            "integrity": "sha512-w5oxRYDKTGXHZr4CtLdi8759v2YU3Qux6kPj4fRq67hYRCKQxJOYdqQTlfLwkshe/ddFPb3Geu5GTdQtW+GnDw==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/label": {
-            "version": "3.9.3",
-            "resolved": "https://registry.npmjs.org/@react-types/label/-/label-3.9.3.tgz",
-            "integrity": "sha512-PGVg/pBYNx3Ft59VNCvG5oqk4pXfS2Gs7t3TGnlBB1d+EXB9BbixJbOAO1PvRqt8SPCNvEAAAVfG6Vf+nOhSWw==",
+            "version": "3.9.5",
+            "resolved": "https://registry.npmjs.org/@react-types/label/-/label-3.9.5.tgz",
+            "integrity": "sha512-kvkPX/S7acwX2E5usekJjpFYFQyykbKFharQvYn06x4sYHevRnxzcRgPkaBynaTu2i5MeQ/Yot7VwyBfEleqSA==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/layout": {
-            "version": "3.3.15",
-            "resolved": "https://registry.npmjs.org/@react-types/layout/-/layout-3.3.15.tgz",
-            "integrity": "sha512-Rj3M0TWmsag83gvFDY6UnfUkNPrA/FLuJ0kEiOryjjffoI0wTxmTAPpIgG4h7YSxpQJD6g6xQ8bkIWEMCXWyag==",
+            "version": "3.3.17",
+            "resolved": "https://registry.npmjs.org/@react-types/layout/-/layout-3.3.17.tgz",
+            "integrity": "sha512-CoDVto9eq9ZX65SSrPS4XSEZKBvKdnBs41B217Yai2K/s5VyyEJ0zOGtohghJOnalBCG7Ci4if8VnE27lonvcQ==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/link": {
-            "version": "3.5.5",
-            "resolved": "https://registry.npmjs.org/@react-types/link/-/link-3.5.5.tgz",
-            "integrity": "sha512-G6P5WagHDR87npN7sEuC5IIgL1GsoY4WFWKO4734i2CXRYx24G9P0Su3AX4GA3qpspz8sK1AWkaCzBMmvnunfw==",
+            "version": "3.5.7",
+            "resolved": "https://registry.npmjs.org/@react-types/link/-/link-3.5.7.tgz",
+            "integrity": "sha512-2WyaVmm1qr9UrSG3Dq6iz+2ziuVp+DH8CsYZ9CA6aNNb6U18Hxju3LTPb4a5gM0eC7W0mQGNBmrgGlAdDZEJOw==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/listbox": {
-            "version": "3.4.9",
-            "resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.4.9.tgz",
-            "integrity": "sha512-S5G+WmNKUIOPZxZ4svWwWQupP3C6LmVfnf8QQmPDvwYXGzVc0WovkqUWyhhjJirFDswTXRCO9p0yaTHHIlkdwQ==",
+            "version": "3.5.1",
+            "resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.5.1.tgz",
+            "integrity": "sha512-n5bOgD9lgfK1qaLtag9WPnu151SwXBCNn/OgGY/Br9mWRl+nPUEYtFcPX+2VCld7uThf54kwrTmzlFnaraIlcw==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/menu": {
-            "version": "3.9.9",
-            "resolved": "https://registry.npmjs.org/@react-types/menu/-/menu-3.9.9.tgz",
-            "integrity": "sha512-FamUaPVs1Fxr4KOMI0YcR2rYZHoN7ypGtgiEiJ11v/tEPjPPGgeKDxii0McCrdOkjheatLN1yd2jmMwYj6hTDg==",
+            "version": "3.9.11",
+            "resolved": "https://registry.npmjs.org/@react-types/menu/-/menu-3.9.11.tgz",
+            "integrity": "sha512-IguQVF70d7aHXgWB1Rd2a/PiIuLZ2Nt7lyayJshLcy/NLOYmgpTmTyn2WCtlA5lTfQwmQrNFf4EvnWkeljJXdA==",
             "dependencies": {
-                "@react-types/overlays": "^3.8.7",
-                "@react-types/shared": "^3.23.1"
+                "@react-types/overlays": "^3.8.9",
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/meter": {
-            "version": "3.4.1",
-            "resolved": "https://registry.npmjs.org/@react-types/meter/-/meter-3.4.1.tgz",
-            "integrity": "sha512-AIJV4NDFAqKH94s02c5Da4TH2qgJjfrw978zuFM0KUBFD85WRPKh7MvgWpomvUgmzqE6lMCzIdi1KPKqrRabdw==",
+            "version": "3.4.3",
+            "resolved": "https://registry.npmjs.org/@react-types/meter/-/meter-3.4.3.tgz",
+            "integrity": "sha512-Y2fX5CTAPGRKxVSeepbeyN6/K+wlF9pMRcNxTSU2qDwdoFqNCtTWMcWuCsU/Y2L/zU0jFWu4x0Vo7WkrcsgcMA==",
             "dependencies": {
-                "@react-types/progress": "^3.5.4"
+                "@react-types/progress": "^3.5.6"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/numberfield": {
-            "version": "3.8.3",
-            "resolved": "https://registry.npmjs.org/@react-types/numberfield/-/numberfield-3.8.3.tgz",
-            "integrity": "sha512-z5fGfVj3oh5bmkw9zDvClA1nDBSFL9affOuyk2qZ/M2SRUmykDAPCksbfcMndft0XULWKbF4s2CYbVI+E/yrUA==",
+            "version": "3.8.5",
+            "resolved": "https://registry.npmjs.org/@react-types/numberfield/-/numberfield-3.8.5.tgz",
+            "integrity": "sha512-LVWggkxwd1nyVZomXBPfQA1E4I4/i4PBifjcDs2AfcV7q5RE9D+DVIDXsYucVOBxPlDOxiAq/T9ypobspWSwHw==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/overlays": {
-            "version": "3.8.7",
-            "resolved": "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.8.7.tgz",
-            "integrity": "sha512-zCOYvI4at2DkhVpviIClJ7bRrLXYhSg3Z3v9xymuPH3mkiuuP/dm8mUCtkyY4UhVeUTHmrQh1bzaOP00A+SSQA==",
+            "version": "3.8.9",
+            "resolved": "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.8.9.tgz",
+            "integrity": "sha512-9ni9upQgXPnR+K9cWmbYWvm3ll9gH8P/XsEZprqIV5zNLMF334jADK48h4jafb1X9RFnj0WbHo6BqcSObzjTig==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/progress": {
-            "version": "3.5.4",
-            "resolved": "https://registry.npmjs.org/@react-types/progress/-/progress-3.5.4.tgz",
-            "integrity": "sha512-JNc246sTjasPyx5Dp7/s0rp3Bz4qlu4LrZTulZlxWyb53WgBNL7axc26CCi+I20rWL9+c7JjhrRxnLl/1cLN5g==",
+            "version": "3.5.6",
+            "resolved": "https://registry.npmjs.org/@react-types/progress/-/progress-3.5.6.tgz",
+            "integrity": "sha512-Nh43sjQ5adyN1bTHBPRaIPhXUdBqP0miYeJpeMY3V/KUl4qmouJLwDnccwFG4xLm6gBfYe22lgbbV7nAfNnuTQ==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/provider": {
-            "version": "3.8.1",
-            "resolved": "https://registry.npmjs.org/@react-types/provider/-/provider-3.8.1.tgz",
-            "integrity": "sha512-Sm59ufxdHh6fGfeUbviNQhRvtI0FMEX1gn9Okc8nL7iTVbAAitT746x0itM+xwhFLDI6gSY8FILDWc5/kIxzxA==",
+            "version": "3.8.3",
+            "resolved": "https://registry.npmjs.org/@react-types/provider/-/provider-3.8.3.tgz",
+            "integrity": "sha512-tUt/94BRS0gZFprBAErYXauyONGcJM8ZWLCae925kZ3iLdzRWxG5qoNyKZ3SRKODdLDvJAgmPjImpj8GzYc3Fg==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/radio": {
-            "version": "3.8.1",
-            "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.8.1.tgz",
-            "integrity": "sha512-bK0gio/qj1+0Ldu/3k/s9BaOZvnnRgvFtL3u5ky479+aLG5qf1CmYed3SKz8ErZ70JkpuCSrSwSCFf0t1IHovw==",
+            "version": "3.8.3",
+            "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.8.3.tgz",
+            "integrity": "sha512-fUVJt4Bb6jOReFqnhHVNxWXH7t6c60uSFfoPKuXt/xI9LL1i2jhpur0ggpTfIn3qLIAmNBU6bKBCWAdr4KjeVQ==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/searchfield": {
-            "version": "3.5.5",
-            "resolved": "https://registry.npmjs.org/@react-types/searchfield/-/searchfield-3.5.5.tgz",
-            "integrity": "sha512-T/NHg12+w23TxlXMdetogLDUldk1z5dDavzbnjKrLkajLb221bp8brlR/+O6C1CtFpuJGALqYHgTasU1qkQFSA==",
+            "version": "3.5.7",
+            "resolved": "https://registry.npmjs.org/@react-types/searchfield/-/searchfield-3.5.7.tgz",
+            "integrity": "sha512-dyuPwNWGswRZfb4i50Q1Q3tCwTBxRLkrAxcMs+Rf2Rl4t93bawBdSdIQuvxu1KEhgd0EXA9ZUW53ZplqfVmtiw==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1",
-                "@react-types/textfield": "^3.9.3"
+                "@react-types/shared": "^3.24.1",
+                "@react-types/textfield": "^3.9.5"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/select": {
-            "version": "3.9.4",
-            "resolved": "https://registry.npmjs.org/@react-types/select/-/select-3.9.4.tgz",
-            "integrity": "sha512-xI7dnOW2st91fPPcv6hdtrTdcfetYiqZuuVPZ5TRobY7Q10/Zqqe/KqtOw1zFKUj9xqNJe4Ov3xP5GSdcO60Eg==",
+            "version": "3.9.6",
+            "resolved": "https://registry.npmjs.org/@react-types/select/-/select-3.9.6.tgz",
+            "integrity": "sha512-cVSFR0eJLup/ht1Uto+y8uyLmHO89J6wNh65SIHb3jeVz9oLBAedP3YNI2qB+F9qFMUcA8PBSLXIIuT6gXzLgQ==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/shared": {
-            "version": "3.23.1",
-            "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.23.1.tgz",
-            "integrity": "sha512-5d+3HbFDxGZjhbMBeFHRQhexMFt4pUce3okyRtUVKbbedQFUrtXSBg9VszgF2RTeQDKDkMCIQDtz5ccP/Lk1gw==",
+            "version": "3.24.1",
+            "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.24.1.tgz",
+            "integrity": "sha512-AUQeGYEm/zDTN6zLzdXolDxz3Jk5dDL7f506F07U8tBwxNNI3WRdhU84G0/AaFikOZzDXhOZDr3MhQMzyE7Ydw==",
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/slider": {
-            "version": "3.7.3",
-            "resolved": "https://registry.npmjs.org/@react-types/slider/-/slider-3.7.3.tgz",
-            "integrity": "sha512-F8qFQaD2mqug2D0XeWMmjGBikiwbdERFlhFzdvNGbypPLz3AZICBKp1ZLPWdl0DMuy03G/jy6Gl4mDobl7RT2g==",
+            "version": "3.7.5",
+            "resolved": "https://registry.npmjs.org/@react-types/slider/-/slider-3.7.5.tgz",
+            "integrity": "sha512-bRitwQRQjQoOcKEdPMljnvm474dwrmsc6pdsVQDh/qynzr+KO9IHuYc3qPW53WVE2hMQJDohlqtCAWQXWQ5Vcg==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/statuslight": {
-            "version": "3.3.9",
-            "resolved": "https://registry.npmjs.org/@react-types/statuslight/-/statuslight-3.3.9.tgz",
-            "integrity": "sha512-6nC17gluvrMCJkb0mihzqAaz8wn0ghfgk1ILkL8CUobsqJU6pW4eGJXNoZCd5wHT/YjwnupzfhHcbMj93AHzWQ==",
+            "version": "3.3.11",
+            "resolved": "https://registry.npmjs.org/@react-types/statuslight/-/statuslight-3.3.11.tgz",
+            "integrity": "sha512-EYxya+R4PpgB1V8pcn2w4fgFbPMCuya+TeYDoO6Izp3AQRWYgQRwM8Gz3IQ/qXFvwzT9e1fEuOHPHqPW1Tiitw==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/switch": {
-            "version": "3.5.3",
-            "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.5.3.tgz",
-            "integrity": "sha512-Nb6+J5MrPaFa8ZNFKGMzAsen/NNzl5UG/BbC65SLGPy7O0VDa/sUpn7dcu8V2xRpRwwIN/Oso4v63bt2sgdkgA==",
+            "version": "3.5.5",
+            "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.5.5.tgz",
+            "integrity": "sha512-SZx1Bd+COhAOs/RTifbZG+uq/llwba7VAKx7XBeX4LeIz1dtguy5bigOBgFTMQi4qsIVCpybSWEEl+daj4XFPw==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/table": {
-            "version": "3.9.5",
-            "resolved": "https://registry.npmjs.org/@react-types/table/-/table-3.9.5.tgz",
-            "integrity": "sha512-fgM2j9F/UR4Anmd28CueghCgBwOZoCVyN8fjaIFPd2MN4gCwUUfANwxLav65gZk4BpwUXGoQdsW+X50L3555mg==",
+            "version": "3.10.1",
+            "resolved": "https://registry.npmjs.org/@react-types/table/-/table-3.10.1.tgz",
+            "integrity": "sha512-xsNh0Gm4GtNeSknZqkMsfGvc94fycmfhspGO+FzQKim2hB5k4yILwd+lHYQ2UKW6New9GVH/zN2Pd3v67IeZ2g==",
             "dependencies": {
-                "@react-types/grid": "^3.2.6",
-                "@react-types/shared": "^3.23.1"
+                "@react-types/grid": "^3.2.8",
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/tabs": {
-            "version": "3.3.7",
-            "resolved": "https://registry.npmjs.org/@react-types/tabs/-/tabs-3.3.7.tgz",
-            "integrity": "sha512-ZdLe5xOcFX6+/ni45Dl2jO0jFATpTnoSqj6kLIS/BYv8oh0n817OjJkLf+DS3CLfNjApJWrHqAk34xNh6nRnEg==",
+            "version": "3.3.9",
+            "resolved": "https://registry.npmjs.org/@react-types/tabs/-/tabs-3.3.9.tgz",
+            "integrity": "sha512-3Q9kRVvg/qDyeJR/W1+C2z2OyvDWQrSLvOCvAezX5UKzww4rBEAA8OqBlyDwn7q3fiwrh/m64l6p+dbln+RdxQ==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/text": {
-            "version": "3.3.9",
-            "resolved": "https://registry.npmjs.org/@react-types/text/-/text-3.3.9.tgz",
-            "integrity": "sha512-JJTmUstFXikZHQhf+0VELODGz1jUcSgXOTYJxTMiMtSjLOSCW5G+pRhT80MRgxOeuD0Z7p0XghUXo3ruD694HA==",
+            "version": "3.3.11",
+            "resolved": "https://registry.npmjs.org/@react-types/text/-/text-3.3.11.tgz",
+            "integrity": "sha512-e78lt//FlmrJSPNgZZYT2LoBXFqoG5MX/kaS738bO9WkUR4nE1wtBBMmztQxQTvqz0cV/gaJEHZla4Orp+Civw==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/textfield": {
-            "version": "3.9.3",
-            "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.9.3.tgz",
-            "integrity": "sha512-DoAY6cYOL0pJhgNGI1Rosni7g72GAt4OVr2ltEx2S9ARmFZ0DBvdhA9lL2nywcnKMf27PEJcKMXzXc10qaHsJw==",
+            "version": "3.9.5",
+            "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.9.5.tgz",
+            "integrity": "sha512-0hwZI4WXSEStPzdltKwbNUZWlgHtwbxMWE0LfqIzEW8RB7DyBflYSKzLyTBFqwUZ8j3C1gWy9c9OPSeCOq792Q==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/tooltip": {
-            "version": "3.4.9",
-            "resolved": "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.4.9.tgz",
-            "integrity": "sha512-wZ+uF1+Zc43qG+cOJzioBmLUNjRa7ApdcT0LI1VvaYvH5GdfjzUJOorLX9V/vAci0XMJ50UZ+qsh79aUlw2yqg==",
+            "version": "3.4.11",
+            "resolved": "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.4.11.tgz",
+            "integrity": "sha512-WPikHQxeT5Lb09yJEaW6Ja3ecE0g1YM6ukWYS2v/iZLUPn5YlYrGytspuCYQNSh/u7suCz4zRLEHYCl7OCigjw==",
             "dependencies": {
-                "@react-types/overlays": "^3.8.7",
-                "@react-types/shared": "^3.23.1"
+                "@react-types/overlays": "^3.8.9",
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/view": {
-            "version": "3.4.9",
-            "resolved": "https://registry.npmjs.org/@react-types/view/-/view-3.4.9.tgz",
-            "integrity": "sha512-HY969whOXKg10ZqIrXOF12wm3rDwNaKaK9fzqhhrUc94+JR4OPKQctps+HeonAXscxy2yMy8V1/2yjiEwluvAA==",
+            "version": "3.4.11",
+            "resolved": "https://registry.npmjs.org/@react-types/view/-/view-3.4.11.tgz",
+            "integrity": "sha512-FgWQGppdqAHfnRUyjc01nRdMKSEpJBze99+k+xscW+Lv6XNXQR3PlC8QOpcEZ4gGy9Xx1YkbKHDX1eOCNTeYnA==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@react-types/well": {
-            "version": "3.3.9",
-            "resolved": "https://registry.npmjs.org/@react-types/well/-/well-3.3.9.tgz",
-            "integrity": "sha512-3ZlxjkWXupxx0PaxpDc4Pqxxgnzp8iJkilbJ3LY5F+RJwqDm0gkKnWcFjlVJw9LkM7Emjrvm1R8naSGzJ7wJ2A==",
+            "version": "3.3.11",
+            "resolved": "https://registry.npmjs.org/@react-types/well/-/well-3.3.11.tgz",
+            "integrity": "sha512-xHe0t/4ndLIG5nrbGBEFJCeYuni4VML8t6rwEOWbQTTke6DSYZ53DPL7aepO4IP1hW0ufEOJ0WV7Bx7YTUMu+Q==",
             "dependencies": {
-                "@react-types/shared": "^3.23.1"
+                "@react-types/shared": "^3.24.1"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@rkusa/linebreak": {
@@ -7099,11 +7103,11 @@
             "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="
         },
         "node_modules/@sindresorhus/is": {
-            "version": "6.3.1",
-            "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-6.3.1.tgz",
-            "integrity": "sha512-FX4MfcifwJyFOI2lPoX7PQxCqx8BG1HCho7WdiXwpEQx1Ycij0JxkfYtGK7yqNScrZGSlt6RE6sw8QYoH7eKnQ==",
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.0.0.tgz",
+            "integrity": "sha512-WDTlVTyvFivSOuyvMeedzg2hdoBLZ3f1uNVuEida2Rl9BrfjrIRjWA/VZIrMRLvSwJYCAlCRA3usDt1THytxWQ==",
             "engines": {
-                "node": ">=16"
+                "node": ">=18"
             },
             "funding": {
                 "url": "https://github.com/sindresorhus/is?sponsor=1"
@@ -7115,31 +7119,31 @@
             "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="
         },
         "node_modules/@spectrum-icons/ui": {
-            "version": "3.6.7",
-            "resolved": "https://registry.npmjs.org/@spectrum-icons/ui/-/ui-3.6.7.tgz",
-            "integrity": "sha512-l08Juk6w8UUpM+xXNVq9LBJ0pxMC1tynXBurTZ135twdtMwofrZmtSHUYdzaRJtm31S9E/+C1Toci1I8aw7Wlw==",
+            "version": "3.6.9",
+            "resolved": "https://registry.npmjs.org/@spectrum-icons/ui/-/ui-3.6.9.tgz",
+            "integrity": "sha512-pxgEoSfce2Vcijh+lizPgCPwAIaBYkOHwWaOXTEHn9REglAnMADdmyAyxib84JSxVY5funJ3AWPKYbEEICEXIg==",
             "dependencies": {
-                "@adobe/react-spectrum-ui": "1.2.0",
-                "@react-spectrum/icon": "^3.7.13",
+                "@adobe/react-spectrum-ui": "1.2.1",
+                "@react-spectrum/icon": "^3.7.15",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@spectrum-icons/workflow": {
-            "version": "4.2.12",
-            "resolved": "https://registry.npmjs.org/@spectrum-icons/workflow/-/workflow-4.2.12.tgz",
-            "integrity": "sha512-xuyytdlM09DEZO7/vSp5z8Y2RYNXL4OOYSmOaWXeYgIa3iPNKz0HW+iVR2P+Ht0iBtKjPvRobbEFb0k280U4yQ==",
+            "version": "4.2.14",
+            "resolved": "https://registry.npmjs.org/@spectrum-icons/workflow/-/workflow-4.2.14.tgz",
+            "integrity": "sha512-wPz3T8sKJCM/o2sWLjHBL/tO2DmD+10zK/AjnbCoytyeMTxniUfMr7i4RM+E/H9uCUcswL9/QFX7kbgArj0A7Q==",
             "dependencies": {
-                "@adobe/react-spectrum-workflow": "2.3.4",
-                "@react-spectrum/icon": "^3.7.13",
+                "@adobe/react-spectrum-workflow": "2.3.5",
+                "@react-spectrum/icon": "^3.7.15",
                 "@swc/helpers": "^0.5.0"
             },
             "peerDependencies": {
                 "@react-spectrum/provider": "^3.0.0",
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/@swc/helpers": {
@@ -8835,9 +8839,9 @@
             "dev": true
         },
         "node_modules/@types/chai": {
-            "version": "4.3.16",
-            "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz",
-            "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==",
+            "version": "4.3.17",
+            "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.17.tgz",
+            "integrity": "sha512-zmZ21EWzR71B4Sscphjief5djsLre50M6lI622OSySTmn9DB3j+C3kWroHfBQWXbOBwbgg/M8CG/hUxDLIloow==",
             "dev": true
         },
         "node_modules/@types/color": {
@@ -9163,15 +9167,21 @@
                 "@types/ms": "*"
             }
         },
+        "node_modules/@types/dom-mediacapture-record": {
+            "version": "1.0.19",
+            "resolved": "https://registry.npmjs.org/@types/dom-mediacapture-record/-/dom-mediacapture-record-1.0.19.tgz",
+            "integrity": "sha512-Cz/85z3YTuUPnXrOp5MvSZZSgDkWTWvj1HgE7MWc5C8d/w/soJBXjnAoYDl4P5gmenDNNZkhXzNylGqxS1FzOw==",
+            "dev": true
+        },
         "node_modules/@types/dom-speech-recognition": {
             "version": "0.0.4",
             "resolved": "https://registry.npmjs.org/@types/dom-speech-recognition/-/dom-speech-recognition-0.0.4.tgz",
             "integrity": "sha512-zf2GwV/G6TdaLwpLDcGTIkHnXf8JEf/viMux+khqKQKDa8/8BAUtXXZS563GnvJ4Fg0PBLGAaFf2GekEVSZ6GQ=="
         },
         "node_modules/@types/eslint": {
-            "version": "8.56.10",
-            "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz",
-            "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==",
+            "version": "8.56.11",
+            "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.11.tgz",
+            "integrity": "sha512-sVBpJMf7UPo/wGecYOpk2aQya2VUGeHhe38WG7/mN5FufNSubf5VT9Uh9Uyp8/eLJpu1/tuhJ/qTo4mhSB4V4Q==",
             "dependencies": {
                 "@types/estree": "*",
                 "@types/json-schema": "*"
@@ -9253,9 +9263,9 @@
             "integrity": "sha512-IGKtSn0Lonfx3HdK6KMcfd5GUc1xdeLtjW1n7ZSA5Tmn1n2gj878q6IC0s4MbF9KtBpXIRqjRQxBzi2kF4WvGw=="
         },
         "node_modules/@types/fluent-ffmpeg": {
-            "version": "2.1.24",
-            "resolved": "https://registry.npmjs.org/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.24.tgz",
-            "integrity": "sha512-g5oQO8Jgi2kFS3tTub7wLvfLztr1s8tdXmRd8PiL/hLMLzTIAyMR2sANkTggM/rdEDAg3d63nYRRVepwBiCw5A==",
+            "version": "2.1.25",
+            "resolved": "https://registry.npmjs.org/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.25.tgz",
+            "integrity": "sha512-a9/Jtv/RVaCG4lUwWIcuClWE5eXJFoFS/oHOecOv/RS8n+lQdJzcJVmDlxA8Xbk4B82YpO88Dijcoljb6sYTcA==",
             "dependencies": {
                 "@types/node": "*"
             }
@@ -9333,9 +9343,9 @@
             "dev": true
         },
         "node_modules/@types/http-proxy": {
-            "version": "1.17.14",
-            "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz",
-            "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==",
+            "version": "1.17.15",
+            "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz",
+            "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==",
             "dev": true,
             "dependencies": {
                 "@types/node": "*"
@@ -9366,6 +9376,7 @@
             "version": "3.5.30",
             "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.30.tgz",
             "integrity": "sha512-nbWKkkyb919DOUxjmRVk8vwtDb0/k8FKncmUKFi+NY+QXqWltooxTrswvz4LspQwxvLdvzBN1TImr6cw3aQx2A==",
+            "dev": true,
             "dependencies": {
                 "@types/sizzle": "*"
             }
@@ -9423,9 +9434,9 @@
             }
         },
         "node_modules/@types/mapbox-gl": {
-            "version": "3.1.0",
-            "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-3.1.0.tgz",
-            "integrity": "sha512-hI6cQDjw1bkJw7MC/eHMqq5TWUamLwsujnUUeiIX2KDRjxRNSYMjnHz07+LATz9I9XIsKumOtUz4gRYnZOJ/FA==",
+            "version": "3.4.0",
+            "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-3.4.0.tgz",
+            "integrity": "sha512-tbn++Mm94H1kE7W6FF0oVC9rMXHVzDDNUbS7KfBMRF8NV/8csFi+67ytKcZJ4LsrpsJ+8MC6Os6ZinEDCsrunw==",
             "dependencies": {
                 "@types/geojson": "*"
             }
@@ -9462,9 +9473,9 @@
             "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
         },
         "node_modules/@types/node": {
-            "version": "20.14.11",
-            "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz",
-            "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==",
+            "version": "20.14.14",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz",
+            "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==",
             "dependencies": {
                 "undici-types": "~5.26.4"
             }
@@ -9789,7 +9800,8 @@
         "node_modules/@types/sizzle": {
             "version": "2.3.8",
             "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz",
-            "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg=="
+            "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==",
+            "dev": true
         },
         "node_modules/@types/sockjs": {
             "version": "0.3.36",
@@ -9825,10 +9837,17 @@
                 "@types/geojson": "*"
             }
         },
+        "node_modules/@types/textarea-caret": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/@types/textarea-caret/-/textarea-caret-3.0.3.tgz",
+            "integrity": "sha512-bsA9GdXV1wQsXyDjS5+A+czz8IAR3haH5DU+KctIoXbzobRL2NOiwF/+EbB7pofAyudMytLj4ihPtbmbJT8FWw==",
+            "dev": true
+        },
         "node_modules/@types/textfit": {
             "version": "2.4.4",
             "resolved": "https://registry.npmjs.org/@types/textfit/-/textfit-2.4.4.tgz",
             "integrity": "sha512-AYlNcJ5j/WspQfbHIhoF0Wo63F5+REnX/VPFSH5unUUuwRcr6IoXxZki3vYhG4DRVUQe51AsFYyRxml5u+qaAg==",
+            "dev": true,
             "dependencies": {
                 "@types/jquery": "*"
             }
@@ -9887,6 +9906,15 @@
                 "webpack": "^5"
             }
         },
+        "node_modules/@types/webscopeio__react-textarea-autocomplete": {
+            "version": "4.7.5",
+            "resolved": "https://registry.npmjs.org/@types/webscopeio__react-textarea-autocomplete/-/webscopeio__react-textarea-autocomplete-4.7.5.tgz",
+            "integrity": "sha512-B9YZ5KrKRcNNsh2v7tyc/tZ1rrPoyWoaXQvvfcG9pX85w9jy2HLnPPT7Kfms5TgzR3RGQ5TIvXQvmsizxdohyQ==",
+            "dev": true,
+            "dependencies": {
+                "@types/react": "*"
+            }
+        },
         "node_modules/@types/whatwg-url": {
             "version": "11.0.5",
             "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
@@ -9896,18 +9924,18 @@
             }
         },
         "node_modules/@types/ws": {
-            "version": "8.5.11",
-            "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.11.tgz",
-            "integrity": "sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w==",
+            "version": "8.5.12",
+            "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz",
+            "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==",
             "dev": true,
             "dependencies": {
                 "@types/node": "*"
             }
         },
         "node_modules/@types/yargs": {
-            "version": "17.0.32",
-            "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz",
-            "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==",
+            "version": "17.0.33",
+            "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
+            "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
             "dependencies": {
                 "@types/yargs-parser": "*"
             }
@@ -9924,16 +9952,16 @@
             "dev": true
         },
         "node_modules/@typescript-eslint/eslint-plugin": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz",
-            "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==",
+            "version": "7.18.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz",
+            "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==",
             "dev": true,
             "dependencies": {
                 "@eslint-community/regexpp": "^4.10.0",
-                "@typescript-eslint/scope-manager": "7.16.1",
-                "@typescript-eslint/type-utils": "7.16.1",
-                "@typescript-eslint/utils": "7.16.1",
-                "@typescript-eslint/visitor-keys": "7.16.1",
+                "@typescript-eslint/scope-manager": "7.18.0",
+                "@typescript-eslint/type-utils": "7.18.0",
+                "@typescript-eslint/utils": "7.18.0",
+                "@typescript-eslint/visitor-keys": "7.18.0",
                 "graphemer": "^1.4.0",
                 "ignore": "^5.3.1",
                 "natural-compare": "^1.4.0",
@@ -9957,14 +9985,14 @@
             }
         },
         "node_modules/@typescript-eslint/parser": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz",
-            "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==",
-            "dependencies": {
-                "@typescript-eslint/scope-manager": "7.16.1",
-                "@typescript-eslint/types": "7.16.1",
-                "@typescript-eslint/typescript-estree": "7.16.1",
-                "@typescript-eslint/visitor-keys": "7.16.1",
+            "version": "7.18.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz",
+            "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==",
+            "dependencies": {
+                "@typescript-eslint/scope-manager": "7.18.0",
+                "@typescript-eslint/types": "7.18.0",
+                "@typescript-eslint/typescript-estree": "7.18.0",
+                "@typescript-eslint/visitor-keys": "7.18.0",
                 "debug": "^4.3.4"
             },
             "engines": {
@@ -9984,12 +10012,12 @@
             }
         },
         "node_modules/@typescript-eslint/scope-manager": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz",
-            "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==",
+            "version": "7.18.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz",
+            "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==",
             "dependencies": {
-                "@typescript-eslint/types": "7.16.1",
-                "@typescript-eslint/visitor-keys": "7.16.1"
+                "@typescript-eslint/types": "7.18.0",
+                "@typescript-eslint/visitor-keys": "7.18.0"
             },
             "engines": {
                 "node": "^18.18.0 || >=20.0.0"
@@ -10000,13 +10028,13 @@
             }
         },
         "node_modules/@typescript-eslint/type-utils": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz",
-            "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==",
+            "version": "7.18.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz",
+            "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/typescript-estree": "7.16.1",
-                "@typescript-eslint/utils": "7.16.1",
+                "@typescript-eslint/typescript-estree": "7.18.0",
+                "@typescript-eslint/utils": "7.18.0",
                 "debug": "^4.3.4",
                 "ts-api-utils": "^1.3.0"
             },
@@ -10027,9 +10055,9 @@
             }
         },
         "node_modules/@typescript-eslint/types": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz",
-            "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==",
+            "version": "7.18.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz",
+            "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==",
             "engines": {
                 "node": "^18.18.0 || >=20.0.0"
             },
@@ -10039,12 +10067,12 @@
             }
         },
         "node_modules/@typescript-eslint/typescript-estree": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz",
-            "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==",
+            "version": "7.18.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz",
+            "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==",
             "dependencies": {
-                "@typescript-eslint/types": "7.16.1",
-                "@typescript-eslint/visitor-keys": "7.16.1",
+                "@typescript-eslint/types": "7.18.0",
+                "@typescript-eslint/visitor-keys": "7.18.0",
                 "debug": "^4.3.4",
                 "globby": "^11.1.0",
                 "is-glob": "^4.0.3",
@@ -10077,15 +10105,15 @@
             }
         },
         "node_modules/@typescript-eslint/utils": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz",
-            "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==",
+            "version": "7.18.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz",
+            "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==",
             "dev": true,
             "dependencies": {
                 "@eslint-community/eslint-utils": "^4.4.0",
-                "@typescript-eslint/scope-manager": "7.16.1",
-                "@typescript-eslint/types": "7.16.1",
-                "@typescript-eslint/typescript-estree": "7.16.1"
+                "@typescript-eslint/scope-manager": "7.18.0",
+                "@typescript-eslint/types": "7.18.0",
+                "@typescript-eslint/typescript-estree": "7.18.0"
             },
             "engines": {
                 "node": "^18.18.0 || >=20.0.0"
@@ -10099,11 +10127,11 @@
             }
         },
         "node_modules/@typescript-eslint/visitor-keys": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz",
-            "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==",
+            "version": "7.18.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz",
+            "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==",
             "dependencies": {
-                "@typescript-eslint/types": "7.16.1",
+                "@typescript-eslint/types": "7.18.0",
                 "eslint-visitor-keys": "^3.4.3"
             },
             "engines": {
@@ -10120,55 +10148,55 @@
             "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ=="
         },
         "node_modules/@vue/compiler-core": {
-            "version": "3.4.33",
-            "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.33.tgz",
-            "integrity": "sha512-MoIREbkdPQlnGfSKDMgzTqzqx5nmEjIc0ydLVYlTACGBsfvOJ4tHSbZXKVF536n6fB+0eZaGEOqsGThPpdvF5A==",
+            "version": "3.4.37",
+            "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.37.tgz",
+            "integrity": "sha512-ZDDT/KiLKuCRXyzWecNzC5vTcubGz4LECAtfGPENpo0nrmqJHwuWtRLxk/Sb9RAKtR9iFflFycbkjkY+W/PZUQ==",
             "dependencies": {
                 "@babel/parser": "^7.24.7",
-                "@vue/shared": "3.4.33",
-                "entities": "^4.5.0",
+                "@vue/shared": "3.4.37",
+                "entities": "^5.0.0",
                 "estree-walker": "^2.0.2",
                 "source-map-js": "^1.2.0"
             }
         },
         "node_modules/@vue/compiler-dom": {
-            "version": "3.4.33",
-            "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.33.tgz",
-            "integrity": "sha512-GzB8fxEHKw0gGet5BKlpfXEqoBnzSVWwMnT+dc25wE7pFEfrU/QsvjZMP9rD4iVXHBBoemTct8mN0GJEI6ZX5A==",
+            "version": "3.4.37",
+            "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.37.tgz",
+            "integrity": "sha512-rIiSmL3YrntvgYV84rekAtU/xfogMUJIclUMeIKEtVBFngOL3IeZHhsH3UaFEgB5iFGpj6IW+8YuM/2Up+vVag==",
             "dependencies": {
-                "@vue/compiler-core": "3.4.33",
-                "@vue/shared": "3.4.33"
+                "@vue/compiler-core": "3.4.37",
+                "@vue/shared": "3.4.37"
             }
         },
         "node_modules/@vue/compiler-sfc": {
-            "version": "3.4.33",
-            "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.33.tgz",
-            "integrity": "sha512-7rk7Vbkn21xMwIUpHQR4hCVejwE6nvhBOiDgoBcR03qvGqRKA7dCBSsHZhwhYUsmjlbJ7OtD5UFIyhP6BY+c8A==",
+            "version": "3.4.37",
+            "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.37.tgz",
+            "integrity": "sha512-vCfetdas40Wk9aK/WWf8XcVESffsbNkBQwS5t13Y/PcfqKfIwJX2gF+82th6dOpnpbptNMlMjAny80li7TaCIg==",
             "dependencies": {
                 "@babel/parser": "^7.24.7",
-                "@vue/compiler-core": "3.4.33",
-                "@vue/compiler-dom": "3.4.33",
-                "@vue/compiler-ssr": "3.4.33",
-                "@vue/shared": "3.4.33",
+                "@vue/compiler-core": "3.4.37",
+                "@vue/compiler-dom": "3.4.37",
+                "@vue/compiler-ssr": "3.4.37",
+                "@vue/shared": "3.4.37",
                 "estree-walker": "^2.0.2",
                 "magic-string": "^0.30.10",
-                "postcss": "^8.4.39",
+                "postcss": "^8.4.40",
                 "source-map-js": "^1.2.0"
             }
         },
         "node_modules/@vue/compiler-ssr": {
-            "version": "3.4.33",
-            "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.33.tgz",
-            "integrity": "sha512-0WveC9Ai+eT/1b6LCV5IfsufBZ0HP7pSSTdDjcuW302tTEgoBw8rHVHKPbGUtzGReUFCRXbv6zQDDgucnV2WzQ==",
+            "version": "3.4.37",
+            "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.37.tgz",
+            "integrity": "sha512-TyAgYBWrHlFrt4qpdACh8e9Ms6C/AZQ6A6xLJaWrCL8GCX5DxMzxyeFAEMfU/VFr4tylHm+a2NpfJpcd7+20XA==",
             "dependencies": {
-                "@vue/compiler-dom": "3.4.33",
-                "@vue/shared": "3.4.33"
+                "@vue/compiler-dom": "3.4.37",
+                "@vue/shared": "3.4.37"
             }
         },
         "node_modules/@vue/shared": {
-            "version": "3.4.33",
-            "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.33.tgz",
-            "integrity": "sha512-aoRY0jQk3A/cuvdkodTrM4NMfxco8n55eG4H7ML/CRy7OryHfiqvug4xrCBBMbbN+dvXAetDDwZW9DXWWjBntA=="
+            "version": "3.4.37",
+            "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.37.tgz",
+            "integrity": "sha512-nIh8P2fc3DflG8+5Uw8PT/1i17ccFn0xxN/5oE9RfV5SVnd7G0XEFRwakrnNFE/jlS95fpGXDVG5zDETS26nmg=="
         },
         "node_modules/@webassemblyjs/ast": {
             "version": "1.12.1",
@@ -10439,9 +10467,9 @@
             }
         },
         "node_modules/adm-zip": {
-            "version": "0.5.14",
-            "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.14.tgz",
-            "integrity": "sha512-DnyqqifT4Jrcvb8USYjp6FHtBpEIz1mnXu6pTRHZ0RL69LbQYiO+0lDFg5+OKA7U29oWSs3a/i8fhn8ZcceIWg==",
+            "version": "0.5.15",
+            "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.15.tgz",
+            "integrity": "sha512-jYPWSeOA8EFoZnucrKCNihqBjoEGQSU4HKgHYQgKNEQ0pQF9a/DYuo/+fAxY76k4qe75LUlLWpAM1QWcBMTOKw==",
             "engines": {
                 "node": ">=12.0"
             }
@@ -11049,23 +11077,23 @@
             }
         },
         "node_modules/aws4": {
-            "version": "1.13.0",
-            "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz",
-            "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g=="
+            "version": "1.13.1",
+            "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.1.tgz",
+            "integrity": "sha512-u5w79Rd7SU4JaIlA/zFqG+gOiuq25q5VLyZ8E+ijJeILuTxVzZgp2CaGw/UTw6pXYN9XMO9yiqj/nEHmhTG5CA=="
         },
         "node_modules/axe-core": {
-            "version": "4.9.1",
-            "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.9.1.tgz",
-            "integrity": "sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==",
+            "version": "4.10.0",
+            "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz",
+            "integrity": "sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==",
             "dev": true,
             "engines": {
                 "node": ">=4"
             }
         },
         "node_modules/axios": {
-            "version": "1.7.2",
-            "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
-            "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
+            "version": "1.7.3",
+            "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz",
+            "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==",
             "dependencies": {
                 "follow-redirects": "^1.15.6",
                 "form-data": "^4.0.0",
@@ -11203,12 +11231,12 @@
             }
         },
         "node_modules/babel-plugin-polyfill-corejs3": {
-            "version": "0.10.4",
-            "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz",
-            "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==",
+            "version": "0.10.6",
+            "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz",
+            "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==",
             "dependencies": {
-                "@babel/helper-define-polyfill-provider": "^0.6.1",
-                "core-js-compat": "^3.36.1"
+                "@babel/helper-define-polyfill-provider": "^0.6.2",
+                "core-js-compat": "^3.38.0"
             },
             "peerDependencies": {
                 "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
@@ -14655,9 +14683,9 @@
             "dev": true
         },
         "node_modules/browserslist": {
-            "version": "4.23.2",
-            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz",
-            "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==",
+            "version": "4.23.3",
+            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz",
+            "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==",
             "funding": [
                 {
                     "type": "opencollective",
@@ -14673,9 +14701,9 @@
                 }
             ],
             "dependencies": {
-                "caniuse-lite": "^1.0.30001640",
-                "electron-to-chromium": "^1.4.820",
-                "node-releases": "^2.0.14",
+                "caniuse-lite": "^1.0.30001646",
+                "electron-to-chromium": "^1.5.4",
+                "node-releases": "^2.0.18",
                 "update-browserslist-db": "^1.1.0"
             },
             "bin": {
@@ -14823,32 +14851,6 @@
                 "node": ">=18"
             }
         },
-        "node_modules/cacheable-request/node_modules/get-stream": {
-            "version": "9.0.1",
-            "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz",
-            "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==",
-            "dependencies": {
-                "@sec-ant/readable-stream": "^0.4.1",
-                "is-stream": "^4.0.1"
-            },
-            "engines": {
-                "node": ">=18"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
-            }
-        },
-        "node_modules/cacheable-request/node_modules/is-stream": {
-            "version": "4.0.1",
-            "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz",
-            "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==",
-            "engines": {
-                "node": ">=18"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
-            }
-        },
         "node_modules/call-bind": {
             "version": "1.0.7",
             "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
@@ -14912,9 +14914,9 @@
             }
         },
         "node_modules/caniuse-lite": {
-            "version": "1.0.30001643",
-            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz",
-            "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==",
+            "version": "1.0.30001651",
+            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz",
+            "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==",
             "funding": [
                 {
                     "type": "opencollective",
@@ -15750,9 +15752,9 @@
             }
         },
         "node_modules/core-js": {
-            "version": "3.37.1",
-            "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz",
-            "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==",
+            "version": "3.38.0",
+            "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.0.tgz",
+            "integrity": "sha512-XPpwqEodRljce9KswjZShh95qJ1URisBeKCjUdq27YdenkslVe7OO0ZJhlYXAChW7OhXaRLl8AAba7IBfoIHug==",
             "hasInstallScript": true,
             "funding": {
                 "type": "opencollective",
@@ -15760,11 +15762,11 @@
             }
         },
         "node_modules/core-js-compat": {
-            "version": "3.37.1",
-            "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz",
-            "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==",
+            "version": "3.38.0",
+            "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.0.tgz",
+            "integrity": "sha512-75LAicdLa4OJVwFxFbQR3NdnZjNgX6ILpVcVzcC4T2smerB5lELMrJQQQoWV6TiuC/vlaFqgU2tKQx9w5s0e0A==",
             "dependencies": {
-                "browserslist": "^4.23.0"
+                "browserslist": "^4.23.3"
             },
             "funding": {
                 "type": "opencollective",
@@ -15772,9 +15774,9 @@
             }
         },
         "node_modules/core-js-pure": {
-            "version": "3.37.1",
-            "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.37.1.tgz",
-            "integrity": "sha512-J/r5JTHSmzTxbiYYrzXg9w1VpqrYt+gexenBE9pugeyhwPZTAEJddyiReJWsLO6uNQ8xJZFbod6XC7KKwatCiA==",
+            "version": "3.38.0",
+            "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.38.0.tgz",
+            "integrity": "sha512-8balb/HAXo06aHP58mZMtXgD8vcnXz9tUDePgqBgJgKdmTlMt+jw3ujqniuBDQXMvTzxnMpxHFeuSM3g1jWQuQ==",
             "hasInstallScript": true,
             "funding": {
                 "type": "opencollective",
@@ -16080,9 +16082,9 @@
             }
         },
         "node_modules/csv-stringify": {
-            "version": "6.5.0",
-            "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.5.0.tgz",
-            "integrity": "sha512-edlXFVKcUx7r8Vx5zQucsuMg4wb/xT6qyz+Sr1vnLrdXqlLD1+UKyWNyZ9zn6mUW1ewmGxrpVwAcChGF0HQ/2Q=="
+            "version": "6.5.1",
+            "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.5.1.tgz",
+            "integrity": "sha512-+9lpZfwpLntpTIEpFbwQyWuW/hmI/eHuJZD1XzeZpfZTqkf1fyvBbBLXTJJMsBuuS11uTShMqPwzx4A6ffXgRQ=="
         },
         "node_modules/csvtojson": {
             "version": "2.0.10",
@@ -16106,9 +16108,9 @@
             "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg=="
         },
         "node_modules/cytoscape": {
-            "version": "3.30.1",
-            "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.1.tgz",
-            "integrity": "sha512-TRJc3HbBPkHd50u9YfJh2FxD1lDLZ+JXnJoyBn5LkncoeuT7fapO/Hq/Ed8TdFclaKshzInge2i30bg7VKeoPQ==",
+            "version": "3.30.2",
+            "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.2.tgz",
+            "integrity": "sha512-oICxQsjW8uSaRmn4UK/jkczKOqTrVqt5/1WL0POiJUT2EKNc9STM4hYFHv917yu55aTBMFNRzymlJhVAiWPCxw==",
             "engines": {
                 "node": ">=0.10"
             }
@@ -16677,9 +16679,9 @@
             "integrity": "sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg=="
         },
         "node_modules/debug": {
-            "version": "4.3.5",
-            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
-            "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+            "version": "4.3.6",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+            "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
             "dependencies": {
                 "ms": "2.1.2"
             },
@@ -17143,6 +17145,17 @@
                 "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
             }
         },
+        "node_modules/dom-serializer/node_modules/entities": {
+            "version": "4.5.0",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+            "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+            "engines": {
+                "node": ">=0.12"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/entities?sponsor=1"
+            }
+        },
         "node_modules/dom-walk": {
             "version": "0.1.2",
             "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
@@ -17258,9 +17271,9 @@
             "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
         },
         "node_modules/electron-to-chromium": {
-            "version": "1.4.832",
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.832.tgz",
-            "integrity": "sha512-cTen3SB0H2SGU7x467NRe1eVcQgcuS6jckKfWJHia2eo0cHIGOqHoAxevIYZD4eRHcWjkvFzo93bi3vJ9W+1lA=="
+            "version": "1.5.5",
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.5.tgz",
+            "integrity": "sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA=="
         },
         "node_modules/elkjs": {
             "version": "0.9.3",
@@ -17369,9 +17382,9 @@
             }
         },
         "node_modules/enhanced-resolve": {
-            "version": "5.17.0",
-            "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz",
-            "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==",
+            "version": "5.17.1",
+            "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
+            "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
             "dependencies": {
                 "graceful-fs": "^4.2.4",
                 "tapable": "^2.2.0"
@@ -17381,9 +17394,9 @@
             }
         },
         "node_modules/entities": {
-            "version": "4.5.0",
-            "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
-            "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-5.0.0.tgz",
+            "integrity": "sha512-BeJFvFRJddxobhvEdm5GqHzRV/X+ACeuw0/BuuxsCh1EUZcAIz8+kYmBp/LrQuloy6K1f3a0M7+IhmZ7QnkISA==",
             "engines": {
                 "node": ">=0.12"
             },
@@ -19634,9 +19647,9 @@
             "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw=="
         },
         "node_modules/fast-xml-parser": {
-            "version": "4.4.0",
-            "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.0.tgz",
-            "integrity": "sha512-kLY3jFlwIYwBNDojclKsNAC12sfD6NwW74QB2CoNGPvtVxjliYehVunB3HYyNi+n4Tt1dAcgwYvmKF/Z18flqg==",
+            "version": "4.4.1",
+            "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz",
+            "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==",
             "funding": [
                 {
                     "type": "github",
@@ -20082,9 +20095,9 @@
             }
         },
         "node_modules/foreground-child": {
-            "version": "3.2.1",
-            "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz",
-            "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==",
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
+            "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
             "dependencies": {
                 "cross-spawn": "^7.0.0",
                 "signal-exit": "^4.0.1"
@@ -20699,11 +20712,26 @@
             }
         },
         "node_modules/get-stream": {
-            "version": "8.0.1",
-            "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
-            "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
+            "version": "9.0.1",
+            "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz",
+            "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==",
+            "dependencies": {
+                "@sec-ant/readable-stream": "^0.4.1",
+                "is-stream": "^4.0.1"
+            },
             "engines": {
-                "node": ">=16"
+                "node": ">=18"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/get-stream/node_modules/is-stream": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz",
+            "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==",
+            "engines": {
+                "node": ">=18"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
@@ -20852,9 +20880,9 @@
             }
         },
         "node_modules/globals": {
-            "version": "15.8.0",
-            "resolved": "https://registry.npmjs.org/globals/-/globals-15.8.0.tgz",
-            "integrity": "sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==",
+            "version": "15.9.0",
+            "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz",
+            "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==",
             "dev": true,
             "engines": {
                 "node": ">=18"
@@ -20904,9 +20932,9 @@
             "integrity": "sha512-sIVQCiRWOymHbVD1Aw/T9/ijbPYAVGBlgGYd1N9MRKfcyBNSpjr87Vg9nSHm+RCT8ELrvK8IJYJV0QRJuVUkCQ=="
         },
         "node_modules/google-auth-library": {
-            "version": "9.11.0",
-            "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.11.0.tgz",
-            "integrity": "sha512-epX3ww/mNnhl6tL45EQ/oixsY8JLEgUFoT4A5E/5iAR4esld9Kqv6IJGk7EmGuOgDvaarwF95hU2+v7Irql9lw==",
+            "version": "9.13.0",
+            "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.13.0.tgz",
+            "integrity": "sha512-p9Y03Uzp/Igcs36zAaB0XTSwZ8Y0/tpYiz5KIde5By+H9DCVUSYtDWZu6aFXsWTqENMb8BD/pDT3hR8NVrPkfA==",
             "dependencies": {
                 "base64-js": "^1.3.0",
                 "ecdsa-sig-formatter": "^1.0.11",
@@ -20996,17 +21024,16 @@
             }
         },
         "node_modules/got": {
-            "version": "14.4.1",
-            "resolved": "https://registry.npmjs.org/got/-/got-14.4.1.tgz",
-            "integrity": "sha512-IvDJbJBUeexX74xNQuMIVgCRRuNOm5wuK+OC3Dc2pnSoh1AOmgc7JVj7WC+cJ4u0aPcO9KZ2frTXcqK4W/5qTQ==",
+            "version": "14.4.2",
+            "resolved": "https://registry.npmjs.org/got/-/got-14.4.2.tgz",
+            "integrity": "sha512-+Te/qEZ6hr7i+f0FNgXx/6WQteSM/QqueGvxeYQQFm0GDfoxLVJ/oiwUKYMTeioColWUTdewZ06hmrBjw6F7tw==",
             "dependencies": {
-                "@sindresorhus/is": "^6.3.1",
+                "@sindresorhus/is": "^7.0.0",
                 "@szmarczak/http-timer": "^5.0.1",
                 "cacheable-lookup": "^7.0.0",
                 "cacheable-request": "^12.0.1",
                 "decompress-response": "^6.0.0",
                 "form-data-encoder": "^4.0.2",
-                "get-stream": "^8.0.1",
                 "http2-wrapper": "^2.2.1",
                 "lowercase-keys": "^3.0.0",
                 "p-cancelable": "^4.0.1",
@@ -21609,6 +21636,17 @@
                 "entities": "^4.4.0"
             }
         },
+        "node_modules/htmlparser2/node_modules/entities": {
+            "version": "4.5.0",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+            "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+            "engines": {
+                "node": ">=0.12"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/entities?sponsor=1"
+            }
+        },
         "node_modules/http-browserify": {
             "version": "1.7.0",
             "resolved": "https://registry.npmjs.org/http-browserify/-/http-browserify-1.7.0.tgz",
@@ -23763,9 +23801,9 @@
             }
         },
         "node_modules/launch-editor": {
-            "version": "2.8.0",
-            "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz",
-            "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==",
+            "version": "2.8.1",
+            "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.1.tgz",
+            "integrity": "sha512-elBx2l/tp9z99X5H/qev8uyDywVh0VXAwEbjk8kJhnc5grOFkGh7aW6q55me9xnYbss261XtnUrysZ+XvGbhQA==",
             "dev": true,
             "dependencies": {
                 "picocolors": "^1.0.0",
@@ -24094,11 +24132,11 @@
             }
         },
         "node_modules/magic-string": {
-            "version": "0.30.10",
-            "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
-            "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
+            "version": "0.30.11",
+            "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz",
+            "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==",
             "dependencies": {
-                "@jridgewell/sourcemap-codec": "^1.4.15"
+                "@jridgewell/sourcemap-codec": "^1.5.0"
             }
         },
         "node_modules/magicli": {
@@ -24264,6 +24302,17 @@
             "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
             "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
         },
+        "node_modules/markdown-it/node_modules/entities": {
+            "version": "4.5.0",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+            "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+            "engines": {
+                "node": ">=0.12"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/entities?sponsor=1"
+            }
+        },
         "node_modules/markdown-table": {
             "version": "3.0.3",
             "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz",
@@ -31094,9 +31143,9 @@
             }
         },
         "node_modules/mongoose": {
-            "version": "8.5.1",
-            "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.1.tgz",
-            "integrity": "sha512-OhVcwVl91A1G6+XpjDcpkGP7l7ikZkxa0DylX7NT/lcEqAjggzSdqDxb48A+xsDxqNAr0ntSJ1yiE3+KJTOd5Q==",
+            "version": "8.5.2",
+            "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.2.tgz",
+            "integrity": "sha512-GZB4rHMdYfGatV+23IpCrqFbyCOjCNOHXgWbirr92KRwTEncBrtW3kgU9vmpKjsGf7nMmnAy06SwWUv1vhDkSg==",
             "dependencies": {
                 "bson": "^6.7.0",
                 "kareem": "2.6.3",
@@ -34216,9 +34265,9 @@
             }
         },
         "node_modules/openai": {
-            "version": "4.52.7",
-            "resolved": "https://registry.npmjs.org/openai/-/openai-4.52.7.tgz",
-            "integrity": "sha512-dgxA6UZHary6NXUHEDj5TWt8ogv0+ibH+b4pT5RrWMjiRZVylNwLcw/2ubDrX5n0oUmHX/ZgudMJeemxzOvz7A==",
+            "version": "4.55.1",
+            "resolved": "https://registry.npmjs.org/openai/-/openai-4.55.1.tgz",
+            "integrity": "sha512-FziYJcWl+SAGbt5AcRIzVzNcnKohpEMQdtzVOmHFbBp/if7x2+ACqgxF2XUbyi2PcKONPcVpmtG5h9qoDAEXwQ==",
             "dependencies": {
                 "@types/node": "^18.11.18",
                 "@types/node-fetch": "^2.6.4",
@@ -34226,17 +34275,24 @@
                 "agentkeepalive": "^4.2.1",
                 "form-data-encoder": "1.7.2",
                 "formdata-node": "^4.3.2",
-                "node-fetch": "^2.6.7",
-                "web-streams-polyfill": "^3.2.1"
+                "node-fetch": "^2.6.7"
             },
             "bin": {
                 "openai": "bin/cli"
+            },
+            "peerDependencies": {
+                "zod": "^3.23.8"
+            },
+            "peerDependenciesMeta": {
+                "zod": {
+                    "optional": true
+                }
             }
         },
         "node_modules/openai/node_modules/@types/node": {
-            "version": "18.19.41",
-            "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.41.tgz",
-            "integrity": "sha512-LX84pRJ+evD2e2nrgYCHObGWkiQJ1mL+meAgbvnwk/US6vmMY7S2ygBTGV2Jw91s9vUsLSXeDEkUHZIJGLrhsg==",
+            "version": "18.19.43",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.43.tgz",
+            "integrity": "sha512-Mw/YlgXnyJdEwLoFv2dpuJaDFriX+Pc+0qOBJ57jC1H6cDxIj2xc5yUrdtArDVG0m+KV6622a4p2tenEqB3C/g==",
             "dependencies": {
                 "undici-types": "~5.26.4"
             }
@@ -34486,6 +34542,17 @@
                 "url": "https://github.com/inikulin/parse5?sponsor=1"
             }
         },
+        "node_modules/parse5/node_modules/entities": {
+            "version": "4.5.0",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+            "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+            "engines": {
+                "node": ">=0.12"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/entities?sponsor=1"
+            }
+        },
         "node_modules/parseley": {
             "version": "0.12.1",
             "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz",
@@ -34720,15 +34787,15 @@
             }
         },
         "node_modules/pdfjs-dist": {
-            "version": "4.4.168",
-            "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.4.168.tgz",
-            "integrity": "sha512-MbkAjpwka/dMHaCfQ75RY1FXX3IewBVu6NGZOcxerRFlaBiIkZmUoR0jotX5VUzYZEXAGzSFtknWs5xRKliXPA==",
+            "version": "4.5.136",
+            "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.5.136.tgz",
+            "integrity": "sha512-V1BALcAN/FmxBEShLxoP73PlQZAZtzlaNfRbRhJrKvXzjLC5VaIlBAQUJuWP8iaYUmIdmdLHmt3E2TBglxOm3w==",
             "engines": {
                 "node": ">=18"
             },
             "optionalDependencies": {
                 "canvas": "^2.11.2",
-                "path2d": "^0.2.0"
+                "path2d": "^0.2.1"
             }
         },
         "node_modules/pdfjs/node_modules/pako": {
@@ -34961,9 +35028,9 @@
             }
         },
         "node_modules/postcss": {
-            "version": "8.4.39",
-            "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz",
-            "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==",
+            "version": "8.4.41",
+            "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
+            "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
             "funding": [
                 {
                     "type": "opencollective",
@@ -35189,9 +35256,9 @@
             "peer": true
         },
         "node_modules/prosemirror-commands": {
-            "version": "1.5.2",
-            "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.5.2.tgz",
-            "integrity": "sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==",
+            "version": "1.6.0",
+            "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.6.0.tgz",
+            "integrity": "sha512-xn1U/g36OqXn2tn5nGmvnnimAj/g1pUx2ypJJIe8WkVX83WyJVC5LTARaxZa2AtQRwntu9Jc5zXs9gL9svp/mg==",
             "dependencies": {
                 "prosemirror-model": "^1.0.0",
                 "prosemirror-state": "^1.0.0",
@@ -35236,9 +35303,9 @@
             }
         },
         "node_modules/prosemirror-model": {
-            "version": "1.22.2",
-            "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.22.2.tgz",
-            "integrity": "sha512-I4lS7HHIW47D0Xv/gWmi4iUWcQIDYaJKd8Hk4+lcSps+553FlQrhmxtItpEvTr75iAruhzVShVp6WUwsT6Boww==",
+            "version": "1.22.3",
+            "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.22.3.tgz",
+            "integrity": "sha512-V4XCysitErI+i0rKFILGt/xClnFJaohe/wrrlT2NSZ+zk8ggQfDH4x2wNK7Gm0Hp4CIoWizvXFP7L9KMaCuI0Q==",
             "dependencies": {
                 "orderedmap": "^2.0.0"
             }
@@ -35669,85 +35736,90 @@
             }
         },
         "node_modules/react-aria": {
-            "version": "3.33.1",
-            "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.33.1.tgz",
-            "integrity": "sha512-hFC3K/UA+90Krlx2IgRTgzFbC6FSPi4pUwHT+STperPLK+cTEHkI+3Lu0YYwQSBatkgxnIv9+GtFuVbps2kROw==",
+            "version": "3.34.1",
+            "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.34.1.tgz",
+            "integrity": "sha512-vA4BP+SWjFFRfOTQcNJtIp9gKlxuC7kPUXQK9fuNA+2K4mJdIc9mBnmwXQiLl/eAthMf43fD4fETfY9SiCm1Zg==",
             "dependencies": {
                 "@internationalized/string": "^3.2.3",
-                "@react-aria/breadcrumbs": "^3.5.13",
-                "@react-aria/button": "^3.9.5",
-                "@react-aria/calendar": "^3.5.8",
-                "@react-aria/checkbox": "^3.14.3",
-                "@react-aria/combobox": "^3.9.1",
-                "@react-aria/datepicker": "^3.10.1",
-                "@react-aria/dialog": "^3.5.14",
-                "@react-aria/dnd": "^3.6.1",
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/gridlist": "^3.8.1",
-                "@react-aria/i18n": "^3.11.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/label": "^3.7.8",
-                "@react-aria/link": "^3.7.1",
-                "@react-aria/listbox": "^3.12.1",
-                "@react-aria/menu": "^3.14.1",
-                "@react-aria/meter": "^3.4.13",
-                "@react-aria/numberfield": "^3.11.3",
-                "@react-aria/overlays": "^3.22.1",
-                "@react-aria/progress": "^3.4.13",
-                "@react-aria/radio": "^3.10.4",
-                "@react-aria/searchfield": "^3.7.5",
-                "@react-aria/select": "^3.14.5",
-                "@react-aria/selection": "^3.18.1",
-                "@react-aria/separator": "^3.3.13",
-                "@react-aria/slider": "^3.7.8",
-                "@react-aria/ssr": "^3.9.4",
-                "@react-aria/switch": "^3.6.4",
-                "@react-aria/table": "^3.14.1",
-                "@react-aria/tabs": "^3.9.1",
-                "@react-aria/tag": "^3.4.1",
-                "@react-aria/textfield": "^3.14.5",
-                "@react-aria/tooltip": "^3.7.4",
-                "@react-aria/utils": "^3.24.1",
-                "@react-aria/visually-hidden": "^3.8.12",
-                "@react-types/shared": "^3.23.1"
-            },
-            "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "@react-aria/breadcrumbs": "^3.5.15",
+                "@react-aria/button": "^3.9.7",
+                "@react-aria/calendar": "^3.5.10",
+                "@react-aria/checkbox": "^3.14.5",
+                "@react-aria/combobox": "^3.10.1",
+                "@react-aria/datepicker": "^3.11.1",
+                "@react-aria/dialog": "^3.5.16",
+                "@react-aria/dnd": "^3.7.1",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/gridlist": "^3.9.1",
+                "@react-aria/i18n": "^3.12.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/label": "^3.7.10",
+                "@react-aria/link": "^3.7.3",
+                "@react-aria/listbox": "^3.13.1",
+                "@react-aria/menu": "^3.15.1",
+                "@react-aria/meter": "^3.4.15",
+                "@react-aria/numberfield": "^3.11.5",
+                "@react-aria/overlays": "^3.23.1",
+                "@react-aria/progress": "^3.4.15",
+                "@react-aria/radio": "^3.10.6",
+                "@react-aria/searchfield": "^3.7.7",
+                "@react-aria/select": "^3.14.7",
+                "@react-aria/selection": "^3.19.1",
+                "@react-aria/separator": "^3.4.1",
+                "@react-aria/slider": "^3.7.10",
+                "@react-aria/ssr": "^3.9.5",
+                "@react-aria/switch": "^3.6.6",
+                "@react-aria/table": "^3.15.1",
+                "@react-aria/tabs": "^3.9.3",
+                "@react-aria/tag": "^3.4.3",
+                "@react-aria/textfield": "^3.14.7",
+                "@react-aria/tooltip": "^3.7.6",
+                "@react-aria/utils": "^3.25.1",
+                "@react-aria/visually-hidden": "^3.8.14",
+                "@react-types/shared": "^3.24.1"
+            },
+            "peerDependencies": {
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/react-aria-components": {
-            "version": "1.2.1",
-            "resolved": "https://registry.npmjs.org/react-aria-components/-/react-aria-components-1.2.1.tgz",
-            "integrity": "sha512-iGIdDjbTyLLn0/tGUyBQxxu+E1bw4/H4AU89d0cRcu8yIdw6MXG29YElmRHn0ugiyrERrk/YQALihstnns5kRQ==",
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/react-aria-components/-/react-aria-components-1.3.1.tgz",
+            "integrity": "sha512-yUTA8uHbioQHU5d7iNvSLZLEfQlcTAmyhhkY+NMc8pIGPdtf0qnrlF0nPtJq8Mro5irpVrgUlqKBvvCiKwFNiQ==",
             "dependencies": {
-                "@internationalized/date": "^3.5.4",
+                "@internationalized/date": "^3.5.5",
                 "@internationalized/string": "^3.2.3",
-                "@react-aria/color": "3.0.0-beta.33",
-                "@react-aria/focus": "^3.17.1",
-                "@react-aria/interactions": "^3.21.3",
-                "@react-aria/menu": "^3.14.1",
-                "@react-aria/toolbar": "3.0.0-beta.5",
-                "@react-aria/tree": "3.0.0-alpha.1",
-                "@react-aria/utils": "^3.24.1",
-                "@react-stately/color": "^3.6.1",
-                "@react-stately/menu": "^3.7.1",
-                "@react-stately/table": "^3.11.8",
-                "@react-stately/utils": "^3.10.1",
-                "@react-types/color": "3.0.0-beta.25",
-                "@react-types/form": "^3.7.4",
-                "@react-types/grid": "^3.2.6",
-                "@react-types/shared": "^3.23.1",
-                "@react-types/table": "^3.9.5",
+                "@react-aria/collections": "3.0.0-alpha.3",
+                "@react-aria/color": "3.0.0-rc.1",
+                "@react-aria/dnd": "^3.7.1",
+                "@react-aria/focus": "^3.18.1",
+                "@react-aria/interactions": "^3.22.1",
+                "@react-aria/menu": "^3.15.1",
+                "@react-aria/toolbar": "3.0.0-beta.7",
+                "@react-aria/tree": "3.0.0-alpha.3",
+                "@react-aria/utils": "^3.25.1",
+                "@react-aria/virtualizer": "^4.0.1",
+                "@react-stately/color": "^3.7.1",
+                "@react-stately/layout": "^4.0.1",
+                "@react-stately/menu": "^3.8.1",
+                "@react-stately/table": "^3.12.1",
+                "@react-stately/utils": "^3.10.2",
+                "@react-stately/virtualizer": "^4.0.1",
+                "@react-types/color": "3.0.0-rc.1",
+                "@react-types/form": "^3.7.6",
+                "@react-types/grid": "^3.2.8",
+                "@react-types/shared": "^3.24.1",
+                "@react-types/table": "^3.10.1",
                 "@swc/helpers": "^0.5.0",
                 "client-only": "^0.0.1",
-                "react-aria": "^3.33.1",
-                "react-stately": "^3.31.1",
+                "react-aria": "^3.34.1",
+                "react-stately": "^3.32.1",
                 "use-sync-external-store": "^1.2.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
-                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0",
+                "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/react-autosuggest": {
@@ -35766,9 +35838,9 @@
             }
         },
         "node_modules/react-awesome-reveal": {
-            "version": "4.2.12",
-            "resolved": "https://registry.npmjs.org/react-awesome-reveal/-/react-awesome-reveal-4.2.12.tgz",
-            "integrity": "sha512-cablqrGypakw34h+rMcn+CmDCMfS+n4MznL/0LBQpFksZ2FCRtKFWIYuKWWpY8lL2ttyBnWnMdlJJiuLHR99uA==",
+            "version": "4.2.14",
+            "resolved": "https://registry.npmjs.org/react-awesome-reveal/-/react-awesome-reveal-4.2.14.tgz",
+            "integrity": "sha512-wknbDl+z5MIhQFfKKSj3iBJzvssqJLP8LbxQjW9OCyXPGtMSYvOFKwjG4/2p1de+qh5gqb8WBMQIYS6wVN3tNw==",
             "funding": [
                 {
                     "type": "github",
@@ -35780,7 +35852,7 @@
                 }
             ],
             "dependencies": {
-                "react-intersection-observer": "^9.10.3",
+                "react-intersection-observer": "^9.13.0",
                 "react-is": "^18.3.1"
             },
             "peerDependencies": {
@@ -36100,36 +36172,36 @@
             }
         },
         "node_modules/react-stately": {
-            "version": "3.31.1",
-            "resolved": "https://registry.npmjs.org/react-stately/-/react-stately-3.31.1.tgz",
-            "integrity": "sha512-wuq673NHkYSdoceGryjtMJJvB9iQgyDkQDsnTN0t2v91pXjGDsN/EcOvnUrxXSBtY9eLdIw74R54z9GX5cJNEg==",
-            "dependencies": {
-                "@react-stately/calendar": "^3.5.1",
-                "@react-stately/checkbox": "^3.6.5",
-                "@react-stately/collections": "^3.10.7",
-                "@react-stately/combobox": "^3.8.4",
-                "@react-stately/data": "^3.11.4",
-                "@react-stately/datepicker": "^3.9.4",
-                "@react-stately/dnd": "^3.3.1",
-                "@react-stately/form": "^3.0.3",
-                "@react-stately/list": "^3.10.5",
-                "@react-stately/menu": "^3.7.1",
-                "@react-stately/numberfield": "^3.9.3",
-                "@react-stately/overlays": "^3.6.7",
-                "@react-stately/radio": "^3.10.4",
-                "@react-stately/searchfield": "^3.5.3",
-                "@react-stately/select": "^3.6.4",
-                "@react-stately/selection": "^3.15.1",
-                "@react-stately/slider": "^3.5.4",
-                "@react-stately/table": "^3.11.8",
-                "@react-stately/tabs": "^3.6.6",
-                "@react-stately/toggle": "^3.7.4",
-                "@react-stately/tooltip": "^3.4.9",
-                "@react-stately/tree": "^3.8.1",
-                "@react-types/shared": "^3.23.1"
-            },
-            "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+            "version": "3.32.1",
+            "resolved": "https://registry.npmjs.org/react-stately/-/react-stately-3.32.1.tgz",
+            "integrity": "sha512-znw+bqHJk1fvv34O3HoVH61otyYJomRu1gI7A4B3UHCnSFS6E6nMI6D3nRv9RrAWhf4ekLLg35FwDTHDcG1zdg==",
+            "dependencies": {
+                "@react-stately/calendar": "^3.5.3",
+                "@react-stately/checkbox": "^3.6.7",
+                "@react-stately/collections": "^3.10.9",
+                "@react-stately/combobox": "^3.9.1",
+                "@react-stately/data": "^3.11.6",
+                "@react-stately/datepicker": "^3.10.1",
+                "@react-stately/dnd": "^3.4.1",
+                "@react-stately/form": "^3.0.5",
+                "@react-stately/list": "^3.10.7",
+                "@react-stately/menu": "^3.8.1",
+                "@react-stately/numberfield": "^3.9.5",
+                "@react-stately/overlays": "^3.6.9",
+                "@react-stately/radio": "^3.10.6",
+                "@react-stately/searchfield": "^3.5.5",
+                "@react-stately/select": "^3.6.6",
+                "@react-stately/selection": "^3.16.1",
+                "@react-stately/slider": "^3.5.6",
+                "@react-stately/table": "^3.12.1",
+                "@react-stately/tabs": "^3.6.8",
+                "@react-stately/toggle": "^3.7.6",
+                "@react-stately/tooltip": "^3.4.11",
+                "@react-stately/tree": "^3.8.3",
+                "@react-types/shared": "^3.24.1"
+            },
+            "peerDependencies": {
+                "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
             }
         },
         "node_modules/react-textarea-autosize": {
@@ -39388,9 +39460,9 @@
             "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
         },
         "node_modules/terser": {
-            "version": "5.31.3",
-            "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.3.tgz",
-            "integrity": "sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==",
+            "version": "5.31.5",
+            "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.5.tgz",
+            "integrity": "sha512-YPmas0L0rE1UyLL/llTWA0SiDOqIcAQYLeUj7cJYzXHlRTAnMSg9pPe4VJ5PlKvTrPQsdVFuiRiwyeNlYgwh2Q==",
             "dependencies": {
                 "@jridgewell/source-map": "^0.3.3",
                 "acorn": "^8.8.2",
@@ -40383,9 +40455,9 @@
             }
         },
         "node_modules/type-fest": {
-            "version": "4.23.0",
-            "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.23.0.tgz",
-            "integrity": "sha512-ZiBujro2ohr5+Z/hZWHESLz3g08BBdrdLMieYFULJO+tWc437sn8kQsWLJoZErY8alNhxre9K4p3GURAG11n+w==",
+            "version": "4.24.0",
+            "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.24.0.tgz",
+            "integrity": "sha512-spAaHzc6qre0TlZQQ2aA/nGMe+2Z/wyGk5Z+Ru2VUfdNwT6kWO6TjevOlpebsATEG1EIQ2sOiDszud3lO5mt/Q==",
             "engines": {
                 "node": ">=16"
             },
@@ -40479,9 +40551,9 @@
             }
         },
         "node_modules/typescript": {
-            "version": "5.5.3",
-            "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz",
-            "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==",
+            "version": "5.5.4",
+            "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
+            "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
             "bin": {
                 "tsc": "bin/tsc",
                 "tsserver": "bin/tsserver"
@@ -40496,14 +40568,14 @@
             "integrity": "sha512-7sI4e/bZijOzyURng88oOFZCISQPTHozfE2sUu5AviFYk5QV7fYGb6YiDl+vKjF/pICA354JImBImL9XJWUvdQ=="
         },
         "node_modules/typescript-eslint": {
-            "version": "7.16.1",
-            "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.16.1.tgz",
-            "integrity": "sha512-889oE5qELj65q/tGeOSvlreNKhimitFwZqQ0o7PcWC7/lgRkAMknznsCsV8J8mZGTP/Z+cIbX8accf2DE33hrA==",
+            "version": "7.18.0",
+            "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.18.0.tgz",
+            "integrity": "sha512-PonBkP603E3tt05lDkbOMyaxJjvKqQrXsnow72sVeOFINDE/qNmnnd+f9b4N+U7W6MXnnYyrhtmF2t08QWwUbA==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/eslint-plugin": "7.16.1",
-                "@typescript-eslint/parser": "7.16.1",
-                "@typescript-eslint/utils": "7.16.1"
+                "@typescript-eslint/eslint-plugin": "7.18.0",
+                "@typescript-eslint/parser": "7.18.0",
+                "@typescript-eslint/utils": "7.18.0"
             },
             "engines": {
                 "node": "^18.18.0 || >=20.0.0"
@@ -40879,12 +40951,15 @@
             }
         },
         "node_modules/url": {
-            "version": "0.11.3",
-            "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz",
-            "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==",
+            "version": "0.11.4",
+            "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz",
+            "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==",
             "dependencies": {
                 "punycode": "^1.4.1",
-                "qs": "^6.11.2"
+                "qs": "^6.12.3"
+            },
+            "engines": {
+                "node": ">= 0.4"
             }
         },
         "node_modules/url-loader": {
@@ -40950,9 +41025,9 @@
             "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="
         },
         "node_modules/url/node_modules/qs": {
-            "version": "6.12.3",
-            "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.3.tgz",
-            "integrity": "sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==",
+            "version": "6.13.0",
+            "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+            "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
             "dependencies": {
                 "side-channel": "^1.0.6"
             },
@@ -41313,9 +41388,11 @@
             }
         },
         "node_modules/web-streams-polyfill": {
-            "version": "3.3.3",
-            "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
-            "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0.tgz",
+            "integrity": "sha512-0zJXHRAYEjM2tUfZ2DiSOHAa2aw1tisnnhU3ufD57R8iefL+DcdJyRBRyJpG+NUimDgbTI/lH+gAE1PAvV3Cgw==",
+            "optional": true,
+            "peer": true,
             "engines": {
                 "node": ">= 8"
             }
@@ -41479,12 +41556,12 @@
             }
         },
         "node_modules/webpack-dev-middleware/node_modules/memfs": {
-            "version": "4.9.3",
-            "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.9.3.tgz",
-            "integrity": "sha512-bsYSSnirtYTWi1+OPMFb0M048evMKyUYe0EbtuGQgq6BVQM1g1W8/KIUJCCvjgI/El0j6Q4WsmMiBwLUBSw8LA==",
+            "version": "4.11.1",
+            "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.11.1.tgz",
+            "integrity": "sha512-LZcMTBAgqUUKNXZagcZxvXXfgF1bHX7Y7nQ0QyEiNbRJgE29GhgPd8Yna1VQcLlPiHt/5RFJMWYN9Uv/VPNvjQ==",
             "dependencies": {
                 "@jsonjoy.com/json-pack": "^1.0.3",
-                "@jsonjoy.com/util": "^1.1.2",
+                "@jsonjoy.com/util": "^1.3.0",
                 "tree-dump": "^1.0.1",
                 "tslib": "^2.0.0"
             },
@@ -41565,9 +41642,9 @@
             }
         },
         "node_modules/webpack-dev-server/node_modules/rimraf": {
-            "version": "5.0.9",
-            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.9.tgz",
-            "integrity": "sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==",
+            "version": "5.0.10",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz",
+            "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==",
             "dev": true,
             "dependencies": {
                 "glob": "^10.3.7"
@@ -41575,9 +41652,6 @@
             "bin": {
                 "rimraf": "dist/esm/bin.mjs"
             },
-            "engines": {
-                "node": "14 >=14.20 || 16 >=16.20 || >=18"
-            },
             "funding": {
                 "url": "https://github.com/sponsors/isaacs"
             }
@@ -41760,13 +41834,13 @@
             }
         },
         "node_modules/which-builtin-type": {
-            "version": "1.1.3",
-            "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz",
-            "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==",
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz",
+            "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==",
             "dev": true,
             "dependencies": {
-                "function.prototype.name": "^1.1.5",
-                "has-tostringtag": "^1.0.0",
+                "function.prototype.name": "^1.1.6",
+                "has-tostringtag": "^1.0.2",
                 "is-async-function": "^2.0.0",
                 "is-date-object": "^1.0.5",
                 "is-finalizationregistry": "^1.0.2",
@@ -41775,8 +41849,8 @@
                 "is-weakref": "^1.0.2",
                 "isarray": "^2.0.5",
                 "which-boxed-primitive": "^1.0.2",
-                "which-collection": "^1.0.1",
-                "which-typed-array": "^1.1.9"
+                "which-collection": "^1.0.2",
+                "which-typed-array": "^1.1.15"
             },
             "engines": {
                 "node": ">= 0.4"
diff --git a/package.json b/package.json
index 899b2968e..302831bd2 100644
--- a/package.json
+++ b/package.json
@@ -36,6 +36,7 @@
         "@types/cookie-parser": "^1.4.6",
         "@types/cookie-session": "^2.0.48",
         "@types/d3": "^7.4.3",
+        "@types/dom-mediacapture-record": "^1.0.19",
         "@types/exif": "^0.6.5",
         "@types/express": "^4.17.21",
         "@types/express-session": "^1.17.10",
@@ -63,10 +64,12 @@
         "@types/request": "^2.48.12",
         "@types/request-promise": "^4.1.51",
         "@types/shelljs": "^0.8.15",
+        "@types/textarea-caret": "^3.0.3",
         "@types/textfit": "^2.4.4",
         "@types/uuid": "^10.0.0",
         "@types/valid-url": "^1.0.7",
         "@types/webpack": "^5.28.5",
+        "@types/webscopeio__react-textarea-autocomplete": "^4.7.5",
         "@types/youtube": "0.0.50",
         "chai": "^5.0.0",
         "cross-env": "^7.0.3",
diff --git a/src/ClientUtils.ts b/src/ClientUtils.ts
index fc415d589..f9e282993 100644
--- a/src/ClientUtils.ts
+++ b/src/ClientUtils.ts
@@ -17,7 +17,7 @@ export function DashColor(color: string | undefined) {
     }
 }
 
-export function lightOrDark(color: any) {
+export function lightOrDark(color: string | undefined) {
     if (color === 'transparent' || !color) return Colors.BLACK;
     if (color.startsWith?.('linear')) return Colors.BLACK;
     if (DashColor(color).isLight()) return Colors.BLACK;
@@ -351,9 +351,9 @@ export namespace ClientUtils {
     }
 }
 
-export function OmitKeys(obj: any, keys: string[], pattern?: string, addKeyFunc?: (dup: any) => void): { omit: any; extract: any } {
-    const omit: any = { ...obj };
-    const extract: any = {};
+export function OmitKeys(obj: object, keys: string[], pattern?: string, addKeyFunc?: (dup: object) => void): { omit: { [key: string]: unknown }; extract: { [key: string]: unknown } } {
+    const omit: { [key: string]: unknown } = { ...obj };
+    const extract: { [key: string]: unknown } = {};
     keys.forEach(key => {
         extract[key] = omit[key];
         delete omit[key];
@@ -369,8 +369,8 @@ export function OmitKeys(obj: any, keys: string[], pattern?: string, addKeyFunc?
     return { omit, extract };
 }
 
-export function WithKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => void) {
-    const dup: any = {};
+export function WithKeys(obj: object & { [key: string]: unknown }, keys: string[], addKeyFunc?: (dup: unknown) => void) {
+    const dup: { [key: string]: unknown } = {};
     keys.forEach(key => {
         dup[key] = obj[key];
     });
@@ -521,7 +521,7 @@ export function simulateMouseClick(element: Element | null | undefined, x: numbe
     }
 }
 
-export function getWordAtPoint(elem: any, x: number, y: number): string | undefined {
+export function getWordAtPoint(elem: Element, x: number, y: number): string | undefined {
     if (elem.tagName === 'INPUT') return 'input';
     if (elem.tagName === 'TEXTAREA') return 'textarea';
     if (elem.nodeType === elem.TEXT_NODE || elem.textContent) {
@@ -534,7 +534,7 @@ export function getWordAtPoint(elem: any, x: number, y: number): string | undefi
             range.setEnd(elem, currentPos + 1);
             const rangeRect = range.getBoundingClientRect();
             if (rangeRect.left <= x && rangeRect.right >= x && rangeRect.top <= y && rangeRect.bottom >= y) {
-                range.expand?.('word'); // doesn't exist in firefox
+                'expand' in range && (range.expand as (val: string) => void)('word'); // doesn't exist in firefox
                 const ret = range.toString();
                 range.detach();
                 return ret;
@@ -542,16 +542,18 @@ export function getWordAtPoint(elem: any, x: number, y: number): string | undefi
             currentPos += 1;
         }
     } else {
-        Array.from(elem.childNodes).forEach((childNode: any) => {
-            const range = childNode.ownerDocument.createRange();
-            range.selectNodeContents(childNode);
-            const rangeRect = range.getBoundingClientRect();
-            if (rangeRect.left <= x && rangeRect.right >= x && rangeRect.top <= y && rangeRect.bottom >= y) {
-                range.detach();
-                const word = getWordAtPoint(childNode, x, y);
-                if (word) return word;
-            } else {
-                range.detach();
+        Array.from(elem.children).forEach(childNode => {
+            const range = childNode.ownerDocument?.createRange();
+            if (range) {
+                range.selectNodeContents(childNode);
+                const rangeRect = range.getBoundingClientRect();
+                if (rangeRect.left <= x && rangeRect.right >= x && rangeRect.top <= y && rangeRect.bottom >= y) {
+                    range.detach();
+                    const word = getWordAtPoint(childNode, x, y);
+                    if (word) return word;
+                } else {
+                    range.detach();
+                }
             }
             return undefined;
         });
@@ -576,17 +578,18 @@ export function setupMoveUpEvents(
     target: object,
     e: React.PointerEvent,
     moveEvent: (e: PointerEvent, down: number[], delta: number[]) => boolean,
-    upEvent: (e: PointerEvent, movement: number[], isClick: boolean) => any,
-    clickEvent: (e: PointerEvent, doubleTap?: boolean) => any,
+    upEvent: (e: PointerEvent, movement: number[], isClick: boolean) => void,
+    clickEvent: (e: PointerEvent, doubleTap?: boolean) => unknown,
     // eslint-disable-next-line default-param-last
     stopPropagation: boolean = true,
     // eslint-disable-next-line default-param-last
     stopMovePropagation: boolean = true,
     noDoubleTapTimeout?: () => void
 ) {
-    const targetAny = target as any;
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    const targetAny: object & { _downX: number; _downY: number; _lastX: number; _lastY: number; _doubleTap: boolean; _doubleTime?: NodeJS.Timeout; _lastTap: number; _noClick: boolean } = target as any;
     const doubleTapTimeout = 300;
-    targetAny._doubleTap = Date.now() - (target as any)._lastTap < doubleTapTimeout;
+    targetAny._doubleTap = Date.now() - targetAny._lastTap < doubleTapTimeout;
     targetAny._lastTap = Date.now();
     targetAny._downX = targetAny._lastX = e.clientX;
     targetAny._downY = targetAny._lastY = e.clientY;
@@ -594,13 +597,13 @@ export function setupMoveUpEvents(
     let moving = false;
 
     const _moveEvent = (moveEv: PointerEvent): void => {
-        if (moving || Math.abs(moveEv.clientX - (target as any)._downX) > ClientUtils.DRAG_THRESHOLD || Math.abs(moveEv.clientY - (target as any)._downY) > ClientUtils.DRAG_THRESHOLD) {
+        if (moving || Math.abs(moveEv.clientX - targetAny._downX) > ClientUtils.DRAG_THRESHOLD || Math.abs(moveEv.clientY - targetAny._downY) > ClientUtils.DRAG_THRESHOLD) {
             moving = true;
-            if ((target as any)._doubleTime) {
-                clearTimeout((target as any)._doubleTime);
+            if (targetAny._doubleTime) {
+                targetAny._doubleTime && clearTimeout(targetAny._doubleTime);
                 targetAny._doubleTime = undefined;
             }
-            if (moveEvent(moveEv, [(target as any)._downX, (target as any)._downY], [moveEv.clientX - (target as any)._lastX, moveEv.clientY - (target as any)._lastY])) {
+            if (moveEvent(moveEv, [targetAny._downX, targetAny._downY], [moveEv.clientX - targetAny._lastX, moveEv.clientY - targetAny._lastY])) {
                 document.removeEventListener('pointermove', _moveEvent);
                 // eslint-disable-next-line no-use-before-define
                 document.removeEventListener('pointerup', _upEvent);
@@ -621,16 +624,16 @@ export function setupMoveUpEvents(
                 }, doubleTapTimeout);
             }
             if (targetAny._doubleTime && targetAny._doubleTap) {
-                clearTimeout(targetAny._doubleTime);
+                targetAny._doubleTime && clearTimeout(targetAny._doubleTime);
                 targetAny._doubleTime = undefined;
             }
-            targetAny._noClick = clickEvent(upEv, targetAny._doubleTap);
+            targetAny._noClick = clickEvent(upEv, targetAny._doubleTap) ? true : false;
         }
         document.removeEventListener('pointermove', _moveEvent);
         document.removeEventListener('pointerup', _upEvent, true);
     };
     const _clickEvent = (clickev: MouseEvent): void => {
-        if ((target as any)._noClick) clickev.stopPropagation();
+        if (targetAny._noClick) clickev.stopPropagation();
         document.removeEventListener('click', _clickEvent, true);
     };
     if (stopPropagation) {
@@ -642,11 +645,11 @@ export function setupMoveUpEvents(
     document.addEventListener('click', _clickEvent, true);
 }
 
-export function DivHeight(ele: HTMLElement): number {
-    return Number(getComputedStyle(ele).height.replace('px', ''));
+export function DivHeight(ele: HTMLElement | null): number {
+    return ele ? Number(getComputedStyle(ele).height.replace('px', '')) : 0;
 }
-export function DivWidth(ele: HTMLElement): number {
-    return Number(getComputedStyle(ele).width.replace('px', ''));
+export function DivWidth(ele: HTMLElement | null): number {
+    return ele ? Number(getComputedStyle(ele).width.replace('px', '')) : 0;
 }
 
 export function dateRangeStrToDates(dateStr: string) {
@@ -709,7 +712,7 @@ export function UpdateIcon(
     realNativeHeight: number,
     noSuffix: boolean,
     replaceRootFilename: string | undefined,
-    cb: (iconFile: string, nativeWidth: number, nativeHeight: number) => any
+    cb: (iconFile: string, nativeWidth: number, nativeHeight: number) => void
 ) {
     const newDiv = docViewContent.cloneNode(true) as HTMLDivElement;
     newDiv.style.width = width.toString();
@@ -719,9 +722,9 @@ export function UpdateIcon(
     const nativeWidth = width;
     const nativeHeight = height;
     return CreateImage(ClientUtils.prepend(''), document.styleSheets, htmlString, nativeWidth, (nativeWidth * panelHeight) / panelWidth, (scrollTop * panelHeight) / realNativeHeight)
-        .then(async (dataUrl: any) => {
+        .then(async dataUrl => {
             const returnedFilename = await ClientUtils.convertDataUri(dataUrl, filename, noSuffix, replaceRootFilename);
             cb(returnedFilename as string, nativeWidth, nativeHeight);
         })
-        .catch((error: any) => console.error('oops, something went wrong!', error));
+        .catch(error => console.error('oops, something went wrong!', error));
 }
diff --git a/src/JSZipUtils.js b/src/JSZipUtils.js
index 5ce1bd471..755de7226 100644
--- a/src/JSZipUtils.js
+++ b/src/JSZipUtils.js
@@ -12,13 +12,17 @@ JSZipUtils._getBinaryFromXHR = function (xhr) {
 function createStandardXHR() {
     try {
         return new window.XMLHttpRequest();
-    } catch (e) {}
+    } catch (e) {
+        /* empty */
+    }
 }
 
 function createActiveXHR() {
     try {
         return new window.ActiveXObject('Microsoft.XMLHTTP');
-    } catch (e) {}
+    } catch (e) {
+        /* empty */
+    }
 }
 
 // Create the request object
@@ -101,7 +105,7 @@ JSZipUtils.getBinaryContent = function (path, options) {
             xhr.overrideMimeType('text/plain; charset=x-user-defined');
         }
 
-        xhr.onreadystatechange = function (event) {
+        xhr.onreadystatechange = function (/* event */) {
             // use `xhr` and not `this`... thanks IE
             if (xhr.readyState === 4) {
                 if (xhr.status === 200 || xhr.status === 0) {
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index ac865382d..2bf3a6f9f 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -1,14 +1,14 @@
-import { runInAction } from 'mobx';
+/* eslint-disable @typescript-eslint/no-namespace */
+import { action } from 'mobx';
 import { Socket, io } from 'socket.io-client';
 import { ClientUtils } from '../ClientUtils';
 import { Utils, emptyFunction } from '../Utils';
-import { Doc, Opt } from '../fields/Doc';
+import { Doc, FieldType, Opt, SetObjGetRefField, SetObjGetRefFields } from '../fields/Doc';
 import { UpdatingFromServer } from '../fields/DocSymbols';
 import { FieldLoader } from '../fields/FieldLoader';
 import { HandleUpdate, Id, Parent } from '../fields/FieldSymbols';
-import { ObjectField, SetObjGetRefField, SetObjGetRefFields } from '../fields/ObjectField';
-import { RefField } from '../fields/RefField';
-import { GestureContent, Message, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent, YoutubeQueryTypes } from '../server/Message';
+import { ObjectField, serverOpType } from '../fields/ObjectField';
+import { GestureContent, Message, MessageStore, MobileDocumentUploadContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent } from '../server/Message';
 import { SerializationHelper } from './util/SerializationHelper';
 
 /**
@@ -25,8 +25,7 @@ import { SerializationHelper } from './util/SerializationHelper';
  * or update ourselves based on the server's update message, that occurs here
  */
 export namespace DocServer {
-    // eslint-disable-next-line import/no-mutable-exports
-    let _cache: { [id: string]: RefField | Promise<Opt<RefField>> } = {};
+    let _cache: { [id: string]: Doc | Promise<Opt<Doc>> } = {};
     export function Cache() {
         return _cache;
     }
@@ -34,24 +33,24 @@ export namespace DocServer {
     function errorFunc(): never {
         throw new Error("Can't use DocServer without calling init first");
     }
-    let _UpdateField: (id: string, diff: any) => void = errorFunc;
-    let _CreateField: (field: RefField) => void = errorFunc;
+    let _UpdateField: (id: string, diff: serverOpType) => void = errorFunc;
+    let _CreateField: (field: Doc) => void = errorFunc;
 
-    export function AddServerHandler<T>(socket: Socket, message: Message<T>, handler: (args: T) => any) {
+    export function AddServerHandler<T>(socket: Socket, message: Message<T>, handler: (args: T) => void) {
         socket.on(message.Message, Utils.loggingCallback('Incoming', handler, message.Name));
     }
     export function Emit<T>(socket: Socket, message: Message<T>, args: T) {
         // log('Emit', message.Name, args, false);
         socket.emit(message.Message, args);
     }
-    export function EmitCallback<T>(socket: Socket, message: Message<T>, args: T): Promise<any>;
-    export function EmitCallback<T>(socket: Socket, message: Message<T>, args: T, fn: (args: any) => any): void;
-    export function EmitCallback<T>(socket: Socket, message: Message<T>, args: T, fn?: (args: any) => any): void | Promise<any> {
+    export function EmitCallback<T>(socket: Socket, message: Message<T>, args: T): Promise<unknown>;
+    export function EmitCallback<T>(socket: Socket, message: Message<T>, args: T, fn: (args: unknown) => unknown): void;
+    export function EmitCallback<T>(socket: Socket, message: Message<T>, args: T, fn?: (args: unknown) => unknown): void | Promise<unknown> {
         // log('Emit', message.Name, args, false);
         if (fn) {
             socket.emit(message.Message, args, Utils.loggingCallback('Receiving', fn, message.Name));
         } else {
-            return new Promise<any>(res => {
+            return new Promise<unknown>(res => {
                 socket.emit(message.Message, args, Utils.loggingCallback('Receiving', res, message.Name));
             });
         }
@@ -99,7 +98,7 @@ export namespace DocServer {
         return ClientUtils.CurrentUserEmail() === 'guest' ? WriteMode.LivePlayground : fieldWriteModes[field] || WriteMode.Default;
     }
 
-    export function registerDocWithCachedUpdate(doc: Doc, field: string, oldValue: any) {
+    export function registerDocWithCachedUpdate(doc: Doc, field: string, oldValue: FieldType) {
         let list = docsWithUpdates[field];
         if (!list) {
             list = docsWithUpdates[field] = new Set();
@@ -203,7 +202,7 @@ export namespace DocServer {
      * the server if the document has not been cached.
      * @param id the id of the requested document
      */
-    const _GetRefFieldImpl = (id: string, force: boolean = false): Promise<Opt<RefField>> => {
+    const _GetRefFieldImpl = (id: string, force: boolean = false): Promise<Opt<Doc>> => {
         // an initial pass through the cache to determine whether the document needs to be fetched,
         // is already in the process of being fetched or already exists in the
         // cache
@@ -221,7 +220,7 @@ export namespace DocServer {
             // future .proto calls on the Doc won't have to go farther than the cache to get their actual value.
             const deserializeField = getSerializedField.then(async fieldJson => {
                 // deserialize
-                const field = await SerializationHelper.Deserialize(fieldJson);
+                const field = (await SerializationHelper.Deserialize(fieldJson)) as Doc;
                 if (force && field && cached instanceof Doc) {
                     cached[UpdatingFromServer] = true;
                     Array.from(Object.keys(field)).forEach(key => {
@@ -247,7 +246,7 @@ export namespace DocServer {
             // here, indicate that the document associated with this id is currently
             // being retrieved and cached
             !force && (_cache[id] = deserializeField);
-            return force ? (cached as any) : deserializeField;
+            return force ? (cached instanceof Promise ? cached : new Promise<Doc>(res => res(cached))) : deserializeField;
         }
         if (cached instanceof Promise) {
             // BEING RETRIEVED AND CACHED => some other caller previously (likely recently) called GetRefField(s),
@@ -261,7 +260,7 @@ export namespace DocServer {
             // (field instanceof Doc) && fetchProto(field);
         );
     };
-    const _GetCachedRefFieldImpl = (id: string): Opt<RefField> => {
+    const _GetCachedRefFieldImpl = (id: string): Opt<Doc> => {
         const cached = _cache[id];
         if (cached !== undefined && !(cached instanceof Promise)) {
             return cached;
@@ -269,174 +268,102 @@ export namespace DocServer {
         return undefined;
     };
 
-    let _GetRefField: (id: string, force: boolean) => Promise<Opt<RefField>> = errorFunc;
-    let _GetCachedRefField: (id: string) => Opt<RefField> = errorFunc;
+    let _GetRefField: (id: string, force: boolean) => Promise<Opt<Doc>> = errorFunc;
+    let _GetCachedRefField: (id: string) => Opt<Doc> = errorFunc;
 
-    export function GetRefField(id: string, force = false): Promise<Opt<RefField>> {
+    export function GetRefField(id: string, force = false): Promise<Opt<Doc>> {
         return _GetRefField(id, force);
     }
-    export function GetCachedRefField(id: string): Opt<RefField> {
+    export function GetCachedRefField(id: string): Opt<Doc> {
         return _GetCachedRefField(id);
     }
 
-    export async function getYoutubeChannels() {
-        return DocServer.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.Channels });
-    }
-
-    export function getYoutubeVideos(videoTitle: string, callBack: (videos: any[]) => void) {
-        DocServer.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.SearchVideo, userInput: videoTitle }, callBack);
-    }
-
-    export function getYoutubeVideoDetails(videoIds: string, callBack: (videoDetails: any[]) => void) {
-        DocServer.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.VideoDetails, videoIds: videoIds }, callBack);
-    }
-
     /**
      * Given a list of Doc GUIDs, this utility function will asynchronously attempt to each id's associated
      * field, first looking in the RefField cache and then communicating with
      * the server if the document has not been cached.
      * @param ids the ids that map to the reqested documents
      */
-    const _GetRefFieldsImpl = async (ids: string[]): Promise<{ [id: string]: Opt<RefField> }> => {
-        const requestedIds: string[] = [];
-        const promises: Promise<any>[] = [];
-
-        let defaultRes: any;
-        const defaultPromise = new Promise<any>(res => {
-            defaultRes = res;
+    const _GetRefFieldsImpl = async (ids: string[]): Promise<Map<string, Opt<Doc>>> => {
+        const uncachedRequestedIds: string[] = [];
+        const deserializeDocPromises: Promise<Opt<Doc>>[] = [];
+
+        // setup a Promise that we will resolve after all cached Docs have been acquired.
+        let allCachesFilledResolver!: (value: Opt<Doc> | PromiseLike<Opt<Doc>>) => void;
+        const allCachesFilledPromise = new Promise<Opt<Doc>>(res => {
+            allCachesFilledResolver = res;
         });
-        const defaultPromises: { p: Promise<any>; id: string }[] = [];
-        // 1) an initial pass through the cache to determine
-        // i) which documents need to be fetched
-        // ii) which are already in the process of being fetched
-        // iii) which already exist in the cache
+
+        const fetchDocPromises: Map<string, Promise<Opt<Doc>>> = new Map(); // { p: Promise<Doc>; id: string }[] = []; // promises to fetch the value for a requested Doc
+        // Determine which requested documents need to be fetched
         // eslint-disable-next-line no-restricted-syntax
         for (const id of ids.filter(filterid => filterid)) {
-            const cached = _cache[id];
-            if (cached === undefined) {
-                defaultPromises.push({
-                    id,
-                    // eslint-disable-next-line no-loop-func
-                    p: (_cache[id] = new Promise<any>(res => {
-                        defaultPromise.then(() => res(_cache[id]));
-                    })),
-                });
-                // NOT CACHED => we'll have to send a request to the server
-                requestedIds.push(id);
-            } else if (cached instanceof Promise) {
-                // BEING RETRIEVED AND CACHED => some other caller previously (likely recently) called GetRefField(s),
-                // and requested one of the documents I'm looking for. Shouldn't fetch again, just
-                // wait until this promise is resolved (see 7)
-                promises.push(cached);
-                // waitingIds.push(id);
-            } else {
-                // CACHED => great, let's just add it to the field map
-                // map[id] = cached;
+            if (_cache[id] === undefined) {
+                // EMPTY CACHE - make promise that we resolve after all batch-requested Docs have been fetched and deserialized and we know we have this Doc
+                const fetchPromise = new Promise<Opt<Doc>>(res =>
+                    allCachesFilledPromise.then(() => {
+                        // if all Docs have been cached, then we can be sure the fetched Doc has been found and cached. So return it to anyone who had been awaiting it.
+                        const cache = _cache[id];
+                        if (!(cache instanceof Doc)) console.log('CACHE WAS NEVER FILLED!!');
+                        res(cache instanceof Doc ? cache : undefined);
+                    })
+                );
+                // eslint-disable-next-line no-loop-func
+                fetchDocPromises.set(id, (_cache[id] = fetchPromise));
+                uncachedRequestedIds.push(id); // add to list of Doc requests from server
             }
+            // else CACHED => do nothing, Doc or promise of Doc is already in cache
         }
 
-        if (requestedIds.length) {
-            // 2) synchronously, we emit a single callback to the server requesting the serialized (i.e. represented by a string)
-            // fields for the given ids. This returns a promise, which, when resolved, indicates that all the JSON serialized versions of
-            // the fields have been returned from the server
-            console.log('Requesting ' + requestedIds.length);
-            setTimeout(() =>
-                runInAction(() => {
-                    FieldLoader.ServerLoadStatus.requested = requestedIds.length;
-                })
-            );
-            const serializedFields = await DocServer.EmitCallback(_socket, MessageStore.GetRefFields, requestedIds);
-
-            // 3) when the serialized RefFields have been received, go head and begin deserializing them into objects.
-            // Here, once deserialized, we also invoke .proto to 'load' the documents' prototypes, which ensures that all
-            // future .proto calls on the Doc won't have to go farther than the cache to get their actual value.
+        if (uncachedRequestedIds.length) {
+            console.log('Requesting ' + uncachedRequestedIds.length);
+            setTimeout(action(() => { FieldLoader.ServerLoadStatus.requested = uncachedRequestedIds.length; })); // prettier-ignore
+
+            // Synchronously emit a single server request for the serialized (i.e. represented by a string) Doc ids
+            // This returns a promise, that resolves when all the JSON serialized Docs have been retrieved
+            const serializedFields = (await DocServer.EmitCallback(_socket, MessageStore.GetRefFields, uncachedRequestedIds)) as { id: string; fields: unknown[]; __type: string }[];
+
             let processed = 0;
-            console.log('deserializing ' + serializedFields.length + ' fields');
+            console.log('Retrieved ' + serializedFields.length + ' fields');
+            // After the serialized Docs have been received, deserialize them into objects.
             // eslint-disable-next-line no-restricted-syntax
             for (const field of serializedFields) {
-                processed++;
-                if (processed % 150 === 0) {
+                // eslint-disable-next-line no-await-in-loop
+                ++processed % 150 === 0 &&
+                    (await new Promise<number>(
+                        res =>
+                        setTimeout(action(() => res(FieldLoader.ServerLoadStatus.retrieved = processed))) // prettier-ignore
+                    )); // force loading to yield to splash screen rendering to update progress
+
+                if (fetchDocPromises.has(field.id)) {
+                    // Doc hasn't started deserializing yet - the cache still has the fetch promise
                     // eslint-disable-next-line no-loop-func
-                    runInAction(() => {
-                        FieldLoader.ServerLoadStatus.retrieved = processed;
+                    const deserializePromise = SerializationHelper.Deserialize(field).then((deserialized: unknown) => {
+                        const doc = deserialized as Doc;
+                        // overwrite any fetch or deserialize cache promise with deserialized value.
+                        // fetch promises wait to resolve until after all deserializations; deserialize promises resolve upon deserializaton
+                        if (deserialized !== undefined) _cache[field.id] = doc;
+                        else delete _cache[field.id];
+
+                        return doc;
                     });
-                    // eslint-disable-next-line no-await-in-loop
-                    await new Promise(res => {
-                        setTimeout(res);
-                    }); // force loading to yield to splash screen rendering to update progress
-                }
-                const cached = _cache[field.id];
-                if (!cached || (cached instanceof Promise && defaultPromises.some(dp => dp.p === cached))) {
-                    // deserialize
-                    // adds to a list of promises that will be awaited asynchronously
-                    promises.push(
-                        // eslint-disable-next-line no-loop-func
-                        (_cache[field.id] = SerializationHelper.Deserialize(field).then(deserialized => {
-                            // overwrite or delete any promises (that we inserted as flags
-                            // to indicate that the field was in the process of being fetched). Now everything
-                            // should be an actual value within or entirely absent from the cache.
-                            if (deserialized !== undefined) {
-                                _cache[field.id] = deserialized;
-                            } else {
-                                delete _cache[field.id];
-                            }
-                            const promInd = defaultPromises.findIndex(dp => dp.id === field.id);
-                            promInd !== -1 && defaultPromises.splice(promInd, 1);
-                            return deserialized;
-                        }))
-                    );
-                    // 4) here, for each of the documents we've requested *ourselves* (i.e. weren't promises or found in the cache)
-                    // we set the value at the field's id to a promise that will resolve to the field.
-                    // When we find that promises exist at keys in the cache, THIS is where they were set, just by some other caller (method).
-                    // The mapping in the .then call ensures that when other callers await these promises, they'll
-                    // get the resolved field
-                } else if (cached instanceof Promise) {
+                    deserializeDocPromises.push((_cache[field.id] = deserializePromise)); // replace the cache's placeholder fetch promise with the deserializePromise
+                    fetchDocPromises.delete(field.id);
+                } else if (_cache[field.id] instanceof Promise) {
                     console.log('.');
-                    // promises.push(cached);
-                } else if (field) {
-                    // console.log('-');
                 }
             }
         }
 
-        await Promise.all(promises);
-        defaultPromises.forEach(df => delete _cache[df.id]);
-        defaultRes();
-
-        // 5) at this point, all fields have a) been returned from the server and b) been deserialized into actual Field objects whose
-        // prototype documents, if any, have also been fetched and cached.
-        console.log('Deserialized ' + (requestedIds.length - defaultPromises.length) + ' fields');
-        // 6) with this confidence, we can now go through and update the cache at the ids of the fields that
-        // we explicitly had to fetch. To finish it off, we add whatever value we've come up with for a given
-        // id to the soon-to-be-returned field mapping.
-        // ids.forEach(id => (map[id] = _cache[id] as any));
-
-        // 7) those promises we encountered in the else if of 1), which represent
-        // other callers having already submitted a request to the server for (a) document(s)
-        // in which we're interested, must still be awaited so that we can return the proper
-        // values for those as well.
-        //
-        // fortunately, those other callers will also hit their own version of 6) and clean up
-        // the shared cache when these promises resolve, so all we have to do is...
-        // const otherCallersFetching = await Promise.all(promises);
-        // ...extract the RefFields returned from the resolution of those promises and add them to our
-        // own map.
-        // waitingIds.forEach((id, index) => (map[id] = otherCallersFetching[index]));
-
-        // now, we return our completed mapping from all of the ids that were passed into the method
-        // to their actual RefField | undefined values. This return value either becomes the input
-        // argument to the caller's promise (i.e. GetRefFields(["_id1_", "_id2_", "_id3_"]).then(map => //do something with map...))
-        // or it is the direct return result if the promise is awaited (i.e. let fields = await GetRefFields(["_id1_", "_id2_", "_id3_"])).
-        return ids.reduce(
-            (map, id) => {
-                map[id] = _cache[id] as any;
-                return map;
-            },
-            {} as { [id: string]: Opt<RefField> }
-        );
+        await Promise.all(deserializeDocPromises); // promise resolves when cache is up-to-date with all requested Docs
+        Array.from(fetchDocPromises).forEach(([id]) => delete _cache[id]);
+        allCachesFilledResolver(undefined); // notify anyone who was promised a Doc fron when it was just being fetched (since all requested Docs have now been fetched and deserialized)
+
+        console.log('Deserialized ' + (uncachedRequestedIds.length - fetchDocPromises.size) + ' fields');
+        return new Map<string, Opt<Doc>>(ids.map(id => [id, _cache[id] instanceof Doc ? (_cache[id] as Doc) : undefined]) as [string, Opt<Doc>][]);
     };
 
-    let _GetRefFields: (ids: string[]) => Promise<{ [id: string]: Opt<RefField> }> = errorFunc;
+    let _GetRefFields: (ids: string[]) => Promise<Map<string, Opt<Doc>>> = errorFunc;
 
     export function GetRefFields(ids: string[]) {
         return _GetRefFields(ids);
@@ -454,12 +381,12 @@ export namespace DocServer {
      * calling the same function throughout the code base (such as in Util.makeReadonly())
      * @param field the [RefField] to be serialized and sent to the server to be stored in the database
      */
-    export function CreateField(field: RefField) {
+    export function CreateField(field: Doc) {
         _cacheNeedsUpdate = true;
         _CreateField(field);
     }
 
-    function _CreateFieldImpl(field: RefField) {
+    function _CreateFieldImpl(field: Doc) {
         _cache[field[Id]] = field;
         const initialState = SerializationHelper.Serialize(field);
         ClientUtils.CurrentUserEmail() !== 'guest' && DocServer.Emit(_socket, MessageStore.CreateField, initialState);
@@ -475,22 +402,22 @@ export namespace DocServer {
      * @param updatedState the new value of the document. At some point, this
      * should actually be a proper diff, to improve efficiency
      */
-    export function UpdateField(id: string, updatedState: any) {
+    export function UpdateField(id: string, updatedState: serverOpType) {
         _UpdateField(id, updatedState);
     }
 
-    function _UpdateFieldImpl(id: string, diff: any) {
+    function _UpdateFieldImpl(id: string, diff: serverOpType) {
         !DocServer.Control.isReadOnly() && ClientUtils.CurrentUserEmail() !== 'guest' && DocServer.Emit(_socket, MessageStore.UpdateField, { id, diff });
     }
 
-    function _respondToUpdateImpl(diff: any) {
-        const { id } = diff;
+    function _respondToUpdateImpl(change: { id: string; diff: serverOpType }) {
+        const { id } = change;
         // to be valid, the Diff object must reference
         // a document's id
         if (id === undefined) {
             return;
         }
-        const update = (f: Opt<RefField>) => {
+        const update = (f: Opt<Doc>) => {
             // if the RefField is absent from the cache or
             // its promise in the cache resolves to undefined, there
             // can't be anything to update
@@ -500,7 +427,7 @@ export namespace DocServer {
             // extract this Doc's update handler
             const handler = f[HandleUpdate];
             if (handler) {
-                handler.call(f, diff.diff);
+                handler.call(f, change.diff as { $set: { [key: string]: FieldType } } | { $unset: unknown });
             }
         };
         // check the cache for the field
@@ -536,8 +463,8 @@ export namespace DocServer {
     const _RespondToUpdate = _respondToUpdateImpl;
     const _respondToDelete = _respondToDeleteImpl;
 
-    function respondToUpdate(diff: any) {
-        _RespondToUpdate(diff);
+    function respondToUpdate(change: { id: string; diff: serverOpType }) {
+        _RespondToUpdate(change);
     }
 
     function respondToDelete(ids: string | string[]) {
@@ -548,7 +475,7 @@ export namespace DocServer {
         _cache = {};
         USER_ID = identifier;
         _socket = io(`${protocol.startsWith('https') ? 'wss' : 'ws'}://${hostname}:${port}`, { transports: ['websocket'], rejectUnauthorized: false });
-        _socket.on('connect_error', (err: any) => console.log(err));
+        _socket.on('connect_error', (err: unknown) => console.log(err));
         // io.connect(`https://7f079dda.ngrok.io`);// if using ngrok, create a special address for the websocket
 
         _GetCachedRefField = _GetCachedRefFieldImpl;
diff --git a/src/client/Network.ts b/src/client/Network.ts
index 968c407b2..8876d8190 100644
--- a/src/client/Network.ts
+++ b/src/client/Network.ts
@@ -8,12 +8,13 @@ import { Upload } from '../server/SharedMediaTypes';
  * mainly provides methods that the client can use to begin the process of
  * interacting with the server, such as fetching or uploading files.
  */
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace Networking {
     export async function FetchFromServer(relativeRoute: string) {
         return (await fetch(relativeRoute)).text();
     }
 
-    export async function PostToServer(relativeRoute: string, body?: any) {
+    export async function PostToServer(relativeRoute: string, body?: unknown) {
         const options = {
             uri: ClientUtils.prepend(relativeRoute),
             method: 'POST',
@@ -31,7 +32,7 @@ export namespace Networking {
      * used as the guid. Otherwise, a new guid is generated.
      */
     export interface FileGuidPair {
-        file: File;
+        file: File | Blob;
         guid?: string;
     }
     /**
@@ -48,15 +49,14 @@ export namespace Networking {
             if (!fileguidpairs.length) {
                 return [];
             }
-            const maxFileSize = 50000000;
+            const maxFileSize = 5000000;
             if (fileguidpairs.some(f => f.file.size > maxFileSize)) {
-                return new Promise<any>(res => {
-                    res([
-                        {
-                            source: { name: '', type: '', size: 0, toJson: () => ({ name: '', type: '' }) },
-                            result: { name: '', message: `max file size (${maxFileSize / 1000000}MB) exceeded` },
-                        },
-                    ]);
+                return new Promise<Upload.FileResponse<T>[]>(res => {
+                    res([{
+                            source:        { size: 0, filepath: '', mimetype: '', originalFilename: '', newFilename: '',hashAlgorithm: false, 
+                            toJSON: () => ({ size: 0, filepath: '', mimetype: '', originalFilename: '', newFilename: '',name: '', length: 0,  mtime: new Date(), type: '' }) },
+                            result: { name: '', message: `max file size (${maxFileSize / 1000000}MB) exceeded` }
+                        }]) // prettier-ignore
                 });
             }
             formData.set('fileguids', fileguidpairs.map(pair => pair.guid).join(';'));
@@ -77,7 +77,12 @@ export namespace Networking {
 
         const endpoint = browndash ? '[insert endpoint allowing local => browndash]' : '/uploadFormData';
         const response = await fetch(endpoint, parameters);
-        return response.json();
+        return response.json().then((json: Upload.FileResponse<T>[]) =>
+            json.map(fileresponse => {
+                if ('message' in fileresponse.result) fileresponse.result = new Error(fileresponse.result.message);
+                return fileresponse;
+            })
+        );
     }
 
     export async function UploadYoutubeToServer<T extends Upload.FileInformation = Upload.FileInformation>(videoId: string, overwriteId?: string): Promise<Upload.FileResponse<T>[]> {
diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts
index 0c9fe0315..a503d732b 100644
--- a/src/client/documents/DocUtils.ts
+++ b/src/client/documents/DocUtils.ts
@@ -35,14 +35,16 @@ import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
 import { DocumentType } from './DocumentTypes';
 import { Docs, DocumentOptions } from './Documents';
 
+// eslint-disable-next-line @typescript-eslint/no-var-requires
 const { DFLT_IMAGE_NATIVE_DIM } = require('../views/global/globalCssVariables.module.scss'); // prettier-ignore
 
 const defaultNativeImageDim = Number(DFLT_IMAGE_NATIVE_DIM.replace('px', ''));
 
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace DocUtils {
-    function matchFieldValue(doc: Doc, key: string, valueIn: any): boolean {
+    function matchFieldValue(doc: Doc, key: string, valueIn: unknown): boolean {
         let value = valueIn;
-        const hasFunctionFilter = ClientUtils.HasFunctionFilter(value);
+        const hasFunctionFilter = ClientUtils.HasFunctionFilter(value as string);
         if (hasFunctionFilter) {
             return hasFunctionFilter(StrCast(doc[key]));
         }
@@ -57,8 +59,8 @@ export namespace DocUtils {
             // prettier-ignore
             return  (value === Doc.FilterNone && !allLinks.length) || 
                     (value === Doc.FilterAny && !!allLinks.length) ||
-                    (allLinks.some(link => matchLink(value,DocCast(link.link_anchor_1)) || 
-                                           matchLink(value,DocCast(link.link_anchor_2)) ));
+                    (allLinks.some(link => matchLink(value as string, DocCast(link.link_anchor_1)) || 
+                                           matchLink(value as string, DocCast(link.link_anchor_2)) ));
         }
         if (typeof value === 'string') {
             value = value.replace(`,${ClientUtils.noRecursionHack}`, '');
@@ -71,9 +73,9 @@ export namespace DocUtils {
         }
         const vals = StrListCast(fieldVal); // list typing is very imperfect.  casting to a string list doesn't mean that the entries will actually be strings
         if (vals.length) {
-            return vals.some(v => typeof v === 'string' && v.includes(value)); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring
+            return vals.some(v => typeof v === 'string' && v.includes(value as string)); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring
         }
-        return Field.toString(fieldVal as FieldType).includes(value); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring
+        return Field.toString(fieldVal as FieldType).includes(value as string); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring
     }
     /**
      * @param docs
@@ -215,13 +217,13 @@ export namespace DocUtils {
                 {
                     acl_Guest: SharingPermissions.Augment,
                     _acl_Guest: SharingPermissions.Augment,
-                    title: ComputedField.MakeFunction('generateLinkTitle(this)') as any,
+                    title: ComputedField.MakeFunction('generateLinkTitle(this)') as unknown as string, // title can accept functions even though type says it can't
                     link_anchor_1_useSmallAnchor: source.useSmallAnchor ? true : undefined,
                     link_anchor_2_useSmallAnchor: target.useSmallAnchor ? true : undefined,
                     link_relationship: linkSettings.link_relationship,
                     link_description: linkSettings.link_description,
-                    x: ComputedField.MakeFunction(`((this.${a}?.x||0)+(this.${b}?.x||0))/2`) as any,
-                    y: ComputedField.MakeFunction(`((this.${a}?.y||0)+(this.${b}?.y||0))/2`) as any,
+                    x: ComputedField.MakeFunction(`((this.${a}?.x||0)+(this.${b}?.x||0))/2`) as unknown as number, // x can accept functions even though type says it can't
+                    y: ComputedField.MakeFunction(`((this.${a}?.y||0)+(this.${b}?.y||0))/2`) as unknown as number, // y can accept functions even though type says it can't
                     link_autoMoveAnchors: true,
                     _lockedPosition: true,
                     _layout_showCaption: '', // removed since they conflict with showing a link with a LinkBox (ie, line, not comparison box)
@@ -235,10 +237,10 @@ export namespace DocUtils {
         );
     }
 
-    export function AssignScripts(doc: Doc, scripts?: { [key: string]: string | undefined }, funcs?: { [key: string]: string }) {
+    export function AssignScripts(doc: Doc, scripts?: { [key: string]: string | undefined }, funcs?: { [key: string]: string | undefined }) {
         scripts &&
             Object.keys(scripts).forEach(key => {
-                const script = scripts[key];
+                const script = scripts[key] as string;
                 if (ScriptCast(doc[key])?.script.originalScript !== scripts[key] && script) {
                     (key.startsWith('_') ? doc : Doc.GetProto(doc))[key] = ScriptField.MakeScript(script, {
                         this: Doc.name,
@@ -261,16 +263,17 @@ export namespace DocUtils {
                 .filter(key => !key.endsWith('-setter'))
                 .forEach(key => {
                     const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
-                    if (ScriptCast(cfield)?.script.originalScript !== funcs[key]) {
+                    const func = funcs[key];
+                    if (ScriptCast(cfield)?.script.originalScript !== func) {
                         const setFunc = Cast(funcs[key + '-setter'], 'string', null);
-                        (key.startsWith('_') ? doc : Doc.GetProto(doc))[key] = funcs[key] ? ComputedField.MakeFunction(funcs[key], { dragData: Doc.DocDragDataName }, { _readOnly_: true }, setFunc) : undefined;
+                        (key.startsWith('_') ? doc : Doc.GetProto(doc))[key] = func ? ComputedField.MakeFunction(func, { dragData: Doc.DocDragDataName }, { _readOnly_: true }, setFunc) : undefined;
                     }
                 });
         return doc;
     }
     export function AssignOpts(doc: Doc | undefined, reqdOpts: DocumentOptions, items?: Doc[]) {
         if (doc) {
-            const compareValues = (val1: any, val2: any) => {
+            const compareValues = (val1: unknown, val2: unknown) => {
                 if (val1 instanceof List && val2 instanceof List && val1.length === val2.length) {
                     return !val1.some(v => !val2.includes(v)) || !val2.some(v => val1.includes(v));
                 }
@@ -334,7 +337,7 @@ export namespace DocUtils {
             if (path.includes(window.location.hostname)) {
                 const s = path.split('/');
                 const id = s[s.length - 1];
-                return DocServer.GetRefField(id).then(field => {
+                return DocServer.GetRefField(id)?.then(field => {
                     if (field instanceof Doc) {
                         const embedding = Doc.MakeEmbedding(field);
                         embedding.x = (options.x as number) || 0;
@@ -354,7 +357,7 @@ export namespace DocUtils {
         return ctor ? ctor(path, overwriteDoc ? { ...options, title: StrCast(overwriteDoc.title, path) } : options, overwriteDoc) : undefined;
     }
 
-    export function addDocumentCreatorMenuItems(docTextAdder: (d: Doc) => void, docAdder: (d: Doc) => void, x: number, y: number, simpleMenu: boolean = false, pivotField?: string, pivotValue?: string): void {
+    export function addDocumentCreatorMenuItems(docTextAdder: (d: Doc) => void, docAdder: (d: Doc) => void, x: number, y: number, simpleMenu: boolean = false, pivotField?: string, pivotValue?: string | number | boolean): void {
         const documentList: ContextMenuProps[] = DocListCast(DocListCast(Doc.MyTools?.data)[0]?.data)
             .filter(btnDoc => !btnDoc.hidden)
             .map(btnDoc => Cast(btnDoc?.dragFactory, Doc, null))
@@ -451,7 +454,7 @@ export namespace DocUtils {
         batch.end();
         return doc;
     }
-    export function findTemplate(templateName: string, type: string) {
+    export function findTemplate(templateName: string, doc: Doc) {
         let docLayoutTemplate: Opt<Doc>;
         const iconViews = DocListCast(Cast(Doc.UserDoc().template_icons, Doc, null)?.data);
         const templBtns = DocListCast(Cast(Doc.UserDoc().template_buttons, Doc, null)?.data);
@@ -469,7 +472,8 @@ export namespace DocUtils {
         // first try to find a template that matches the specific document type (<typeName>_<templateName>).  otherwise, fallback to a general match on <templateName>
         !docLayoutTemplate &&
             allTemplates.forEach(tempDoc => {
-                StrCast(tempDoc.title) === templateName + '_' + type && (docLayoutTemplate = tempDoc);
+                const templateType = StrCast(doc[templateName + '_fieldKey'] || doc.type);
+                StrCast(tempDoc.title) === templateName + '_' + templateType && (docLayoutTemplate = tempDoc);
             });
         !docLayoutTemplate &&
             allTemplates.forEach(tempDoc => {
@@ -481,7 +485,7 @@ export namespace DocUtils {
         const templateName = templateSignature.replace(/\(.*\)/, '');
         doc.layout_fieldKey = 'layout_' + (templateSignature || (docLayoutTemplate?.title ?? ''));
         // eslint-disable-next-line no-param-reassign
-        docLayoutTemplate = docLayoutTemplate || findTemplate(templateName, StrCast(doc.isGroup && doc.transcription ? 'transcription' : doc.type));
+        docLayoutTemplate = docLayoutTemplate || findTemplate(templateName, doc);
 
         const customName = 'layout_' + templateSignature;
         const _width = NumCast(doc._width);
@@ -619,7 +623,7 @@ export namespace DocUtils {
         const proto = protoIn;
         if (Upload.isImageInformation(result)) {
             const maxNativeDim = Math.min(Math.max(result.nativeHeight, result.nativeWidth), defaultNativeImageDim);
-            const exifRotation = StrCast((result.exifData?.data as any)?.Orientation).toLowerCase();
+            const exifRotation = StrCast(result.exifData?.data?.Orientation).toLowerCase();
             proto.data_nativeOrientation = result.exifData?.data?.image?.Orientation ?? (exifRotation.includes('rotate 90') || exifRotation.includes('rotate 270') ? 5 : undefined);
             proto.data_nativeWidth = result.nativeWidth < result.nativeHeight ? (maxNativeDim * result.nativeWidth) / result.nativeHeight : maxNativeDim;
             proto.data_nativeHeight = result.nativeWidth < result.nativeHeight ? maxNativeDim : maxNativeDim / (result.nativeWidth / result.nativeHeight);
@@ -697,10 +701,10 @@ export namespace DocUtils {
                 source: { newFilename, mimetype },
                 result,
             } = upfiles.lastElement();
-            if ((result as any).message) {
+            if (result instanceof Error) {
                 if (overwriteDoc) {
                     overwriteDoc.isLoading = false;
-                    overwriteDoc.loadingError = (result as any).message;
+                    overwriteDoc.loadingError = result.message;
                     Doc.removeCurrentlyLoading(overwriteDoc);
                 }
             } else newFilename && processFileupload(generatedDocuments, newFilename, mimetype ?? '', result, options, overwriteDoc);
@@ -736,9 +740,9 @@ export namespace DocUtils {
                 source: { newFilename, mimetype },
                 result,
             } = upfiles.lastElement() ?? { source: { newFilename: '', mimetype: '' }, result: { message: 'upload failed' } };
-            if ((result as any).message) {
+            if (result instanceof Error) {
                 if (overwriteDoc) {
-                    overwriteDoc.loadingError = (result as any).message;
+                    overwriteDoc.loadingError = result.message;
                     Doc.removeCurrentlyLoading(overwriteDoc);
                 }
             } else newFilename && mimetype && processFileupload(generatedDocuments, newFilename, mimetype, result, options, overwriteDoc);
@@ -768,7 +772,7 @@ export namespace DocUtils {
     export async function Zip(doc: Doc, zipFilename = 'dashExport.zip') {
         const { clone, map, linkMap } = await Doc.MakeClone(doc);
         const proms = new Set<string>();
-        function replacer(key: any, value: any) {
+        function replacer(key: string, value: { url: string; [key: string]: unknown }) {
             if (key && ['branchOf', 'cloneOf', 'cursors'].includes(key)) return undefined;
             if (value?.__type === 'image') {
                 const extension = value.url.replace(/.*\./, '');
@@ -804,8 +808,8 @@ export namespace DocUtils {
             return value;
         }
 
-        const docs: { [id: string]: any } = {};
-        const links: { [id: string]: any } = {};
+        const docs: { [id: string]: unknown } = {};
+        const links: { [id: string]: unknown } = {};
         Array.from(map.entries()).forEach(f => {
             docs[f[0]] = f[1];
         });
@@ -826,13 +830,13 @@ export namespace DocUtils {
         } else
             promArr.forEach((url, i) => {
                 // loading a file and add it in a zip file
-                JSZipUtils.getBinaryContent(window.location.origin + '/' + url, (err: any, data: any) => {
+                JSZipUtils.getBinaryContent(window.location.origin + '/' + url, (err: unknown, data: unknown) => {
                     if (err) throw err; // or handle the error
                     // // Generate a directory within the Zip file structure
                     // const assets = zip.folder("assets");
                     // assets.file(filename, data, {binary: true});
                     const assetPathOnServer = promArr[i].replace(window.location.origin + '/', '').replace(/\//g, '%%%');
-                    zip.file(assetPathOnServer, data, { binary: true });
+                    zip.file(assetPathOnServer, data as string, { binary: true });
                     console.log(' => ' + url);
                     if (++count === promArr.length) {
                         zip.file('docs.json', jsonDocs);
@@ -862,7 +866,7 @@ ScriptingGlobals.add(function copyDragFactory(dragFactory: Doc, asDelegate?: boo
     return dragFactory instanceof Doc ? (asDelegate ? DocUtils.delegateDragFactory(dragFactory) : DocUtils.copyDragFactory(dragFactory)) : dragFactory;
 });
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function makeDelegate(proto: any) {
+ScriptingGlobals.add(function makeDelegate(proto: Doc) {
     const d = Docs.Create.DelegateDocument(proto, { title: 'child of ' + proto.title });
     return d;
 });
diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 8f95068db..53edb2e31 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -31,7 +31,6 @@ export enum DocumentType {
 
     // special purpose wrappers that either take no data or are compositions of lower level types
     LINK = 'link',
-    IMPORT = 'import',
     PRES = 'presentation',
     PRESELEMENT = 'preselement',
     COMPARISON = 'comparison',
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index b96fdb4bd..d7fdf016c 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -141,12 +141,12 @@ class RtfInfo extends FInfo {
 }
 class ListInfo extends FInfo {
     fieldType? = FInfoFieldType.list;
-    values?: List<any>[] = [];
+    values?: List<FieldType>[] = [];
 }
 type BOOLt = BoolInfo | boolean;
 type NUMt = NumInfo | number;
 type STRt = StrInfo | string;
-type LISTt = ListInfo | List<any>;
+type LISTt = ListInfo | List<FieldType>;
 type DOCt = DocInfo | Doc;
 type RTFt = RtfInfo | RichTextField;
 type DIMt = DimInfo; // | typeof DimUnit.Pixel | typeof DimUnit.Ratio;
@@ -358,7 +358,7 @@ export class DocumentOptions {
     presentation_duration?: NUMt = new NumInfo('the duration of the slide in presentation view', false);
     presentation_zoomText?: BOOLt = new BoolInfo('whether text anchors should shown in a larger box when following links to make them stand out', false);
 
-    data?: any;
+    data?: FieldType;
     data_useCors?: BOOLt = new BoolInfo('whether CORS protocol should be used for web page');
     columnHeaders?: List<SchemaHeaderField>; // headers for stacking views
     schemaHeaders?: List<SchemaHeaderField>; // headers for schema view
@@ -464,13 +464,14 @@ export class DocumentOptions {
     sidebar_color?: string; // background color of text sidebar
     sidebar_type_collection?: string; // collection type of text sidebar
 
-    data_dashboards?: List<any>; // list of dashboards used in shareddocs;
+    data_dashboards?: List<FieldType>; // list of dashboards used in shareddocs;
     textTransform?: string;
     letterSpacing?: string;
     iconTemplate?: string; // name of icon template style
+    icon_fieldKey?: string; // specifies the icon template to use (e.g., icon_fieldKey='george', then the icon template's name is icon_george; otherwise, the template's name would be icon_<type> where type is the Doc's type(pdf,rich text, etc))
     selectedIndex?: NUMt = new NumInfo("which item in a linear view has been selected using the 'thumb doc' ui");
 
-    fieldValues?: List<any>; // possible values a field can have (used by FieldInfo's only)
+    fieldValues?: List<FieldType>; // possible values a field can have (used by FieldInfo's only)
     fieldType?: string; // display type of a field, e.g. string, number, enumeration (used by FieldInfo's only)
 
     clipboard?: Doc;
@@ -484,7 +485,10 @@ export class DocumentOptions {
 }
 
 export const DocOptions = new DocumentOptions();
+
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace Docs {
+    // eslint-disable-next-line @typescript-eslint/no-namespace
     export namespace Prototypes {
         type LayoutSource = { LayoutString: (key: string) => string };
         type PrototypeTemplate = {
@@ -492,7 +496,6 @@ export namespace Docs {
                 view: LayoutSource;
                 dataField: string;
             };
-            data?: any;
             options?: Partial<DocumentOptions>;
         };
         type TemplateMap = Map<DocumentType, PrototypeTemplate>;
@@ -554,7 +557,7 @@ export namespace Docs {
             const actualProtos = await DocServer.GetRefFields(prototypeIds);
             // update this object to include any default values: DocumentOptions for all prototypes
             prototypeIds.forEach(id => {
-                const existing = actualProtos[id] as Doc;
+                const existing = actualProtos.get(id);
                 const type = id.replace(suffix, '') as DocumentType;
                 // get or create prototype of the specified type...
                 const target = buildPrototype(type, id, existing);
@@ -627,16 +630,15 @@ export namespace Docs {
                 acl_Guest: SharingPermissions.View,
                 ...(template.options || {}),
                 layout: layout.view?.LayoutString(layout.dataField),
-                data: template.data,
             };
             Object.entries(options)
                 .filter(pair => typeof pair[1] === 'string' && pair[1].startsWith('@'))
                 .forEach(pair => {
                     if (!existing || ScriptCast(existing[pair[0]])?.script.originalScript !== pair[1].substring(1)) {
-                        (options as any)[pair[0]] = ComputedField.MakeFunction(pair[1].substring(1));
+                        (options as { [key: string]: unknown })[pair[0]] = ComputedField.MakeFunction(pair[1].substring(1));
                     }
                 });
-            return Doc.assign(existing ?? new Doc(prototypeId, true), OmitKeys(options, Object.keys(existing ?? {})).omit, undefined, true);
+            return Doc.assign(existing ?? new Doc(prototypeId, true), OmitKeys(options, Object.keys(existing ?? {})).omit as { [key: string]: FieldType }, undefined, true);
         }
     }
 
@@ -644,6 +646,7 @@ export namespace Docs {
      * Encapsulates the factory used to create new document instances
      * delegated from top-level prototypes
      */
+    // eslint-disable-next-line @typescript-eslint/no-namespace
     export namespace Create {
         /**
          * This function receives the relevant document prototype and uses
@@ -667,10 +670,10 @@ export namespace Docs {
         function InstanceFromProto(proto: Doc, data: FieldType | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = 'data', protoId?: string, placeholderDocIn?: Doc, noView?: boolean) {
             const placeholderDoc = placeholderDocIn;
             const viewKeys = ['x', 'y', 'isSystem']; // keys that should be addded to the view document even though they don't begin with an "_"
-            const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, '^_');
+            const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, '^_') as { omit: { [key: string]: FieldType | undefined }; extract: { [key: string]: FieldType | undefined } };
 
             // dataProps.acl_Override = SharingPermissions.Unset;
-            dataProps.acl_Guest = options.acl_Guest ?? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View);
+            dataProps.acl_Guest = options.acl_Guest?.toString() ?? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View);
             dataProps.isSystem = viewProps.isSystem;
             dataProps.isDataDoc = true;
             dataProps.author = ClientUtils.CurrentUserEmail();
@@ -693,7 +696,7 @@ export namespace Docs {
             }
 
             if (!noView) {
-                const viewFirstProps: { [id: string]: any } = { author: ClientUtils.CurrentUserEmail() };
+                const viewFirstProps: { [id: string]: FieldType } = { author: ClientUtils.CurrentUserEmail() };
                 viewFirstProps.acl_Guest = options._acl_Guest ?? (Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View);
                 let viewDoc: Doc;
                 // determines whether viewDoc should be created using placeholder Doc or default
@@ -710,7 +713,7 @@ export namespace Docs {
                     viewDoc = Doc.assign(Doc.MakeDelegate(dataDoc, delegId), viewFirstProps, true, true);
                 }
                 Doc.assign(viewDoc, viewProps, true, true);
-                if (![DocumentType.LINK, DocumentType.CONFIG, DocumentType.LABEL].includes(viewDoc.type as any)) {
+                if (![DocumentType.LINK, DocumentType.CONFIG, DocumentType.LABEL].includes(viewDoc.type as DocumentType)) {
                     CreateLinkToActiveAudio(() => viewDoc);
                 }
                 updateCachedAcls(dataDoc);
@@ -909,7 +912,7 @@ export namespace Docs {
         }
 
         export function ConfigDocument(options: DocumentOptions, id?: string) {
-            return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), options?.data, options, id, '', undefined, undefined, true);
+            return InstanceFromProto(Prototypes.get(DocumentType.CONFIG), undefined, options, id, '', undefined, undefined, true);
         }
 
         export function PileDocument(documents: Array<Doc>, options: DocumentOptions, id?: string) {
diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
index 77cf80151..d0cd69273 100644
--- a/src/client/util/CalendarManager.tsx
+++ b/src/client/util/CalendarManager.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { DateRangePicker, Provider, defaultTheme } from '@adobe/react-spectrum';
 import { IconLookup, faPlus } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -19,6 +17,7 @@ import { DocumentView } from '../views/nodes/DocumentView';
 import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
 import './CalendarManager.scss';
 import { SnappingManager } from './SnappingManager';
+import { CalendarDate, DateValue } from '@internationalized/date';
 // import 'react-date-range/dist/styles.css';
 // import 'react-date-range/dist/theme/default.css';
 
@@ -29,7 +28,7 @@ interface CalendarSelectOptions {
     value: string;
 }
 
-const formatCalendarDateToString = (calendarDate: any) => {
+const formatCalendarDateToString = (calendarDate: DateValue) => {
     console.log('Formatting the following date: ', calendarDate);
     const date = new Date(calendarDate.year, calendarDate.month - 1, calendarDate.day);
     console.log(typeof date);
@@ -44,7 +43,7 @@ const formatCalendarDateToString = (calendarDate: any) => {
 // TODO: For a doc already in a calendar: give option to edit date range, delete from calendar
 
 @observer
-export class CalendarManager extends ObservableReactComponent<{}> {
+export class CalendarManager extends ObservableReactComponent<object> {
     // eslint-disable-next-line no-use-before-define
     public static Instance: CalendarManager;
     @observable private isOpen = false;
@@ -101,7 +100,7 @@ export class CalendarManager extends ObservableReactComponent<{}> {
         this.layoutDocAcls = false;
     });
 
-    constructor(props: {}) {
+    constructor(props: object) {
         super(props);
         CalendarManager.Instance = this;
         makeObservable(this);
@@ -109,15 +108,6 @@ export class CalendarManager extends ObservableReactComponent<{}> {
 
     componentDidMount(): void {}
 
-    @action
-    handleSelectChange = (option: any) => {
-        if (option) {
-            const 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);
@@ -212,15 +202,13 @@ export class CalendarManager extends ObservableReactComponent<{}> {
     };
 
     @observable
-    selectedDateRange: any = [
-        {
-            start: new Date(),
-            end: new Date(),
-        },
-    ];
+    selectedDateRange: { start: DateValue; end: DateValue } = {
+        start: new CalendarDate(2024, 1, 1),
+        end: new CalendarDate(2024, 1, 1),
+    };
 
     @action
-    setSelectedDateRange = (range: any) => {
+    setSelectedDateRange = (range: { start: DateValue; end: DateValue }) => {
         console.log('Range: ', range);
         this.selectedDateRange = range;
     };
@@ -228,14 +216,14 @@ export class CalendarManager extends ObservableReactComponent<{}> {
     @computed
     get createButtonActive() {
         if (this.calendarName.length === 0 || this.errorMessage.length > 0) return false; // disabled if no calendar name
-        let startDate: Date | undefined;
-        let endDate: Date | undefined;
+        let startDate: DateValue | undefined;
+        let endDate: DateValue | undefined;
         try {
             startDate = this.selectedDateRange.start;
             endDate = this.selectedDateRange.end;
             console.log(startDate);
             console.log(endDate);
-        } catch (e: any) {
+        } catch (e) {
             console.log(e);
             return false; // disabled
         }
@@ -288,7 +276,13 @@ export class CalendarManager extends ObservableReactComponent<{}> {
                             isSearchable
                             options={this.selectOptions}
                             value={this.selectedExistingCalendarOption}
-                            onChange={this.handleSelectChange}
+                            onChange={change => {
+                                if (change) {
+                                    const selectOpt = change;
+                                    this.selectedExistingCalendarOption = selectOpt;
+                                    this.calendarName = selectOpt.value; // or label
+                                }
+                            }}
                             styles={{
                                 control: () => ({
                                     display: 'inline-flex',
diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx
index 253cdd8b5..47f31612f 100644
--- a/src/client/util/CaptureManager.tsx
+++ b/src/client/util/CaptureManager.tsx
@@ -1,26 +1,24 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { addStyleSheet } from '../../ClientUtils';
-import { Doc } from '../../fields/Doc';
+import { Doc, Opt } from '../../fields/Doc';
 import { DocCast, StrCast } from '../../fields/Types';
 import { MainViewModal } from '../views/MainViewModal';
 import { DocumentView } from '../views/nodes/DocumentView';
 import './CaptureManager.scss';
 
 @observer
-export class CaptureManager extends React.Component<{}> {
+export class CaptureManager extends React.Component<object> {
     // eslint-disable-next-line no-use-before-define
     public static Instance: CaptureManager;
     static _settingsStyle = addStyleSheet();
-    @observable _document: any = undefined;
+    @observable _document: Opt<Doc> = undefined;
     @observable isOpen: boolean = false; // whether the CaptureManager is to be displayed or not.
 
     // eslint-disable-next-line react/sort-comp
-    constructor(props: {}) {
+    constructor(props: object) {
         super(props);
         makeObservable(this);
         CaptureManager.Instance = this;
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index e095bc659..c99ce1832 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -1,7 +1,7 @@
 import { reaction, runInAction } from "mobx";
 import * as rp from 'request-promise';
 import { ClientUtils, OmitKeys } from "../../ClientUtils";
-import { Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc";
+import { Doc, DocListCast, DocListCastAsync, FieldType, Opt } from "../../fields/Doc";
 import { DocData } from "../../fields/DocSymbols";
 import { InkTool } from "../../fields/InkField";
 import { List } from "../../fields/List";
@@ -60,11 +60,10 @@ interface Button {
 
     // fields that do not correspond to DocumentOption fields
     scripts?: { script?: string; onClick?: string; onDoubleClick?: string }
-    funcs?: { [key:string]: any};
+    funcs?: { [key:string]: string};
     subMenu?: Button[];
 }
 
-// eslint-disable-next-line import/no-mutable-exports
 export let resolvedPorts: { server: number, socket: number };
 export class CurrentUserUtils {
 
@@ -174,8 +173,8 @@ export class CurrentUserUtils {
         const imageBox = (opts: DocumentOptions, fieldKey:string) => Docs.Create.ImageDocument( "http://www.cs.brown.edu/~bcz/noImage.png", { layout:ImageBox.LayoutString(fieldKey), "icon_nativeWidth": 360 / 4, "icon_nativeHeight": 270 / 4, iconTemplate:DocumentType.IMG,  _width: 360 / 4, _height: 270 / 4,  _layout_showTitle: "title", ...opts });
         const fontBox = (opts:DocumentOptions, fieldKey:string) => Docs.Create.FontIconDocument({ layout:FontIconBox.LayoutString(fieldKey), _nativeHeight: 30, _nativeWidth: 30, _width: 30, _height: 30, ...opts  });
         
-        const makeIconTemplate = (type: DocumentType | undefined, templateField: string, opts:DocumentOptions) => {
-            const title = "icon" + (type ? "_" + type : "");
+        const makeIconTemplate = (name: DocumentType | string | undefined, templateField: string, opts:DocumentOptions) => {
+            const title = "icon" + (name ? "_" + name : "");
             const curIcon = DocCast(templateIconsDoc[title]);
             const creator =  (() => { switch (opts.iconTemplate) {
                                         case DocumentType.IMG : return imageBox;
@@ -189,6 +188,10 @@ export class CurrentUserUtils {
                 {onClick:"deiconifyView(documentView)", onDoubleClick: "deiconifyViewToLightbox(documentView)", });
         };
         const iconTemplates = [
+            // see createCustomView for where icon templates are created at run time
+            // templates defined by a Docs icon_fieldKey (e.g., ink with a transciprtion shows a template of the transcribed text, not miniature ink)
+            makeIconTemplate("transcription",    "text",  { iconTemplate:DocumentType.LABEL, backgroundColor: "orange" }),
+            // templates defined by a Doc's type
             makeIconTemplate(undefined,          "title", { iconTemplate:DocumentType.LABEL, backgroundColor: "dimgray"}),
             makeIconTemplate(DocumentType.AUDIO, "title", { iconTemplate:DocumentType.LABEL, backgroundColor: "lightgreen"}),
             makeIconTemplate(DocumentType.PDF,   "title", { iconTemplate:DocumentType.LABEL, backgroundColor: "pink"}),
@@ -199,10 +202,9 @@ export class CurrentUserUtils {
             makeIconTemplate(DocumentType.COL,   "icon",  { iconTemplate:DocumentType.IMG}),
             makeIconTemplate(DocumentType.VID,   "icon",  { iconTemplate:DocumentType.IMG}),
             makeIconTemplate(DocumentType.BUTTON,"title", { iconTemplate:DocumentType.FONTICON}),
-            // nasty hack .. templates are looked up exclusively by type -- but we want a template for a document with a certain field (transcription) .. so this hack and the companion hack in createCustomView does this for now
-            makeIconTemplate("transcription" as any, "transcription", { iconTemplate:DocumentType.LABEL, backgroundColor: "orange" }),
-            // makeIconTemplate(DocumentType.PDF, "icon", {iconTemplate:DocumentType.IMG}, (opts) => imageBox("http://www.cs.brown.edu/~bcz/noImage.png", opts))
-        ].filter(d => d).map(d => d!);
+         // makeIconTemplate(DocumentType.PDF,   "icon",  { iconTemplate:DocumentType.IMG}),
+         ].filter(d => d).map(d => d!);
+
         DocUtils.AssignOpts(DocCast(doc[field]), {}, iconTemplates);
     }
 
@@ -349,9 +351,9 @@ pie title Minerals in my tap water
         plotlyApi(); mermaidsApi();
         const emptyThings:{key:string,  // the field name where the empty thing will be stored
                           opts:DocumentOptions,   // the document options that are required for the empty thing
-                          funcs?:{[key:string]: any},  // computed fields that are rquired for the empth thing
-                          scripts?:{[key:string]: any},
-                          creator:(opts:DocumentOptions)=> any // how to create the empty thing if it doesn't exist
+                          funcs?:{[key:string]: string},  // computed fields that are rquired for the empth thing
+                          scripts?:{[key:string]: string},
+                          creator:(opts:DocumentOptions)=> Doc // how to create the empty thing if it doesn't exist
               }[] = [
             {key: "Note",       creator: opts => Docs.Create.TextDocument("", opts),        opts: { _width: 200, _layout_autoHeight: true }},
             {key: "Flashcard",  creator: opts => Docs.Create.ComparisonDocument("", opts),  opts: { _layout_isFlashcard: true, _width: 300, _height: 300}},
@@ -402,7 +404,7 @@ pie title Minerals in my tap water
             { toolTip: "Tap or drag to create a collection",      title: "Col", icon: "folder",         dragFactory: doc.emptyCollection as Doc, clickFactory: DocCast(doc.emptyTab)},
             { toolTip: "Tap or drag to create a webpage",         title: "Web", icon: "globe-asia",     dragFactory: doc.emptyWebpage as Doc,    clickFactory: DocCast(doc.emptyWebpage)},
             { toolTip: "Tap or drag to create a comparison box",  title: "Compare", icon: "columns",    dragFactory: doc.emptyComparison as Doc, clickFactory: DocCast(doc.emptyComparison)},
-            { toolTip: "Tap or drag to create a diagram",      title: "Diagram", icon: "tree",        dragFactory: doc.emptyDiagram as Doc, clickFactory: DocCast(doc.emptyDiagram)},
+            { toolTip: "Tap or drag to create a diagram",      title: "Diagram", icon: "tree",          dragFactory: doc.emptyDiagram as Doc,    clickFactory: DocCast(doc.emptyDiagram)},
             { toolTip: "Tap or drag to create an audio recorder", title: "Audio", icon: "microphone",   dragFactory: doc.emptyAudio as Doc,      clickFactory: DocCast(doc.emptyAudio),      openFactoryLocation: OpenWhere.overlay},
             { toolTip: "Tap or drag to create a map",             title: "Map", icon: "map-marker-alt", dragFactory: doc.emptyMap as Doc,        clickFactory: DocCast(doc.emptyMap)},
             { toolTip: "Tap or drag to create a chat assistant",  title: "Assistant Chat", icon: "book",dragFactory: doc.emptyChat as Doc,       clickFactory: DocCast(doc.emptyChat)},
@@ -411,11 +413,11 @@ pie title Minerals in my tap water
             { toolTip: "Tap or drag to create a button",          title: "Button", icon: "circle",      dragFactory: doc.emptyButton as Doc,     clickFactory: DocCast(doc.emptyButton)},
             { toolTip: "Tap or drag to create a scripting box",   title: "Script", icon: "terminal",    dragFactory: doc.emptyScript as Doc,     clickFactory: DocCast(doc.emptyScript),                                             funcs: { hidden: "IsNoviceMode()"}},
             { toolTip: "Tap or drag to create a data viz node",   title: "DataViz", icon: "chart-bar",  dragFactory: doc.emptyDataViz as Doc,    clickFactory: DocCast(doc.emptyDataViz)},
-            { toolTip: "Tap or drag to create a bullet slide",    title: "PPT Slide", icon: "person-chalkboard", dragFactory: doc.emptySlide as Doc,      clickFactory: DocCast(doc.emptySlide),      openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}},
-            { toolTip: "Tap or drag to create a view slide",      title: "View Slide", icon: "address-card", dragFactory: doc.emptyViewSlide as Doc,clickFactory: DocCast(doc.emptyViewSlide),openFactoryLocation: OpenWhere.overlay,funcs: { hidden: "IsNoviceMode()"}},
-            { toolTip: "Tap or drag to create a data note",       title: "DataNote", icon: "window-maximize",dragFactory: doc.emptyHeader as Doc,clickFactory: DocCast(doc.emptyHeader),     openFactoryAsDelegate: true,            funcs: { hidden: "IsNoviceMode()"} },
-            { toolTip: "Toggle a Calculator REPL",                title: "replviewer",  icon: "calculator",                                      clickFactory: '<ScriptingRepl />' as any,   openFactoryLocation: OpenWhere.overlay}, // hack: clickFactory is not a Doc but will get interpreted as a custom UI by the openDoc() onClick script
-           // { toolTip: "Toggle an UndoStack",                     title: "undostacker", icon: "calculator",                                      clickFactory: "<UndoStack />" as any,         openFactoryLocation: OpenWhere.overlay},
+            { toolTip: "Tap or drag to create a bullet slide",    title: "PPT Slide", icon: "person-chalkboard",dragFactory: doc.emptySlide as Doc,clickFactory: DocCast(doc.emptySlide),      openFactoryLocation: OpenWhere.overlay, funcs: { hidden: "IsNoviceMode()"}},
+            { toolTip: "Tap or drag to create a view slide",      title: "View Slide", icon: "address-card", dragFactory: doc.emptyViewSlide as Doc,clickFactory: DocCast(doc.emptyViewSlide), openFactoryLocation: OpenWhere.overlay,funcs: { hidden: "IsNoviceMode()"}},
+            { toolTip: "Tap or drag to create a data note",       title: "DataNote", icon: "window-maximize",dragFactory: doc.emptyHeader as Doc,clickFactory: DocCast(doc.emptyHeader),       openFactoryAsDelegate: true,            funcs: { hidden: "IsNoviceMode()"} },
+            { toolTip: "Toggle a Calculator REPL",                title: "replviewer",  icon: "calculator",                                      clickFactory: '<ScriptingRepl />' as unknown as Doc, openFactoryLocation: OpenWhere.overlay}, // hack: clickFactory is not a Doc but will get interpreted as a custom UI by the openDoc() onClick script
+           // { toolTip: "Toggle an UndoStack",                     title: "undostacker", icon: "calculator",                                      clickFactory: "<UndoStack />" as any,        openFactoryLocation: OpenWhere.overlay},
           ].map(tuple => (
               { openFactoryLocation: OpenWhere.addRight, 
                 scripts: { onClick:     'openDoc(copyDragFactory(this.clickFactory,this.openFactoryAsDelegate), this.openFactoryLocation)', 
@@ -445,7 +447,7 @@ pie title Minerals in my tap water
     }
 
     /// returns descriptions needed to buttons for the left sidebar to open up panes displaying different collections of documents
-    static leftSidebarMenuBtnDescriptions(doc: Doc):{title:string, target:Doc, icon:string, toolTip: string, scripts:{[key:string]:any}, funcs?:{[key:string]:any}, hidden?: boolean}[] {
+    static leftSidebarMenuBtnDescriptions(doc: Doc):{title:string, target:Doc, icon:string, toolTip: string, scripts:{[key:string]:undefined|string}, funcs?:{[key:string]:undefined|string}, hidden?: boolean}[] {
       const badgeValue = "((len) => len && len !== '0' ? len: undefined)(docList(this.target?.data).filter(doc => !docList(this.target.viewed).includes(doc)).length.toString())"; 
       const getActiveDashTrails = "Doc.ActiveDashboard?.myTrails";
         return [
@@ -463,7 +465,7 @@ pie title Minerals in my tap water
 
     /// the empty panel that is filled with whichever left menu button's panel has been selected
     static setupLeftSidebarPanel(doc: Doc, field="myLeftSidebarPanel") {
-        DocUtils.AssignDocField(doc, field, (opts) => Doc.assign(new Doc(), opts as any), {title:"leftSidebarPanel", isSystem:true, undoIgnoreFields: new List<string>(['proto'])});
+        DocUtils.AssignDocField(doc, field, (opts) => Doc.assign(new Doc(), opts as {[key:string]: FieldType}), {title:"leftSidebarPanel", isSystem:true, undoIgnoreFields: new List<string>(['proto'])});
     }
 
     /// Initializes the left sidebar menu buttons and the panels they open up
@@ -523,7 +525,7 @@ pie title Minerals in my tap water
         const contextMenuLabels = [/* "Create New Dashboard" */]  as string[];
         const contextMenuIcons = [/* "plus" */]  as string[];
         const childContextMenuScripts = [`toggleComicMode()`, `snapshotDashboard()`, `shareDashboard(this)`, 'removeDashboard(this)', 'resetDashboard(this)']; // entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuFilters
-        const childContextMenuFilters =  ['!IsNoviceMode()', '!IsNoviceMode()', undefined as any, undefined as any, '!IsNoviceMode()'];// entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts
+        const childContextMenuFilters =  ['!IsNoviceMode()', '!IsNoviceMode()', undefined, undefined, '!IsNoviceMode()'];// entries must be kept in synch with childContextMenuLabels, childContextMenuIcons, and childContextMenuScripts
         const childContextMenuLabels =  ["Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard", "Reset Dashboard"];// entries must be kept in synch with childContextMenuScripts, childContextMenuIcons, and childContextMenuFilters
         const childContextMenuIcons = ["tv", "camera", "users", "times", "trash"]; // entries must be kept in synch with childContextMenuScripts, childContextMenuLabels, and childContextMenuFilters
         const reqdOpts:DocumentOptions = {
@@ -545,7 +547,7 @@ pie title Minerals in my tap water
             myDashboards.childContextMenuScripts = new List<ScriptField>(childContextMenuScripts.map(script => ScriptField.MakeFunction(script)!));
         } 
         if (Cast(myDashboards.childContextMenuFilters, listSpec(ScriptField), null)?.length !== childContextMenuFilters.length) {
-            myDashboards.childContextMenuFilters = new List<ScriptField>(childContextMenuFilters.map(script => !script ? script: ScriptField.MakeFunction(script)!));
+            myDashboards.childContextMenuFilters = new List<ScriptField>(childContextMenuFilters.map(script => !script ? script as unknown as ScriptField: ScriptField.MakeFunction(script)!));
         }
         return myDashboards;
     }
@@ -611,7 +613,7 @@ pie title Minerals in my tap water
         _lockedPosition: true, isSystem: true, flexDirection: "row"
     })
     static multiToggleList = (opts: DocumentOptions, docs: Doc[]) => Docs.Create.FontIconDocument({
-        ...opts, data:docs, _gridGap: 0, _xMargin: 5, _yMargin: 5, layout_boxShadow: "0 0", _forceActive: true,
+        ...opts, data: new List<Doc>(docs), _gridGap: 0, _xMargin: 5, _yMargin: 5, layout_boxShadow: "0 0", _forceActive: true,
         dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }),
         _lockedPosition: true, isSystem: true, flexDirection: "row"
     })
@@ -806,7 +808,7 @@ pie title Minerals in my tap water
     /// initializes a context menu button for the top bar context menu
     static setupContextMenuButton(params:Button, btnDoc?:Doc, btnContainer?:Doc) {
         const reqdOpts:DocumentOptions = {
-            ...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit,
+            ...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit as {[key:string]: string|undefined},
             color: Colors.WHITE, isSystem: true,
             _nativeWidth: params.width ?? 30, _width: params.width ?? 30,
             _height: 30, _nativeHeight: 30, linearBtnWidth: params.linearBtnWidth,
@@ -814,7 +816,7 @@ pie title Minerals in my tap water
             _dragOnlyWithinContainer: true, _lockedPosition: true,
             _embedContainer: btnContainer
         };
-        const reqdFuncs:{[key:string]:any} = {
+        const reqdFuncs:{[key:string]:string} = {
             ...params.funcs,
         }
         return DocUtils.AssignScripts(DocUtils.AssignOpts(btnDoc, reqdOpts) ?? Docs.Create.FontIconDocument(reqdOpts), params.scripts, reqdFuncs);
@@ -853,14 +855,14 @@ pie title Minerals in my tap water
         Doc.UserDoc().workspaceRecordingState = undefined;
         Doc.UserDoc().workspaceReplayingState = undefined;
         const dockedBtns = DocCast(doc[field]);
-        const dockBtn = (opts: DocumentOptions, scripts: {[key:string]:string|undefined}, funcs?: {[key:string]:any}) =>
+        const dockBtn = (opts: DocumentOptions, scripts: {[key:string]:string|undefined}, funcs?: {[key:string]:string|undefined}) =>
             DocUtils.AssignScripts(DocUtils.AssignOpts(DocListCast(dockedBtns?.data)?.find(fdoc => fdoc.title === opts.title), opts) ?? 
                             CurrentUserUtils.createToolButton(opts), scripts, funcs);
         
         const btnDescs = [// setup reactions to change the highlights on the undo/redo buttons -- would be better to encode this in the undo/redo buttons, but the undo/redo stacks are not wired up that way yet
-            { opts: { title: "Replicate",icon:"camera",toolTip: "Copy dashboard layout",btnType: ButtonType.ClickButton, expertMode: true},                                                                                              scripts: { onClick:  `snapshotDashboard()`}},
-            { opts: { title: "Recordings",            toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList,expertMode: false, ignoreClick: true, width: 100}, funcs: {hidden: `false`, btnList:`getWorkspaceRecordings()`}, scripts: { script:  `{ return replayWorkspace(value, _readOnly_); }`, onDragScript: `{ return startRecordingDrag(value); }`}},
-            { opts: { title: "Stop Rec",icon: "stop", toolTip: "Stop recording",       btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `!isWorkspaceRecording()`},                                                  scripts: { onClick: `stopWorkspaceRecording()`}},
+            { opts: { title: "Replicate",icon:"camera",toolTip: "Copy dashboard layout",btnType: ButtonType.ClickButton, expertMode: true},                                                                                             scripts: { onClick:  `snapshotDashboard()`}},
+            { opts: { title: "Recordings",            toolTip: "Workspace Recordings", btnType: ButtonType.DropdownList,expertMode: false, ignoreClick: true, width: 100}, funcs: {hidden: `false`, btnList:`getWorkspaceRecordings()`},scripts: { script:  `{ return replayWorkspace(value, _readOnly_); }`, onDragScript: `{ return startRecordingDrag(value); }`}},
+            { opts: { title: "Stop Rec",icon: "stop", toolTip: "Stop recording",       btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `!isWorkspaceRecording()`},                                                 scripts: { onClick: `stopWorkspaceRecording()`}},
             { opts: { title: "Play",    icon: "play", toolTip: "Play recording",       btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${mediaState.Paused}"`},                       scripts: { onClick: `resumeWorkspaceReplaying(getCurrentRecording())`}},
             { opts: { title: "Pause",   icon: "pause",toolTip: "Pause playback",       btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${mediaState.Playing}"`},                      scripts: { onClick: `pauseWorkspaceReplaying(getCurrentRecording())`}},
             { opts: { title: "Stop",    icon: "stop", toolTip: "Stop playback",        btnType: ButtonType.ClickButton, expertMode: false}, funcs: {hidden: `isWorkspaceReplaying() !== "${mediaState.Paused}"`},                       scripts: { onClick: `stopWorkspaceReplaying(getCurrentRecording())`}},
@@ -1002,20 +1004,20 @@ pie title Minerals in my tap water
         return doc;
     }
     static setupFieldInfos(doc:Doc, field="fieldInfos") {
-        const fieldInfoOpts = { title: "Field Infos", isSystem: true}; // bcz: all possible document options have associated field infos which are stored onn the FieldInfos document **except for title and system which are used as part of the definition of the fieldInfos object
-        const infos = DocUtils.AssignDocField(doc, field, opts => Doc.assign(new Doc(), opts as any), fieldInfoOpts);
+        const fieldInfoOpts = { title: "Field Infos", isSystem: true}; // bcz: all possible document options have associated field infos which are stored on the FieldInfos document **except for title and system which are used as part of the definition of the fieldInfos object
+        const infos = DocUtils.AssignDocField(doc, field, opts => Doc.assign(new Doc(), opts as {[key:string]: FieldType}), fieldInfoOpts);
         const entries = Object.entries(new DocumentOptions());
         entries.forEach(pair => {
             if (!Array.from(Object.keys(fieldInfoOpts)).includes(pair[0])) {
                 const options = pair[1] as FInfo;
-                const opts:DocumentOptions = { isSystem: true, title: pair[0], ...OmitKeys(options, ["values"]).omit, fieldIsLayout: pair[0].startsWith("_")};
+                const opts:DocumentOptions = { isSystem: true, title: pair[0], ...OmitKeys(options, ["values"]).omit};
                 switch (options.fieldType) {
-                    case FInfoFieldType.boolean: opts.fieldValues = new List<boolean>(options.values as any); break;
-                    case FInfoFieldType.number: opts.fieldValues = new List<number>(options.values as any); break;
-                    case FInfoFieldType.Doc: opts.fieldValues = new List<Doc>(options.values as any); break;
-                    default: opts.fieldValues = new List<string>(options.values as any); break;// string, pointerEvents, dimUnit, dropActionType
+                    case FInfoFieldType.boolean: opts.fieldValues = new List<boolean>(options.values as boolean[]); break;
+                    case FInfoFieldType.number: opts.fieldValues = new List<number>(options.values as number[]); break;
+                    case FInfoFieldType.Doc: opts.fieldValues = new List<Doc>(options.values as Doc[]); break;
+                    default: opts.fieldValues = new List<FieldType>(options.values); break;// string, pointerEvents, dimUnit, dropActionType
                 }
-                DocUtils.AssignDocField(infos, pair[0], docOpts => Doc.assign(new Doc(), OmitKeys(docOpts,["values"]).omit), opts);
+                DocUtils.AssignDocField(infos, pair[0], docOpts => Doc.assign(new Doc(), OmitKeys(docOpts,["values"]).omit as {[key:string]: FieldType}), opts);
             }
         });
     }
@@ -1023,10 +1025,10 @@ pie title Minerals in my tap water
     public static async loadCurrentUser() {
         return rp.get(ClientUtils.prepend("/getCurrentUser")).then(async response => {
             if (response) {
-                const result: { version: string, userDocumentId: string, sharingDocumentId: string, linkDatabaseId: string,  email: string, cacheDocumentIds: string, resolvedPorts: string } = JSON.parse(response);
+                const result: { version: string, userDocumentId: string, sharingDocumentId: string, linkDatabaseId: string,  email: string, cacheDocumentIds: string, resolvedPorts: {server: number, socket: number} } = JSON.parse(response);
                 runInAction(() => { SnappingManager.SetServerVersion(result.version); });
                 ClientUtils.SetCurrentUserEmail(result.email);
-                resolvedPorts = result.resolvedPorts as any;
+                resolvedPorts = result.resolvedPorts;
                 DocServer.init(window.location.protocol, window.location.hostname, resolvedPorts?.socket, result.email);
                 if (result.cacheDocumentIds) 
                 {
diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts
index bc9fe813f..16a0df120 100644
--- a/src/client/util/DictationManager.ts
+++ b/src/client/util/DictationManager.ts
@@ -1,7 +1,5 @@
 /* eslint-disable no-use-before-define */
 import * as interpreter from 'words-to-numbers';
-// @ts-ignore  bcz: how are you supposed to include these definitions since dom-speech-recognition isn't a module?
-import type {} from '@types/dom-speech-recognition';
 import { ClientUtils } from '../../ClientUtils';
 import { Doc, Opt } from '../../fields/Doc';
 import { DocData } from '../../fields/DocSymbols';
@@ -33,19 +31,24 @@ import { UndoManager } from './UndoManager';
  * In addition to compile-time default commands, you can invoke DictationManager.Commands.Register(Independent|Dependent)
  * to add new commands as classes or components are constructed.
  */
+
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace DictationManager {
     /**
      * Some type maneuvering to access Webkit's built-in
      * speech recognizer.
      */
+
+    // eslint-disable-next-line @typescript-eslint/no-namespace
     namespace CORE {
         export interface IWindow extends Window {
-            webkitSpeechRecognition: any;
+            webkitSpeechRecognition: { new (): SpeechRecognition };
         }
     }
-    const { webkitSpeechRecognition }: CORE.IWindow = window as any as CORE.IWindow;
+    const { webkitSpeechRecognition }: CORE.IWindow = window as unknown as CORE.IWindow;
     export const placeholder = 'Listening...';
 
+    // eslint-disable-next-line @typescript-eslint/no-namespace
     export namespace Controls {
         export const Infringed = 'unable to process: dictation manager still involved in previous session';
         const browser = (() => {
@@ -74,7 +77,7 @@ export namespace DictationManager {
         // eslint-disable-next-line new-cap
         const recognizer: Opt<SpeechRecognition> = webkitSpeechRecognition ? new webkitSpeechRecognition() : undefined;
 
-        export type InterimResultHandler = (results: string) => any;
+        export type InterimResultHandler = (results: string) => void;
         export type ContinuityArgs = { indefinite: boolean } | false;
         export type DelimiterArgs = { inter: string; intra: string };
         export type ListeningUIStatus = { interim: boolean } | false;
@@ -117,11 +120,11 @@ export namespace DictationManager {
                     }
                     options?.tryExecute && (await DictationManager.Commands.execute(results));
                 }
-            } catch (e: any) {
+            } catch (e) {
                 console.log(e);
                 if (overlay) {
                     DictationOverlay.Instance.isListening = false;
-                    DictationOverlay.Instance.dictatedPhrase = results = `dictation error: ${'error' in e ? e.error : 'unknown error'}`;
+                    DictationOverlay.Instance.dictatedPhrase = results = `dictation error: ${(e as { error: string }).error || 'unknown error'}`;
                     DictationOverlay.Instance.dictationSuccess = false;
                 }
             } finally {
@@ -156,11 +159,11 @@ export namespace DictationManager {
             recognizer.start();
 
             return new Promise<string>(resolve => {
-                recognizer.onerror = (e: any) => {
+                recognizer.onerror = e => {
                     // e is SpeechRecognitionError but where is that defined?
                     if (!(indefinite && e.error === 'no-speech')) {
                         recognizer.stop();
-                        resolve(e);
+                        resolve(e.message);
                     }
                 };
 
@@ -227,13 +230,14 @@ export namespace DictationManager {
         };
     }
 
+    // eslint-disable-next-line @typescript-eslint/no-namespace
     export namespace Commands {
         export const dictationFadeDuration = 2000;
 
-        export type IndependentAction = (target: DocumentView) => any | Promise<any>;
+        export type IndependentAction = (target: DocumentView) => void | Promise<void>;
         export type IndependentEntry = { action: IndependentAction; restrictTo?: DocumentType[] };
 
-        export type DependentAction = (target: DocumentView, matches: RegExpExecArray) => any | Promise<any>;
+        export type DependentAction = (target: DocumentView, matches: RegExpExecArray) => void | Promise<void>;
         export type DependentEntry = { expression: RegExp; action: DependentAction; restrictTo?: DocumentType[] };
 
         export const RegisterIndependent = (key: string, value: IndependentEntry) => Independent.set(key, value);
@@ -295,7 +299,6 @@ export namespace DictationManager {
             [DocumentType.COL, listSpec(Doc)],
             [DocumentType.AUDIO, AudioField],
             [DocumentType.IMG, ImageField],
-            [DocumentType.IMPORT, listSpec(Doc)],
             [DocumentType.RTF, 'string'],
         ]);
 
@@ -397,8 +400,8 @@ export namespace DictationManager {
         ];
     }
     export function recordAudioAnnotation(dataDoc: Doc, field: string, onRecording?: (stop: () => void) => void, onEnd?: () => void) {
-        let gumStream: any;
-        let recorder: any;
+        let gumStream: MediaStream | undefined;
+        let recorder: MediaRecorder | undefined;
         navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
             let audioTextAnnos = Cast(dataDoc[field + '_audioAnnotations_text'], listSpec('string'), null);
             if (audioTextAnnos) audioTextAnnos.push('');
@@ -415,8 +418,12 @@ export namespace DictationManager {
 
             gumStream = stream;
             recorder = new MediaRecorder(stream);
-            recorder.ondataavailable = async (e: any) => {
-                const [{ result }] = await Networking.UploadFilesToServer({ file: e.data });
+            recorder.ondataavailable = async (e: BlobEvent) => {
+                const file: Blob & { name?: string; lastModified?: number; webkitRelativePath?: string } = e.data;
+                file.name = '';
+                file.lastModified = 0;
+                file.webkitRelativePath = '';
+                const [{ result }] = await Networking.UploadFilesToServer({ file: file as Blob & { name: string; lastModified: number; webkitRelativePath: string } });
                 if (!(result instanceof Error)) {
                     const audioField = new AudioField(result.accessPaths.agnostic.client);
                     const audioAnnos = Cast(dataDoc[field + '_audioAnnotations'], listSpec(AudioField), null);
@@ -426,10 +433,10 @@ export namespace DictationManager {
             };
             recorder.start();
             const stopFunc = () => {
-                recorder.stop();
+                recorder?.stop();
                 DictationManager.Controls.stop(/* false */);
                 dataDoc.audioAnnoState = AudioAnnoState.stopped;
-                gumStream.getAudioTracks()[0].stop();
+                gumStream?.getAudioTracks()[0].stop();
             };
             if (onRecording) onRecording(stopFunc);
             else setTimeout(stopFunc, 5000);
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index e41546d09..b12bf4390 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -50,22 +50,19 @@ export class DocumentManager {
         DocumentView.getLightboxDocumentView = this.getLightboxDocumentView;
         observe(Doc.CurrentlyLoading, change => {
             // watch CurrentlyLoading-- when something is loaded, it's removed from the list and we have to update its icon if it were iconified since LoadingBox icons are different than the media they become
-            switch (change.type as any) {
+            switch (change.type) {
                 case 'update':
                     break;
-                case 'remove':
-                    // DocumentManager.Instance.getAllDocumentViews(change as any).forEach(dv => StrCast(dv.Document.layout_fieldKey) === 'layout_icon' && dv.iconify(() => dv.iconify()));
-                    break;
                 case 'splice':
-                    (change as any).removed.forEach((doc: Doc) => DocumentManager.Instance.getAllDocumentViews(doc).forEach(dv => StrCast(dv.Document.layout_fieldKey) === 'layout_icon' && dv.iconify(() => dv.iconify())));
+                    change.removed.forEach((doc: Doc) => DocumentManager.Instance.getAllDocumentViews(doc).forEach(dv => StrCast(dv.Document.layout_fieldKey) === 'layout_icon' && dv.iconify(() => dv.iconify())));
                     break;
                 default:
             }
         });
     }
 
-    private _viewRenderedCbs: { doc: Doc; func: (dv: DocumentView) => any }[] = [];
-    public AddViewRenderedCb = (doc: Opt<Doc>, func: (dv: DocumentView) => any) => {
+    private _viewRenderedCbs: { doc: Doc; func: (dv: DocumentView) => unknown }[] = [];
+    public AddViewRenderedCb = (doc: Opt<Doc>, func: (dv: DocumentView) => unknown) => {
         if (doc) {
             const dv = DocumentView.LightboxDoc() ? this.getLightboxDocumentView(doc) : this.getDocumentView(doc);
             this._viewRenderedCbs.push({ doc, func });
@@ -74,6 +71,7 @@ export class DocumentManager {
                 return true;
             }
         } else {
+            // eslint-disable-next-line @typescript-eslint/no-explicit-any
             func(undefined as any);
         }
         return false;
@@ -341,18 +339,21 @@ export class DocumentManager {
             // if there's an options.effect, it will be handled from linkFollowHighlight.  We delay the start of
             // the highlight so that the target document can be somewhat centered so that the effect/highlight will be seen
             // bcz: should this delay be an options parameter?
-            setTimeout(() => {
-                Doc.linkFollowHighlight(viewSpec ? [docView.Document, viewSpec] : docView.Document, undefined, options.effect);
-                if (options.zoomTextSelections && Doc.IsUnhighlightTimerSet() && contextView && targetDoc.text_html) {
-                    // if the docView is a text anchor, the contextView is the PDF/Web/Text doc
-                    contextView.setTextHtmlOverlay(StrCast(targetDoc.text_html), options.effect);
-                    DocumentManager._overlayViews.add(contextView);
-                }
-                Doc.AddUnHighlightWatcher(() => {
-                    docView.Document[Animation] = undefined;
-                    DocumentManager.removeOverlayViews();
-                });
-            }, (options.zoomTime ?? 0) * 0.5);
+            setTimeout(
+                () => {
+                    Doc.linkFollowHighlight(viewSpec ? [docView.Document, viewSpec] : docView.Document, undefined, options.effect);
+                    if (options.zoomTextSelections && Doc.IsUnhighlightTimerSet() && contextView && targetDoc.text_html) {
+                        // if the docView is a text anchor, the contextView is the PDF/Web/Text doc
+                        contextView.setTextHtmlOverlay(StrCast(targetDoc.text_html), options.effect);
+                        DocumentManager._overlayViews.add(contextView);
+                    }
+                    Doc.AddUnHighlightWatcher(() => {
+                        docView.Document[Animation] = undefined;
+                        DocumentManager.removeOverlayViews();
+                    });
+                },
+                (options.zoomTime ?? 0) * 0.5
+            );
             if (options.playMedia) docView.ComponentView?.playFrom?.(NumCast(docView.Document._layout_currentTimecode));
             if (options.playAudio) DocumentManager.playAudioAnno(docView.Document);
             if (options.toggleTarget && (!options.didMove || docView.Document.hidden)) docView.Document.hidden = !docView.Document.hidden;
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index fda505420..c237a75de 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,4 +1,3 @@
-/* eslint-disable import/no-mutable-exports */
 /* eslint-disable no-use-before-define */
 /**
  * The DragManager handles all dragging interactions that occur entirely within Dash (as opposed to external drag operations from the file system, etc)
@@ -23,13 +22,14 @@ import { DocData } from '../../fields/DocSymbols';
 import { List } from '../../fields/List';
 import { PrefetchProxy } from '../../fields/Proxy';
 import { ScriptField } from '../../fields/ScriptField';
-import { ScriptCast } from '../../fields/Types';
+import { ScriptCast, StrCast } from '../../fields/Types';
 import { Docs } from '../documents/Documents';
 import { DocumentView } from '../views/nodes/DocumentView';
 import { dropActionType } from './DropActionTypes';
 import { SnappingManager } from './SnappingManager';
 import { UndoManager } from './UndoManager';
 
+// eslint-disable-next-line @typescript-eslint/no-var-requires
 const { contextMenuZindex } = require('../views/global/globalCssVariables.module.scss'); // prettier-ignore
 
 /**
@@ -70,6 +70,7 @@ export function SetupDrag(_reference: React.RefObject<HTMLElement>, docFunc: ()
     return onItemDown;
 }
 
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace DragManager {
     export const dragClassName = 'collectionFreeFormDocumentView-container';
     let dragDiv: HTMLDivElement;
@@ -78,7 +79,7 @@ export namespace DragManager {
     export let CompleteWindowDrag: Opt<(aborted: boolean) => void>;
     export let AbortDrag: () => void = emptyFunction;
     export const docsBeingDragged: Doc[] = observable([]);
-    export let DocDragData: DocumentDragData | undefined;
+    export let DraggedDocs: Doc[] | undefined;
 
     export function Root() {
         const root = document.getElementById('root');
@@ -118,7 +119,7 @@ export namespace DragManager {
 
     // event called when the drag operation has completed (aborted or completed a drop) -- this will be after any drop event has been generated
     export class DragCompleteEvent {
-        constructor(aborted: boolean, dragData: { [id: string]: any }) {
+        constructor(aborted: boolean, dragData: DocumentDragData | AnchorAnnoDragData | LinkDragData | ColumnDragData) {
             this.aborted = aborted;
             this.docDragData = dragData instanceof DocumentDragData ? dragData : undefined;
             this.annoDragData = dragData instanceof AnchorAnnoDragData ? dragData : undefined;
@@ -167,6 +168,9 @@ export namespace DragManager {
         linkSourceGetAnchor: () => Doc;
         linkSourceDoc?: Doc;
         linkDragView: DocumentView;
+        get canEmbed() {
+            return true;
+        }
     }
     export class ColumnDragData {
         // constructor(colKey: SchemaHeaderField) {
@@ -177,6 +181,9 @@ export namespace DragManager {
             this.colIndex = colIndex;
         }
         colIndex: number;
+        get canEmbed() {
+            return true;
+        }
     }
     // used by PDFs,Text,Image,Video,Web to conditionally (if the drop completes) create a text annotation when dragging the annotate button from the AnchorMenu when a text/region selection has been made.
     // this is pretty clunky and should be rethought out using linkDrag or DocumentDrag
@@ -191,6 +198,9 @@ export namespace DragManager {
         offset: number[];
         dropAction?: dropActionType;
         userDropAction?: dropActionType;
+        get canEmbed() {
+            return true;
+        }
     }
 
     const defaultPreDropFunc = (e: Event, de: DragManager.DropEvent, targetAction: dropActionType) => {
@@ -208,7 +218,7 @@ export namespace DragManager {
         const handler = (e: Event) => dropFunc(e, (e as CustomEvent<DropEvent>).detail);
         const preDropHandler = (e: Event) => {
             const de = (e as CustomEvent<DropEvent>).detail;
-            (preDropFunc ?? defaultPreDropFunc)(e, de, doc.dropAction as any as dropActionType);
+            (preDropFunc ?? defaultPreDropFunc)(e, de, StrCast(doc.dropAction) as dropActionType);
         };
         element.addEventListener('dashOnDrop', handler);
         element.addEventListener('dashPreDrop', preDropHandler);
@@ -220,8 +230,8 @@ export namespace DragManager {
     }
 
     // drag a document and drop it (or make an embed/copy on drop)
-    export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions, onDropCompleted?: (e?: DragCompleteEvent) => any) {
-        const addAudioTag = (dropDoc: any) => {
+    export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions, onDropCompleted?: (e?: DragCompleteEvent) => unknown) {
+        const addAudioTag = (dropDoc: Doc) => {
             dropDoc && !dropDoc.author_date && (dropDoc.author_date = new DateField());
             dropDoc instanceof Doc && CreateLinkToActiveAudio(() => dropDoc);
             return dropDoc;
@@ -236,7 +246,7 @@ export namespace DragManager {
                     await Promise.all(
                         dragData.draggedDocuments.map(async d =>
                             !dragData.isDocDecorationMove && !dragData.userDropAction && ScriptCast(d.onDragStart)
-                                ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result)
+                                ? addAudioTag(ScriptCast(d.onDragStart).script.run({ this: d }).result as Doc)
                                 : docDragData.dropAction === dropActionType.embed
                                   ? Doc.BestEmbedding(d)
                                   : docDragData.dropAction === dropActionType.add
@@ -249,7 +259,7 @@ export namespace DragManager {
                         )
                     )
                 ).filter(d => d);
-                ![dropActionType.same, dropActionType.proto].includes(docDragData.dropAction as any) &&
+                ![dropActionType.same, dropActionType.proto].includes(StrCast(docDragData.dropAction) as dropActionType) &&
                     docDragData.droppedDocuments
                         // .filter(drop => !drop.dragOnlyWithinContainer || ['embed', 'copy'].includes(docDragData.dropAction as any))
                         .forEach((drop: Doc, i: number) => {
@@ -376,9 +386,18 @@ export namespace DragManager {
         options?.dragComplete?.(complete);
         endDrag?.();
     }
-    export function StartDrag(elesIn: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void, dragUndoName?: string) {
-        if (dragData.dropAction === 'none' || SnappingManager.ExploreMode) return;
-        DocDragData = dragData as DocumentDragData;
+    export function StartDrag(
+        elesIn: HTMLElement[],
+        dragData: DocumentDragData | LinkDragData | ColumnDragData | AnchorAnnoDragData,
+        downX: number,
+        downY: number,
+        options?: DragOptions,
+        finishDrag?: (dropData: DragCompleteEvent) => void,
+        dragUndoName?: string
+    ) {
+        if (SnappingManager.ExploreMode) return;
+        const docDragData = dragData instanceof DocumentDragData ? dragData : undefined;
+        DraggedDocs = docDragData?.draggedDocuments;
         const batch = UndoManager.StartBatch(dragUndoName ?? 'document drag');
         const eles = elesIn.filter(e => e);
         SnappingManager.SetCanEmbed(dragData.canEmbed || false);
@@ -437,8 +456,9 @@ export namespace DragManager {
                 next && children.push(...Array.from(next.children));
                 if (next) {
                     ['marker-start', 'marker-mid', 'marker-end'].forEach(field => {
-                        if (next.localName.startsWith('path') && (next.attributes as any)[field]) {
-                            next.setAttribute(field, (next.attributes as any)[field].value.replace('#', '#X'));
+                        if (next.localName.startsWith('path')) {
+                            const item = next.attributes.getNamedItem(field);
+                            item && next.setAttribute(field, item.value.replace('#', '#X'));
                         }
                     });
                     if (next.localName.startsWith('marker')) {
@@ -495,7 +515,7 @@ export namespace DragManager {
                     .map((pb, i) => pb.getContext('2d')!.drawImage(pdfBoxSrc[i], 0, 0));
             }
             [dragElement, ...Array.from(dragElement.getElementsByTagName('*'))]
-                .map(dele => (dele as any).style)
+                .map(dele => (dele as HTMLElement)?.style)
                 .forEach(style => {
                     style && (style.pointerEvents = 'none');
                 });
@@ -536,34 +556,35 @@ export namespace DragManager {
         const yFromBottom = elesCont.bottom - downY;
         let scrollAwaiter: Opt<NodeJS.Timeout>;
 
-        let startWindowDragTimer: any;
+        let startWindowDragTimer: NodeJS.Timeout | undefined;
         const moveHandler = (e: PointerEvent) => {
             e.preventDefault(); // required or dragging text menu link item ends up dragging the link button as native drag/drop
-            if (dragData instanceof DocumentDragData) {
-                dragData.userDropAction = e.ctrlKey && e.altKey ? dropActionType.copy : e.shiftKey ? dropActionType.move : e.ctrlKey ? dropActionType.embed : dragData.defaultDropAction;
-            }
-            if (['lm_tab', 'lm_title_wrap', 'lm_tabs', 'lm_header'].includes(typeof (e.target as any).className === 'string' ? (e.target as any)?.className : '') && dragData.draggedDocuments.length === 1) {
-                if (!startWindowDragTimer) {
-                    startWindowDragTimer = setTimeout(async () => {
-                        startWindowDragTimer = undefined;
-                        dragData.dropAction = dragData.userDropAction || 'same';
-                        AbortDrag();
-                        await finishDrag?.(new DragCompleteEvent(true, dragData));
-                        DragManager.StartWindowDrag?.(e, dragData.droppedDocuments, aborted => {
-                            if (!aborted && (dragData.dropAction === 'move' || dragData.dropAction === 'same')) {
-                                dragData.removeDocument?.(dragData.draggedDocuments[0]);
-                            }
-                        });
-                    }, 500);
+            if (docDragData) {
+                docDragData.userDropAction = e.ctrlKey && e.altKey ? dropActionType.copy : e.shiftKey ? dropActionType.move : e.ctrlKey ? dropActionType.embed : docDragData.defaultDropAction;
+                const targClassName = e.target instanceof HTMLElement && typeof e.target.className === 'string' ? e.target.className : '';
+                if (['lm_tab', 'lm_title_wrap', 'lm_tabs', 'lm_header'].includes(targClassName) && docDragData.draggedDocuments.length === 1) {
+                    if (!startWindowDragTimer) {
+                        startWindowDragTimer = setTimeout(async () => {
+                            startWindowDragTimer = undefined;
+                            docDragData.dropAction = docDragData.userDropAction || dropActionType.same;
+                            AbortDrag();
+                            await finishDrag?.(new DragCompleteEvent(true, docDragData));
+                            DragManager.StartWindowDrag?.(e, docDragData.droppedDocuments, aborted => {
+                                if (!aborted && (docDragData?.dropAction === 'move' || docDragData?.dropAction === 'same')) {
+                                    docDragData.removeDocument?.(docDragData?.draggedDocuments[0]);
+                                }
+                            });
+                        }, 500);
+                    }
+                } else {
+                    clearTimeout(startWindowDragTimer);
+                    startWindowDragTimer = undefined;
                 }
-            } else {
-                clearTimeout(startWindowDragTimer);
-                startWindowDragTimer = undefined;
             }
 
             const target = document.elementFromPoint(e.x, e.y);
 
-            if (target && !Doc.UserDoc()._noAutoscroll && !options?.noAutoscroll && !dragData.draggedDocuments?.some((d: any) => d._freeform_noAutoPan)) {
+            if (target && !Doc.UserDoc()._noAutoscroll && !options?.noAutoscroll && !(docDragData?.draggedDocuments as Doc[])?.some(d => d._freeform_noAutoPan)) {
                 const autoScrollHandler = () => {
                     target.dispatchEvent(
                         new CustomEvent<React.DragEvent>('dashDragMovePause', {
@@ -587,7 +608,7 @@ export namespace DragManager {
                                 screenX: e.screenX,
                                 screenY: e.screenY,
                                 detail: e.detail,
-                                view: e.view ? e.view : (new Window() as any),
+                                view: { ...(e.view ?? new Window()), styleMedia: { type: '', matchMedium: () => false } }, // bcz: Ugh.. this looks wrong
                                 nativeEvent: new DragEvent('dashDragMovePause'),
                                 currentTarget: target,
                                 target: target,
@@ -596,10 +617,10 @@ export namespace DragManager {
                                 defaultPrevented: true,
                                 eventPhase: e.eventPhase,
                                 isTrusted: true,
-                                preventDefault: () => 'not implemented for this event' && false,
-                                isDefaultPrevented: () => 'not implemented for this event' && false,
-                                stopPropagation: () => 'not implemented for this event' && false,
-                                isPropagationStopped: () => 'not implemented for this event' && false,
+                                preventDefault: () => 'not implemented for this event',
+                                isDefaultPrevented: () => false,
+                                stopPropagation: () => 'not implemented for this event',
+                                isPropagationStopped: () => false,
                                 persist: emptyFunction,
                                 timeStamp: e.timeStamp,
                                 type: 'dashDragMovePause',
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 0314af06b..eb2011b77 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -26,9 +26,10 @@ function makeTemplate(doc: Doc, first: boolean = true): boolean {
     if (layoutDoc.layout instanceof Doc) {
         return true; // its already a template
     }
-    const layout = StrCast(layoutDoc.layout).match(/fieldKey={'[^']*'}/)![0];
-    const fieldKey = layout.replace("fieldKey={'", '').replace(/'}$/, '');
-    const docs = DocListCast(layoutDoc[fieldKey]);
+    const layout = StrCast(layoutDoc.layout).match(/fieldKey={'[^']*'}/)?.[0];
+    const fieldKey = layout?.replace("fieldKey={'", '').replace(/'}$/, '');
+    const docData = fieldKey ? layoutDoc[fieldKey] : undefined;
+    const docs = DocListCast(docData);
     let isTemplate = false;
     docs.forEach(d => {
         if (!StrCast(d.title).startsWith('-')) {
@@ -40,7 +41,7 @@ function makeTemplate(doc: Doc, first: boolean = true): boolean {
     if (first && !docs.length) {
         // bcz: feels hacky : if the root level document has items, it's not a field template
         isTemplate = Doc.MakeMetadataFieldTemplate(doc, layoutDoc[DocData], true) || isTemplate;
-    } else if (layoutDoc[fieldKey] instanceof RichTextField || layoutDoc[fieldKey] instanceof ImageField) {
+    } else if (docData instanceof RichTextField || docData instanceof ImageField) {
         if (!StrCast(layoutDoc.title).startsWith('-')) {
             isTemplate = Doc.MakeMetadataFieldTemplate(layoutDoc, layoutDoc[DocData], true);
         }
@@ -110,8 +111,8 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) {
 }
 ScriptingGlobals.add(
     // eslint-disable-next-line prefer-arrow-callback
-    function convertToButtons(dragData: any) {
-        convertDropDataToButtons(dragData as DragManager.DocumentDragData);
+    function convertToButtons(dragData: DragManager.DocumentDragData) {
+        convertDropDataToButtons(dragData);
     },
     'converts the dropped data to buttons',
     '(dragData: any)'
diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index 5701a22c0..9d0817a06 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -1,8 +1,6 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Button, IconButton, Size, Type } from 'browndash-components';
-import { action, computed, makeObservable, observable } from 'mobx';
+import { action, computed, makeObservable, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import Select from 'react-select';
@@ -31,7 +29,7 @@ export interface UserOptions {
 }
 
 @observer
-export class GroupManager extends ObservableReactComponent<{}> {
+export class GroupManager extends ObservableReactComponent<object> {
     // eslint-disable-next-line no-use-before-define
     static Instance: GroupManager;
     @observable isOpen: boolean = false; // whether the GroupManager is to be displayed or not.
@@ -44,7 +42,7 @@ export class GroupManager extends ObservableReactComponent<{}> {
     @observable private buttonColour: '#979797' | 'black' = '#979797';
     @observable private groupSort: 'ascending' | 'descending' | 'none' = 'none';
 
-    constructor(props: Readonly<{}>) {
+    constructor(props: Readonly<object>) {
         super(props);
         makeObservable(this);
         GroupManager.Instance = this;
@@ -226,15 +224,6 @@ export class GroupManager extends ObservableReactComponent<{}> {
         }
     }
 
-    /**
-     * Handles changes in the users selected in the "Select users" dropdown.
-     * @param selectedOptions
-     */
-    @action
-    handleChange = (selectedOptions: any) => {
-        this.selectedUsers = selectedOptions as UserOptions[];
-    };
-
     /**
      * Creates the group when the enter key has been pressed (when in the input).
      * @param e
@@ -309,7 +298,6 @@ export class GroupManager extends ObservableReactComponent<{}> {
                     <input
                         ref={this.inputRef}
                         onKeyDown={this.handleKeyDown}
-                        // eslint-disable-next-line jsx-a11y/no-autofocus
                         autoFocus
                         type="text"
                         placeholder="Group name"
@@ -323,7 +311,9 @@ export class GroupManager extends ObservableReactComponent<{}> {
                         className="select-users"
                         isMulti
                         options={this.options}
-                        onChange={this.handleChange}
+                        onChange={selectedOptions => {
+                            runInAction(() => (this.selectedUsers = Array.from(selectedOptions)));
+                        }}
                         placeholder="Select users"
                         value={this.selectedUsers}
                         closeMenuOnSelect={false}
diff --git a/src/client/util/GroupMemberView.tsx b/src/client/util/GroupMemberView.tsx
index da9e1aa28..88d73d742 100644
--- a/src/client/util/GroupMemberView.tsx
+++ b/src/client/util/GroupMemberView.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Button, IconButton, Size, Type } from 'browndash-components';
 import { action, observable } from 'mobx';
diff --git a/src/client/util/History.ts b/src/client/util/History.ts
index 52d0223d5..067c28c6b 100644
--- a/src/client/util/History.ts
+++ b/src/client/util/History.ts
@@ -10,6 +10,7 @@ import { OmitKeys, ClientUtils } from '../../ClientUtils';
 import { DocServer } from '../DocServer';
 import { DashboardView } from '../views/DashboardView';
 
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace HistoryUtil {
     export interface DocInitializerList {
         [key: string]: string | number;
@@ -85,7 +86,7 @@ export namespace HistoryUtil {
     const parsers: { [type: string]: (pathname: string[], opts: qs.ParsedQuery) => ParsedUrl | undefined } = {};
     const stringifiers: { [type: string]: (state: ParsedUrl) => string } = {};
 
-    type ParserValue = true | 'none' | 'json' | ((value: string) => any);
+    type ParserValue = true | 'none' | 'json' | ((value: string) => string | null | (string | null)[]);
 
     type Parser = {
         [key: string]: ParserValue;
@@ -106,7 +107,7 @@ export namespace HistoryUtil {
             return value;
         }
         parsers[type] = (pathname, opts) => {
-            const current: any = { type };
+            const current: DocUrl & { [key: string]: null | (string | null)[] | string } = { type: 'doc', docId: '' };
             for (const required in requiredFields) {
                 if (!(required in opts)) {
                     return undefined;
@@ -148,7 +149,7 @@ export namespace HistoryUtil {
                 path = customStringifier(state, path);
             }
             const queryObj = OmitKeys(state, keys).extract;
-            const query: any = {};
+            const query: { [key: string]: string | null } = {};
             Object.keys(queryObj).forEach(key => {
                 query[key] = queryObj[key] === null ? null : JSON.stringify(queryObj[key]);
             });
diff --git a/src/client/util/Import & Export/ImageUtils.ts b/src/client/util/Import & Export/ImageUtils.ts
index 8d4eefa7e..266e05f08 100644
--- a/src/client/util/Import & Export/ImageUtils.ts	
+++ b/src/client/util/Import & Export/ImageUtils.ts	
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-namespace */
 import { ClientUtils } from '../../../ClientUtils';
 import { Doc } from '../../../fields/Doc';
 import { DocData } from '../../../fields/DocSymbols';
diff --git a/src/client/util/Import & Export/ImportMetadataEntry.tsx b/src/client/util/Import & Export/ImportMetadataEntry.tsx
index db1e3d6cd..63dedf820 100644
--- a/src/client/util/Import & Export/ImportMetadataEntry.tsx	
+++ b/src/client/util/Import & Export/ImportMetadataEntry.tsx	
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 /* eslint-disable no-use-before-define */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed } from 'mobx';
diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx
index a07550e09..f3ede596d 100644
--- a/src/client/util/InteractionUtils.tsx
+++ b/src/client/util/InteractionUtils.tsx
@@ -1,8 +1,10 @@
+import { Property } from 'csstype';
 import * as React from 'react';
 import { Utils } from '../../Utils';
 import { Gestures } from '../../pen-gestures/GestureTypes';
 import './InteractionUtils.scss';
 
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace InteractionUtils {
     export const MOUSETYPE = 'mouse';
     export const TOUCHTYPE = 'touch';
@@ -11,7 +13,7 @@ export namespace InteractionUtils {
 
     const ERASER_BUTTON = 5;
 
-    export function makePolygon(shape: string, points: { X: number; Y: number }[]) {
+    export function makePolygon(shape: Gestures, points: { X: number; Y: number }[]) {
         // if arrow/line/circle, the two end points should be the starting and the ending point
         let left = points[0].X;
         let top = points[0].Y;
@@ -19,7 +21,7 @@ export namespace InteractionUtils {
         let bottom = points[1].Y;
         if (points.length > 1 && points[points.length - 1].X === points[0].X && points[points.length - 1].Y + 1 === points[0].Y) {
             // pointer is up (first and last points are the same)
-            if (![Gestures.Arrow, Gestures.Line, Gestures.Circle].includes(shape as any as Gestures)) {
+            if (![Gestures.Arrow, Gestures.Line, Gestures.Circle].includes(shape)) {
                 // otherwise take max and min
                 const xs = points.map(p => p.X);
                 const ys = points.map(p => p.Y);
@@ -98,8 +100,8 @@ export namespace InteractionUtils {
         color: string,
         width: number,
         strokeWidth: number,
-        lineJoin: string,
-        strokeLineCap: string,
+        lineJoin: Property.StrokeLinejoin,
+        strokeLineCap: Property.StrokeLinecap,
         bezier: string,
         fill: string,
         arrowStart: string,
@@ -108,8 +110,8 @@ export namespace InteractionUtils {
         dash: string | undefined,
         scalexIn: number,
         scaleyIn: number,
-        shape: string,
-        pevents: string,
+        shape: Gestures,
+        pevents: Property.PointerEvents,
         opacity: number,
         nodefs: boolean,
         downHdlr?: (e: React.PointerEvent) => void,
@@ -154,7 +156,7 @@ export namespace InteractionUtils {
                             <marker id={`arrowStart${defGuid}`} markerUnits="userSpaceOnUse" orient="auto" overflow="visible" refX={markerStrokeWidth * (arrowLengthFactor - arrowNotchFactor)} refY={0} markerWidth="10" markerHeight="7">
                                 <polygon
                                     style={{ stroke: color }}
-                                    strokeLinejoin={lineJoin as any}
+                                    strokeLinejoin={lineJoin as 'inherit' | 'round' | 'bevel' | 'miter'}
                                     strokeWidth={(markerStrokeWidth * 2) / 3}
                                     points={`${arrowLengthFactor * markerStrokeWidth} ${-markerStrokeWidth * arrowWidthFactor}, ${markerStrokeWidth * (arrowLengthFactor - arrowNotchFactor)} 0, ${arrowLengthFactor * markerStrokeWidth} ${
                                         markerStrokeWidth * arrowWidthFactor
@@ -166,7 +168,7 @@ export namespace InteractionUtils {
                             <marker id={`arrowEnd${defGuid}`} markerUnits="userSpaceOnUse" orient="auto" overflow="visible" refX={markerStrokeWidth * arrowNotchFactor} refY={0} markerWidth="10" markerHeight="7">
                                 <polygon
                                     style={{ stroke: color }}
-                                    strokeLinejoin={lineJoin as any}
+                                    strokeLinejoin={lineJoin as 'inherit' | 'miter' | 'round' | 'bevel'}
                                     strokeWidth={(markerStrokeWidth * 2) / 3}
                                     points={`0 ${-markerStrokeWidth * arrowWidthFactor}, ${markerStrokeWidth * arrowNotchFactor} 0, 0 ${markerStrokeWidth * arrowWidthFactor}, ${arrowLengthFactor * markerStrokeWidth} 0`}
                                 />
@@ -184,10 +186,10 @@ export namespace InteractionUtils {
                         filter: mask ? `url(#mask${defGuid})` : undefined,
                         opacity: 1.0,
                         // opacity: strokeWidth !== width ? 0.5 : undefined,
-                        pointerEvents: (pevents as any) === 'all' ? 'visiblepainted' : (pevents as any),
+                        pointerEvents: pevents === 'all' ? 'visiblePainted' : pevents,
                         stroke: color ?? 'rgb(0, 0, 0)',
                         strokeWidth,
-                        strokeLinecap: strokeLineCap as any,
+                        strokeLinecap: strokeLineCap,
                         strokeDasharray: dashArray,
                         transition: 'inherit',
                     }}
diff --git a/src/client/util/LinkFollower.ts b/src/client/util/LinkFollower.ts
index 9a0edcfec..0a3a0ba49 100644
--- a/src/client/util/LinkFollower.ts
+++ b/src/client/util/LinkFollower.ts
@@ -50,7 +50,7 @@ export class LinkFollower {
         const backLinks = linkDocs.filter(l => isAnchor(sourceDoc, l.link_anchor_2 as Doc)); // link docs where 'sourceDoc' is link_anchor_2
         const fwdLinkWithoutTargetView = fwdLinks.find(l => !getView(DocCast(l.link_anchor_2)));
         const backLinkWithoutTargetView = backLinks.find(l => !getView(DocCast(l.link_anchor_1)));
-        const linkWithoutTargetDoc = traverseBacklink === undefined ? fwdLinkWithoutTargetView ?? backLinkWithoutTargetView : traverseBacklink ? backLinkWithoutTargetView : fwdLinkWithoutTargetView;
+        const linkWithoutTargetDoc = traverseBacklink === undefined ? (fwdLinkWithoutTargetView ?? backLinkWithoutTargetView) : traverseBacklink ? backLinkWithoutTargetView : fwdLinkWithoutTargetView;
         const linkDocList = linkWithoutTargetDoc && !sourceDoc.followAllLinks ? [linkWithoutTargetDoc] : traverseBacklink === undefined ? fwdLinks.concat(backLinks) : traverseBacklink ? backLinks : fwdLinks;
         const followLinks = sourceDoc.followLinkToggle || sourceDoc.followAllLinks ? linkDocList : linkDocList.slice(0, 1);
         let count = 0;
@@ -82,7 +82,7 @@ export class LinkFollower {
                         willZoomCentered: BoolCast(srcAnchor.followLinkZoom, false),
                         zoomTime: NumCast(srcAnchor.followLinkTransitionTime, 500),
                         zoomScale: Cast(srcAnchor.followLinkZoomScale, 'number', null),
-                        easeFunc: StrCast(srcAnchor.followLinkEase, 'ease') as any,
+                        easeFunc: StrCast(srcAnchor.followLinkEase, 'ease') as 'ease' | 'linear',
                         openLocation: StrCast(srcAnchor.followLinkLocation, OpenWhere.lightbox) as OpenWhere,
                         effect: srcAnchor,
                         zoomTextSelections: BoolCast(srcAnchor.followLinkZoomText),
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index 56d5dce4e..e11482572 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -31,13 +31,13 @@ export class LinkManager {
     @observable public currentLink: Opt<Doc> = undefined;
     @observable public currentLinkAnchor: Opt<Doc> = undefined;
     public static get Instance(): LinkManager {
-        return Doc.UserDoc() ? LinkManager._instance ?? new LinkManager() : (undefined as any as LinkManager);
+        return Doc.UserDoc() ? (LinkManager._instance ?? new LinkManager()) : (undefined as unknown as LinkManager);
     }
 
     public static Links(doc: Doc | undefined) {
         return doc ? LinkManager.Instance.getAllRelatedLinks(doc) : [];
     }
-    public addLinkDB = async (linkDb: any) => {
+    public addLinkDB = async (linkDb: Doc) => {
         await Promise.all(
             ((await DocListCastAsync(linkDb.data)) ?? []).map(link =>
                 // makes sure link anchors are loaded to avoid incremental updates to computedFns in LinkManager
@@ -95,35 +95,24 @@ export class LinkManager {
         const watchUserLinkDB = (userLinkDBDoc: Doc) => {
             const toRealField = (field: FieldType) => (field instanceof ProxyField ? field.value : field); // see List.ts.  data structure is not a simple list of Docs, but a list of ProxyField/Fields
             if (userLinkDBDoc.data) {
+                // observe pushes/splices on a user link DB 'data' field (should only happen for local changes)
                 observe(
-                    userLinkDBDoc.data,
+                    userLinkDBDoc.data as unknown as Doc[],
                     change => {
-                        // observe pushes/splices on a user link DB 'data' field (should only happen for local changes)
-                        switch (change.type as any) {
+                        switch (change.type) {
                             case 'splice':
-                                (change as any).added.forEach((link: any) => addLinkToDoc(toRealField(link)));
-                                (change as any).removed.forEach((link: any) => remLinkFromDoc(toRealField(link)));
+                                change.added.forEach(link => addLinkToDoc(toRealField(link)));
+                                change.removed.forEach(link => remLinkFromDoc(toRealField(link)));
                                 break;
-                            case 'update': // let oldValue = change.oldValue;
-                            default:
-                        }
-                    },
-                    true
-                );
-                observe(
-                    userLinkDBDoc,
-                    'data', // obsever when a new array of links is assigned as the link DB 'data' field (should happen whenever a remote user adds/removes a link)
-                    change => {
-                        switch (change.type as any) {
                             case 'update':
-                                Promise.all([...((change.oldValue as any as Doc[]) || []), ...((change.newValue as any as Doc[]) || [])]).then(doclist => {
-                                    const oldDocs = doclist.slice(0, ((change.oldValue as any as Doc[]) || []).length);
-                                    const newDocs = doclist.slice(((change.oldValue as any as Doc[]) || []).length, doclist.length);
+                                Promise.all([...((change.oldValue as unknown as Doc[]) || []), ...((change.newValue as unknown as Doc[]) || [])]).then(doclist => {
+                                    const oldDocs = doclist.slice(0, ((change.oldValue as unknown as Doc[]) || []).length);
+                                    const newDocs = doclist.slice(((change.oldValue as unknown as Doc[]) || []).length, doclist.length);
 
                                     const added = newDocs?.filter(link => !(oldDocs || []).includes(link));
                                     const removed = oldDocs?.filter(link => !(newDocs || []).includes(link));
-                                    added?.forEach((link: any) => addLinkToDoc(toRealField(link)));
-                                    removed?.forEach((link: any) => remLinkFromDoc(toRealField(link)));
+                                    added?.forEach(link => addLinkToDoc(toRealField(link)));
+                                    removed?.forEach(link => remLinkFromDoc(toRealField(link)));
                                 });
                                 break;
                             default:
@@ -136,9 +125,9 @@ export class LinkManager {
         observe(
             this.userLinkDBs,
             change => {
-                switch (change.type as any) {
+                switch (change.type) {
                     case 'splice':
-                        (change as any).added.forEach(watchUserLinkDB);
+                        change.added.forEach(watchUserLinkDB);
                         break;
                     case 'update': // let oldValue = change.oldValue;
                     default:
@@ -188,7 +177,7 @@ export class LinkManager {
             return [];
         }
 
-        const dirLinks = Array.from(anchor[DocData][DirectLinks]).filter(l => Doc.GetProto(anchor) === anchor[DocData] || ['1', '2'].includes(LinkManager.anchorIndex(l, anchor) as any));
+        const dirLinks = Array.from(anchor[DocData][DirectLinks]).filter(l => Doc.GetProto(anchor) === anchor[DocData] || ['1', '2'].includes(LinkManager.anchorIndex(l, anchor) as '0' | '1' | '2'));
         const anchorRoot = DocCast(anchor.rootDocument, anchor); // template Doc fields store annotations on the topmost root of a template (not on themselves since the template layout items are only for layout)
         const annos = DocListCast(anchorRoot[Doc.LayoutFieldKey(anchor) + '_annotations']);
         return Array.from(
@@ -283,7 +272,7 @@ export function UPDATE_SERVER_CACHE() {
 
 ScriptingGlobals.add(
     // eslint-disable-next-line prefer-arrow-callback
-    function links(doc: any) {
+    function links(doc: Doc) {
         return new List(LinkManager.Links(doc));
     },
     'returns all the links to the document or its annotations',
diff --git a/src/client/util/ProsemirrorCopy/prompt.js b/src/client/util/ProsemirrorCopy/prompt.js
deleted file mode 100644
index b9068195f..000000000
--- a/src/client/util/ProsemirrorCopy/prompt.js
+++ /dev/null
@@ -1,179 +0,0 @@
-const prefix = "ProseMirror-prompt"
-
-export function openPrompt(options) {
-    let wrapper = document.body.appendChild(document.createElement("div"))
-    wrapper.className = prefix
-    wrapper.style.zIndex = 1000;
-    wrapper.style.width = 250;
-    wrapper.style.textAlign = "center";
-
-    let mouseOutside = e => { if (!wrapper.contains(e.target)) close() }
-    setTimeout(() => window.addEventListener("mousedown", mouseOutside), 50)
-    let close = () => {
-        window.removeEventListener("mousedown", mouseOutside)
-        if (wrapper.parentNode) wrapper.parentNode.removeChild(wrapper)
-    }
-
-    let domFields = []
-    for (let name in options.fields) domFields.push(options.fields[name].render())
-
-    let submitButton = document.createElement("button")
-    submitButton.type = "submit"
-    submitButton.className = prefix + "-submit"
-    submitButton.textContent = "OK"
-    let cancelButton = document.createElement("button")
-    cancelButton.type = "button"
-    cancelButton.className = prefix + "-cancel"
-    cancelButton.textContent = "Cancel"
-    cancelButton.addEventListener("click", close)
-
-    let form = wrapper.appendChild(document.createElement("form"))
-    let title = document.createElement("h5")
-    title.style.marginBottom = 15
-    title.style.marginTop = 10
-    if (options.title) form.appendChild(title).textContent = options.title
-    domFields.forEach(field => {
-        form.appendChild(document.createElement("div")).appendChild(field)
-    })
-    let b = document.createElement("div");
-    b.style.marginTop = 15;
-    let buttons = form.appendChild(b)
-    // buttons.className = prefix + "-buttons"
-    buttons.appendChild(submitButton)
-    buttons.appendChild(document.createTextNode(" "))
-    buttons.appendChild(cancelButton)
-
-    let box = wrapper.getBoundingClientRect()
-    wrapper.style.top = options.flyout_top + "px"
-    wrapper.style.left = options.flyout_left + "px"
-
-    let submit = () => {
-        let params = getValues(options.fields, domFields)
-        if (params) {
-            close()
-            options.callback(params)
-        }
-    }
-
-    form.addEventListener("submit", e => {
-        e.preventDefault()
-        submit()
-    })
-
-    form.addEventListener("keydown", e => {
-        if (e.keyCode == 27) {
-            e.preventDefault()
-            close()
-        } else if (e.keyCode == 13 && !(e.ctrlKey || e.metaKey || e.shiftKey)) {
-            e.preventDefault()
-            submit()
-        } else if (e.keyCode == 9) {
-            window.setTimeout(() => {
-                if (!wrapper.contains(document.activeElement)) close()
-            }, 500)
-        }
-    })
-
-    let input = form.elements[0]
-    if (input) input.focus()
-}
-
-function getValues(fields, domFields) {
-    let result = Object.create(null), i = 0
-    for (let name in fields) {
-        let field = fields[name], dom = domFields[i++]
-        let value = field.read(dom), bad = field.validate(value)
-        if (bad) {
-            reportInvalid(dom, bad)
-            return null
-        }
-        result[name] = field.clean(value)
-    }
-    return result
-}
-
-function reportInvalid(dom, message) {
-    // FIXME this is awful and needs a lot more work
-    let parent = dom.parentNode
-    let msg = parent.appendChild(document.createElement("div"))
-    msg.style.left = (dom.offsetLeft + dom.offsetWidth + 2) + "px"
-    msg.style.top = (dom.offsetTop - 5) + "px"
-    msg.className = "ProseMirror-invalid"
-    msg.textContent = message
-    setTimeout(() => parent.removeChild(msg), 1500)
-}
-
-// ::- The type of field that `FieldPrompt` expects to be passed to it.
-export class Field {
-    // :: (Object)
-    // Create a field with the given options. Options support by all
-    // field types are:
-    //
-    // **`value`**`: ?any`
-    //   : The starting value for the field.
-    //
-    // **`label`**`: string`
-    //   : The label for the field.
-    //
-    // **`required`**`: ?bool`
-    //   : Whether the field is required.
-    //
-    // **`validate`**`: ?(any) → ?string`
-    //   : A function to validate the given value. Should return an
-    //     error message if it is not valid.
-    constructor(options) { this.options = options }
-
-    // render:: (state: EditorState, props: Object) → dom.Node
-    // Render the field to the DOM. Should be implemented by all subclasses.
-
-    // :: (dom.Node) → any
-    // Read the field's value from its DOM node.
-    read(dom) { return dom.value }
-
-    // :: (any) → ?string
-    // A field-type-specific validation function.
-    validateType(_value) { }
-
-    validate(value) {
-        if (!value && this.options.required)
-            return "Required field"
-        return this.validateType(value) || (this.options.validate && this.options.validate(value))
-    }
-
-    clean(value) {
-        return this.options.clean ? this.options.clean(value) : value
-    }
-}
-
-// ::- A field class for single-line text fields.
-export class TextField extends Field {
-    render() {
-        let input = document.createElement("input")
-        input.type = "text"
-        input.placeholder = this.options.label
-        input.value = this.options.value || ""
-        input.autocomplete = "off"
-        input.style.marginBottom = 4
-        input.style.border = "1px solid black"
-        input.style.padding = "4px 4px"
-        return input
-    }
-}
-
-
-// ::- A field class for dropdown fields based on a plain `<select>`
-// tag. Expects an option `options`, which should be an array of
-// `{value: string, label: string}` objects, or a function taking a
-// `ProseMirror` instance and returning such an array.
-export class SelectField extends Field {
-    render() {
-        let select = document.createElement("select")
-        this.options.options.forEach(o => {
-            let opt = select.appendChild(document.createElement("option"))
-            opt.value = o.value
-            opt.selected = o.value == this.options.value
-            opt.label = o.label
-        })
-        return select
-    }
-}
diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx
index a07ad2047..a01b64eda 100644
--- a/src/client/util/RTFMarkup.tsx
+++ b/src/client/util/RTFMarkup.tsx
@@ -5,7 +5,7 @@ import { MainViewModal } from '../views/MainViewModal';
 import { SnappingManager } from './SnappingManager';
 
 @observer
-export class RTFMarkup extends React.Component<{}> {
+export class RTFMarkup extends React.Component<object> {
     // eslint-disable-next-line no-use-before-define
     static Instance: RTFMarkup;
     @observable private isOpen = false; // whether the SharingManager modal is open or not
@@ -14,7 +14,7 @@ export class RTFMarkup extends React.Component<{}> {
         this.isOpen = status;
     });
 
-    constructor(props: {}) {
+    constructor(props: object) {
         super(props);
         makeObservable(this);
         RTFMarkup.Instance = this;
diff --git a/src/client/util/ReplayMovements.ts b/src/client/util/ReplayMovements.ts
index c5afe549c..62a09a8bc 100644
--- a/src/client/util/ReplayMovements.ts
+++ b/src/client/util/ReplayMovements.ts
@@ -7,11 +7,12 @@ import { SnappingManager } from './SnappingManager';
 import { Movement, Presentation } from './TrackMovements';
 import { ViewBoxInterface } from '../views/ViewBoxInterface';
 import { StrCast } from '../../fields/Types';
+import { FieldViewProps } from '../views/nodes/FieldView';
 
 export class ReplayMovements {
     private timers: NodeJS.Timeout[] | null;
     private videoBoxDisposeFunc: IReactionDisposer | null;
-    private videoBox: ViewBoxInterface<any> | null;
+    private videoBox: ViewBoxInterface<FieldViewProps> | null;
     private isPlaying: boolean;
 
     // create static instance and getter for global use
@@ -62,7 +63,7 @@ export class ReplayMovements {
         this.timers?.map(timer => clearTimeout(timer));
     };
 
-    setVideoBox = async (videoBox: ViewBoxInterface<any>) => {
+    setVideoBox = async (videoBox: ViewBoxInterface<FieldViewProps>) => {
         if (this.videoBox !== null) {
             console.warn('setVideoBox on already videoBox');
         }
@@ -147,7 +148,7 @@ export class ReplayMovements {
         // generate a set of all unique docIds
         const docIdtoFirstMove = new Map<Doc, Movement>();
         movements.forEach(move => {
-            if (!docIdtoFirstMove.has(move.doc)) docIdtoFirstMove.set(move.doc, move);
+            if (!docIdtoFirstMove.has(move.doc as Doc)) docIdtoFirstMove.set(move.doc as Doc, move);
         });
         return docIdtoFirstMove;
     };
@@ -175,8 +176,8 @@ export class ReplayMovements {
         const handleFirstMovements = () => {
             // if the first movement is a closed tab, open it
             const firstMovement = filteredMovements[0];
-            const isClosed = this.getCollectionFFView(firstMovement.doc) === undefined;
-            if (isClosed) this.openTab(firstMovement.doc);
+            const isClosed = this.getCollectionFFView(firstMovement.doc as Doc) === undefined;
+            if (isClosed) this.openTab(firstMovement.doc as Doc);
 
             // for the open tabs, set it to the first move
             const docIdtoFirstMove = this.getFirstMovements(filteredMovements);
@@ -192,12 +193,12 @@ export class ReplayMovements {
             const timeDiff = movement.time - timeViewed * 1000;
 
             return setTimeout(() => {
-                const collectionFFView = this.getCollectionFFView(movement.doc);
+                const collectionFFView = this.getCollectionFFView(movement.doc as Doc);
                 if (collectionFFView) {
                     this.zoomAndPan(movement, collectionFFView);
                 } else {
                     // tab wasn't open - open it and play the movement
-                    const openedColFFView = this.openTab(movement.doc);
+                    const openedColFFView = this.openTab(movement.doc as Doc);
                     openedColFFView && this.zoomAndPan(movement, openedColFFView);
                 }
 
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index 6948469cc..133f8f2ce 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -1,10 +1,6 @@
-/* eslint-disable import/no-unresolved */
-/* eslint-disable import/no-webpack-loader-syntax */
 // export const ts = (window as any).ts;
-// // @ts-ignore
 // import * as typescriptlib from '!!raw-loader!../../../node_modules/typescript/lib/lib.d.ts'
 // import * as typescriptes5 from '!!raw-loader!../../../node_modules/typescript/lib/lib.es5.d.ts'
-// eslint-disable-next-line node/no-unpublished-import
 import * as typescriptlib from '!!raw-loader!./type_decls.d';
 import * as ts from 'typescript';
 import { Doc, FieldType } from '../../fields/Doc';
@@ -16,13 +12,13 @@ export { ts };
 
 export interface ScriptSuccess {
     success: true;
-    result: any;
+    result: unknown;
 }
 
 export interface ScriptError {
     success: false;
-    error: any;
-    result: any;
+    error: unknown;
+    result: unknown;
 }
 
 export type ScriptResult = ScriptSuccess | ScriptError;
@@ -34,12 +30,12 @@ export interface CompiledScript {
     readonly originalScript: string;
     // eslint-disable-next-line no-use-before-define
     readonly options: Readonly<ScriptOptions>;
-    run(args?: { [name: string]: any }, onError?: (res: any) => void, errorVal?: any): ScriptResult;
+    run(args?: { [name: string]: unknown }, onError?: (res: string) => void, errorVal?: unknown): ScriptResult;
 }
 
 export interface CompileError {
     compiled: false;
-    errors: any[];
+    errors: ts.Diagnostic[];
 }
 
 export type CompileResult = CompiledScript | CompileError;
@@ -51,7 +47,7 @@ export function isCompileError(toBeDetermined: CompileResult): toBeDetermined is
 }
 
 // eslint-disable-next-line no-use-before-define
-function Run(script: string | undefined, customParams: string[], diagnostics: any[], originalScript: string, options: ScriptOptions): CompileResult {
+function Run(script: string | undefined, customParams: string[], diagnostics: ts.Diagnostic[], originalScript: string, options: ScriptOptions): CompileResult {
     const errors = diagnostics.filter(diag => diag.category === ts.DiagnosticCategory.Error);
     if ((options.typecheck !== false && errors.length) || !script) {
         return { compiled: false, errors };
@@ -74,8 +70,8 @@ function Run(script: string | undefined, customParams: string[], diagnostics: an
     if (!compiledFunction) return { compiled: false, errors };
     const { capturedVariables = {} } = options;
     // eslint-disable-next-line default-param-last
-    const run = (args: { [name: string]: any } = {}, onError?: (e: any) => void, errorVal?: any): ScriptResult => {
-        const argsArray: any[] = [];
+    const run = (args: { [name: string]: unknown } = {}, onError?: (e: string) => void, errorVal?: ts.Diagnostic): ScriptResult => {
+        const argsArray: unknown[] = [];
         // eslint-disable-next-line no-restricted-syntax
         for (const name of customParams) {
             if (name !== 'this') {
@@ -94,7 +90,7 @@ function Run(script: string | undefined, customParams: string[], diagnostics: an
             return { success: true, result };
         } catch (error) {
             batch?.end();
-            onError?.(script + ' ' + error);
+            onError?.(script + ' ' + (error as string).toString());
             return { success: false, error, result: errorVal };
         }
     };
@@ -111,7 +107,7 @@ class ScriptingCompilerHost {
     files: File[] = [];
 
     // getSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError?: ((message: string) => void) | undefined, shouldCreateNewSourceFile?: boolean | undefined): ts.SourceFile | undefined {
-    getSourceFile(fileName: string, languageVersion: any /* , onError?: ((message: string) => void) | undefined, shouldCreateNewSourceFile?: boolean | undefined */): any | undefined {
+    getSourceFile(fileName: string, languageVersion: ts.ScriptTarget | ts.CreateSourceFileOptions /* , onError?: ((message: string) => void) | undefined, shouldCreateNewSourceFile?: boolean | undefined */): ts.SourceFile | undefined {
         const contents = this.readFile(fileName);
         if (contents !== undefined) {
             return ts.createSourceFile(fileName, contents, languageVersion, true);
@@ -165,18 +161,19 @@ export interface ScriptOptions {
     requiredType?: string; // does function required a typed return value
     addReturn?: boolean; // does the compiler automatically add a return statement
     params?: { [name: string]: string }; // list of function parameters and their types
-    capturedVariables?: { [name: string]: Doc | number | string | boolean }; // list of captured variables
+    capturedVariables?: { [name: string]: Doc | number | string | boolean | undefined }; // list of captured variables
     typecheck?: boolean; // should the compiler perform typechecking
     editable?: boolean; // can the script edit Docs
     traverser?: TraverserParam;
     transformer?: Transformer; // does the editor display a text label by each document that can be used as a captured document reference
-    globals?: { [name: string]: any };
+    globals?: { [name: string]: unknown };
 }
 
 // function forEachNode(node:ts.Node, fn:(node:any) => void);
 function forEachNode(node: ts.Node, onEnter: Traverser, onExit?: Traverser, indentation = '') {
     return (
         onEnter(node, indentation) ||
+        // eslint-disable-next-line @typescript-eslint/no-explicit-any
         ts.forEachChild(node, (n: any) => {
             forEachNode(n, onEnter, onExit, indentation + '    ');
         }) ||
@@ -187,8 +184,9 @@ function forEachNode(node: ts.Node, onEnter: Traverser, onExit?: Traverser, inde
 export function CompileScript(script: string, options: ScriptOptions = {}): CompileResult {
     const captured = options.capturedVariables ?? {};
     const signature = Object.keys(captured).reduce((p, v) => {
-        const formatCapture = (obj: any) => `${v}=${obj instanceof RefField ? 'XXX' : obj.toString()}`;
-        if (captured[v] instanceof Array) return p + (captured[v] as any).map(formatCapture);
+        const formatCapture = (obj: FieldType | undefined) => `${v}=${obj instanceof RefField ? 'XXX' : obj?.toString()}`;
+        const captureVal = captured[v];
+        if (captureVal instanceof Array) return p + captureVal.map(formatCapture);
         return p + formatCapture(captured[v]);
     }, '');
     const found = ScriptField.GetScriptFieldCache(script + ':' + signature);
diff --git a/src/client/util/ScriptingGlobals.ts b/src/client/util/ScriptingGlobals.ts
index ac524394a..4a1a70633 100644
--- a/src/client/util/ScriptingGlobals.ts
+++ b/src/client/util/ScriptingGlobals.ts
@@ -2,23 +2,22 @@ import ts from 'typescript';
 
 export { ts };
 
-const _scriptingGlobals: { [name: string]: any } = {};
-const _scriptingDescriptions: { [name: string]: any } = {};
-const _scriptingParams: { [name: string]: any } = {};
-// eslint-disable-next-line import/no-mutable-exports
-export let scriptingGlobals: { [name: string]: any } = _scriptingGlobals;
+const _scriptingGlobals: { [name: string]: unknown } = {};
+const _scriptingDescriptions: { [name: string]: string } = {};
+const _scriptingParams: { [name: string]: string } = {};
+export let scriptingGlobals: { [name: string]: unknown } = _scriptingGlobals;
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace ScriptingGlobals {
     export function getGlobals()      { return Object.keys(_scriptingGlobals); } // prettier-ignore
     export function getGlobalObj()    { return _scriptingGlobals; } // prettier-ignore
     export function getDescriptions() { return _scriptingDescriptions; } // prettier-ignore
     export function getParameters()   { return _scriptingParams; } // prettier-ignore
 
-    export function add(global: { name: string }): void;
-    export function add(name: string, global: any): void;
-    export function add(global: { name: string }, decription?: string, params?: string): void;
-    export function add(first: any, second?: any, third?: string) {
-        let n: any;
-        let obj: any;
+    export function add(name: string, namespace_func_or_object: unknown): void;
+    export function add(func: { name: string }, description?: string, params?: string): void;
+    export function add(first: string | { name: string }, second?: unknown, params?: string): void {
+        let n: string = '';
+        let obj: unknown;
 
         if (second !== undefined) {
             if (typeof first === 'string') {
@@ -27,32 +26,32 @@ export namespace ScriptingGlobals {
             } else {
                 obj = first;
                 n = first.name;
-                _scriptingDescriptions[n] = second;
-                if (third !== undefined) {
-                    _scriptingParams[n] = third;
+                _scriptingDescriptions[n] = second as string;
+                if (params !== undefined) {
+                    _scriptingParams[n] = params;
                 }
             }
-        } else if (first && typeof first.name === 'string') {
+        } else if (first instanceof Object && 'name' in first && typeof first.name === 'string') {
             n = first.name;
             obj = first;
         } else {
             throw new Error('Must either register an object with a name, or give a name and an object');
         }
         if (n === undefined || n === 'undefined') {
-            return false;
+            return; // false;
         }
         // eslint-disable-next-line no-prototype-builtins
         if (_scriptingGlobals.hasOwnProperty(n)) {
             throw new Error(`Global with name ${n} is already registered, choose another name`);
         }
         _scriptingGlobals[n] = obj;
-        return true;
+        return; // true;
     }
-    export function makeMutableGlobalsCopy(globals?: { [name: string]: any }) {
+    export function makeMutableGlobalsCopy(globals?: { [name: string]: unknown }) {
         return { ..._scriptingGlobals, ...(globals || {}) };
     }
 
-    export function setScriptingGlobals(globals: { [key: string]: any }) {
+    export function setScriptingGlobals(globals: { [key: string]: unknown }) {
         scriptingGlobals = globals;
     }
 
@@ -75,11 +74,12 @@ export namespace ScriptingGlobals {
     }
 
     // const types = Object.keys(ts.SyntaxKind).map(kind => ts.SyntaxKind[kind]);
-    export function printNodeType(node: any, indentation = '') {
+    export function printNodeType(node: ts.Node, indentation = '') {
         console.log(indentation + ts.SyntaxKind[node.kind]);
     }
 }
 
-export function scriptingGlobal(constructor: { new (...args: any[]): any }) {
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export function scriptingGlobal(constructor: { new (...args: any[]): unknown }) {
     ScriptingGlobals.add(constructor);
 }
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index 609fedfa9..6cad7060b 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -5,6 +5,7 @@ import { StrCast } from '../../fields/Types';
 import { DocumentType } from '../documents/DocumentTypes';
 import { DocOptions, FInfo } from '../documents/Documents';
 
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace SearchUtil {
     export type HighlightingResult = { [id: string]: { [key: string]: string[] } };
 
@@ -22,6 +23,7 @@ export namespace SearchUtil {
         const results = new ObservableMap<Doc, string[]>();
         if (collectionDoc) {
             const docs = DocListCast(collectionDoc[Doc.LayoutFieldKey(collectionDoc)]);
+            // eslint-disable-next-line @typescript-eslint/ban-types
             const docIDs: String[] = [];
             SearchUtil.foreachRecursiveDoc(docs, (depth: number, doc: Doc) => {
                 const dtype = StrCast(doc.type) as DocumentType;
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 0b942116c..1ab84421c 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -115,7 +115,7 @@ ScriptingGlobals.add(function redo() {
     return UndoManager.Redo();
 });
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) {
+ScriptingGlobals.add(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: Doc[]) {
     const docs = SelectionManager.Docs().filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.KVP && (!excludeCollections || d.type !== DocumentType.COL || !Cast(d.data, listSpec(Doc), null)));
     return docs.length ? new List(docs) : prevValue;
 });
diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts
index d9d22437c..0386b2455 100644
--- a/src/client/util/SerializationHelper.ts
+++ b/src/client/util/SerializationHelper.ts
@@ -1,22 +1,24 @@
 import { PropSchema, serialize, deserialize, custom, setDefaultModelSchema, getDefaultModelSchema } from 'serializr';
+import Context from 'serializr/lib/core/Context';
 // import { Field } from '../../fields/Doc';
 
 let serializing = 0;
-export function afterDocDeserialize(cb: (err: any, val: any) => void, err: any, newValue: any) {
+export function afterDocDeserialize(cb: (err: unknown, val: unknown) => void, err: unknown, newValue: unknown) {
     serializing++;
     cb(err, newValue);
     serializing--;
 }
 
-const serializationTypes: { [name: string]: { ctor: { new (): any }; afterDeserialize?: (obj: any) => void | Promise<any> } } = {};
+const serializationTypes: { [name: string]: { ctor: { new (): unknown }; afterDeserialize?: (obj: unknown) => void | Promise<unknown> } } = {};
 const reverseMap: { [ctor: string]: string } = {};
 
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace SerializationHelper {
     export function IsSerializing() {
         return serializing > 0;
     }
 
-    export function Serialize(obj: any /* Field */): any {
+    export function Serialize(obj: unknown /* Field */): unknown {
         if (obj === undefined || obj === null) {
             return null;
         }
@@ -37,7 +39,7 @@ export namespace SerializationHelper {
         return json;
     }
 
-    export async function Deserialize(obj: any): Promise<any> {
+    export async function Deserialize(obj: unknown): Promise<unknown> {
         if (obj === undefined || obj === null) {
             return undefined;
         }
@@ -46,16 +48,17 @@ export namespace SerializationHelper {
             return obj;
         }
 
-        if (!obj.__type) {
-            console.warn("No property 'type' found in JSON.");
+        const objtype = '__type' in obj ? (obj.__type as string) : undefined;
+        if (!objtype) {
+            console.warn(`No property ${objtype} found in JSON.`);
             return undefined;
         }
 
-        if (!(obj.__type in serializationTypes)) {
-            throw Error(`type '${obj.__type}' not registered. Make sure you register it using a @Deserializable decorator`);
+        if (!(objtype in serializationTypes)) {
+            throw Error(`type '${objtype}' not registered. Make sure you register it using a @Deserializable decorator`);
         }
 
-        const type = serializationTypes[obj.__type];
+        const type = serializationTypes[objtype];
         const value = await new Promise(res => {
             deserialize(type.ctor, obj, (err, result) => res(result));
         });
@@ -65,11 +68,12 @@ export namespace SerializationHelper {
     }
 }
 
-export function Deserializable(classNameForSerializer: string, afterDeserialize?: (obj: any) => void | Promise<any>, constructorArgs?: [string]): (constructor: { new (...args: any[]): any }) => void {
-    function addToMap(className: string, Ctor: { new (...args: any[]): any }) {
-        const schema = getDefaultModelSchema(Ctor) as any;
-        if (schema.targetClass !== Ctor || constructorArgs) {
-            setDefaultModelSchema(Ctor, { ...schema, factory: (context: any) => new Ctor(...(constructorArgs ?? []).map(arg => context.json[arg])) });
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export function Deserializable(classNameForSerializer: string, afterDeserialize?: (obj: unknown) => void | Promise<unknown>, constructorArgs?: [string]): (constructor: { new (...args: any[]): any }) => void {
+    function addToMap(className: string, Ctor: { new (...args: unknown[]): unknown }) {
+        const schema = getDefaultModelSchema(Ctor);
+        if (schema && (schema.targetClass !== Ctor || constructorArgs)) {
+            setDefaultModelSchema(Ctor, { ...schema, factory: (context: Context) => new Ctor(...(constructorArgs ?? []).map(arg => context.json[arg])) });
         }
         if (!(className in serializationTypes)) {
             serializationTypes[className] = { ctor: Ctor, afterDeserialize };
@@ -78,12 +82,12 @@ export function Deserializable(classNameForSerializer: string, afterDeserialize?
             throw new Error(`Name ${className} has already been registered as deserializable`);
         }
     }
-    return (ctor: { new (...args: any[]): any }) => addToMap(classNameForSerializer, ctor);
+    return (ctor: { new (...args: unknown[]): unknown }) => addToMap(classNameForSerializer, ctor);
 }
 
 export function autoObject(): PropSchema {
     return custom(
         s => SerializationHelper.Serialize(s),
-        (json: any, context: any, oldValue: any, cb: (err: any, result: any) => void) => SerializationHelper.Deserialize(json).then(res => cb(null, res))
+        (json: object, context: Context, oldValue: unknown, cb: (err: unknown, result: unknown) => void) => SerializationHelper.Deserialize(json).then(res => cb(null, res))
     );
 }
diff --git a/src/client/util/ServerStats.tsx b/src/client/util/ServerStats.tsx
index 57363663d..11db5ee5e 100644
--- a/src/client/util/ServerStats.tsx
+++ b/src/client/util/ServerStats.tsx
@@ -6,18 +6,29 @@ import './SharingManager.scss';
 import { PingManager } from './PingManager';
 import { SettingsManager } from './SettingsManager';
 
+/**
+ * NOTE: this must be kept in synch with UserStats definition in server's DashStats.ts file
+ * UserStats holds the stats associated with a particular user.
+ */
+interface UserStats {
+    socketId: string;
+    username: string;
+    time: string;
+    operations: number;
+    rate: number;
+}
 @observer
-export class ServerStats extends React.Component<{}> {
+export class ServerStats extends React.Component<object> {
     // eslint-disable-next-line no-use-before-define
     public static Instance: ServerStats;
     @observable private isOpen = false; // whether the SharingManager modal is open or not
 
-    @observable _stats: { [key: string]: any } | undefined = undefined;
+    @observable _stats: { socketMap: UserStats[]; currentConnections: number } | undefined = undefined;
     // private get linkVisible() {
     //     return this.targetDoc ? this.targetDoc['acl_' + PublicKey] !== SharingPermissions.None : false;
     // }
 
-    constructor(props: {}) {
+    constructor(props: object) {
         super(props);
         makeObservable(this);
         ServerStats.Instance = this;
@@ -41,7 +52,7 @@ export class ServerStats extends React.Component<{}> {
 
                     <br />
                     <span>Active users:{this._stats?.socketMap.length}</span>
-                    {this._stats?.socketMap.map((user: any) => <p>{user.username}</p>)}
+                    {this._stats?.socketMap.map(user => <p key={user.username}>{user.username}</p>)}
                 </div>
             </div>
         );
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 278931cdd..2d8763b63 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Button, ColorPicker, Dropdown, DropdownType, EditableText, Group, NumberDropdown, Size, Toggle, ToggleType, Type } from 'browndash-components';
 import { action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index c2a52cae9..117d7935e 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -1,13 +1,10 @@
-/* eslint-disable jsx-a11y/label-has-associated-control */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Button, IconButton, Size, Type } from 'browndash-components';
 import { concat, intersection } from 'lodash';
 import { action, computed, makeObservable, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import Select from 'react-select';
+import Select, { MultiValue } from 'react-select';
 import * as RequestPromise from 'request-promise';
 import { ClientUtils } from '../../ClientUtils';
 import { Utils } from '../../Utils';
@@ -27,6 +24,7 @@ import { SearchUtil } from './SearchUtil';
 import './SharingManager.scss';
 import { SnappingManager } from './SnappingManager';
 import { undoable } from './UndoManager';
+import { LinkManager } from './LinkManager';
 
 export interface User {
     email: string;
@@ -64,7 +62,7 @@ interface ValidatedUser {
 }
 
 @observer
-export class SharingManager extends React.Component<{}> {
+export class SharingManager extends React.Component<object> {
     // eslint-disable-next-line no-use-before-define
     public static Instance: SharingManager;
     private shareDocumentButtonRef: React.RefObject<HTMLButtonElement> = React.createRef(); // ref for the share button, used for the position of the popup
@@ -90,7 +88,7 @@ export class SharingManager extends React.Component<{}> {
     //     return this.targetDoc ? this.targetDoc['acl_' + PublicKey] !== SharingPermissions.None : false;
     // }
 
-    constructor(props: {}) {
+    constructor(props: object) {
         super(props);
         makeObservable(this);
         SharingManager.Instance = this;
@@ -108,8 +106,8 @@ export class SharingManager extends React.Component<{}> {
      * Handles changes in the users selected in react-select
      */
     @action
-    handleUsersChange = (selectedOptions: any) => {
-        this.selectedUsers = selectedOptions as UserOptions[];
+    handleUsersChange = (selectedOptions: MultiValue<UserOptions> /* , actionMeta: ActionMeta<UserOptions> */) => {
+        this.selectedUsers = Array.from(selectedOptions);
     };
 
     /**
@@ -490,12 +488,12 @@ export class SharingManager extends React.Component<{}> {
             const docs = await DocServer.GetRefFields(raw.reduce((list, user) => [...list, user.sharingDocumentId, user.linkDatabaseId], [] as string[]));
             raw.map(
                 action((newUser: User) => {
-                    const sharingDoc = docs[newUser.sharingDocumentId];
-                    const linkDatabase = docs[newUser.linkDatabaseId];
+                    const sharingDoc = docs.get(newUser.sharingDocumentId);
+                    const linkDatabase = docs.get(newUser.linkDatabaseId);
                     if (sharingDoc instanceof Doc && linkDatabase instanceof Doc) {
                         if (!this.users.find(user => user.user.email === newUser.email)) {
                             this.users.push({ user: newUser, sharingDoc, linkDatabase, userColor: StrCast(sharingDoc.userColor) });
-                            // LinkManager.addLinkDB(linkDatabase);
+                            LinkManager.Instance.addLinkDB(linkDatabase);
                         }
                     }
                 })
@@ -539,9 +537,8 @@ export class SharingManager extends React.Component<{}> {
     // eslint-disable-next-line react/no-unused-class-component-methods
     shareWithAddedMember = (group: Doc, emailId: string, retry: boolean = true) => {
         const user = this.users.find(({ user: { email } }) => email === emailId)!;
-        const self = this;
         if (group.docsShared) {
-            if (!user) retry && this.populateUsers().then(() => self.shareWithAddedMember(group, emailId, false));
+            if (!user) retry && this.populateUsers().then(() => this.shareWithAddedMember(group, emailId, false));
             else {
                 DocListCastAsync(user.sharingDoc[storage]).then(userdocs =>
                     DocListCastAsync(group.docsShared).then(dl => {
diff --git a/src/client/util/SnappingManager.ts b/src/client/util/SnappingManager.ts
index cc0366c5b..95ccc7735 100644
--- a/src/client/util/SnappingManager.ts
+++ b/src/client/util/SnappingManager.ts
@@ -79,5 +79,5 @@ export class SnappingManager {
     public static userColor: string | undefined;
     public static userVariantColor: string | undefined;
     public static userBackgroundColor: string | undefined;
-    public static SettingsStyle: any;
+    public static SettingsStyle: CSSStyleSheet | null;
 }
diff --git a/src/client/util/TrackMovements.ts b/src/client/util/TrackMovements.ts
index 25a3c9ad8..7da0281c0 100644
--- a/src/client/util/TrackMovements.ts
+++ b/src/client/util/TrackMovements.ts
@@ -9,13 +9,13 @@ export type Movement = {
     panX: number;
     panY: number;
     scale: number;
-    doc: Doc;
+    doc: Doc | string;
 };
 
 export type Presentation = {
     movements: Movement[] | null;
     totalTime: number;
-    meta: Object | Object[];
+    meta: object | object[];
 };
 
 export class TrackMovements {
@@ -142,7 +142,7 @@ export class TrackMovements {
         );
     };
 
-    start = (meta?: Object) => {
+    start = (meta?: object) => {
         this.initTabTracker();
 
         // update the presentation mode
@@ -245,7 +245,7 @@ export class TrackMovements {
         // these three will lead to the combined presentation
         const combinedMovements: Movement[] = [];
         let sumTime = 0;
-        const combinedMetas: any[] = [];
+        const combinedMetas: (object | object[])[] = [];
 
         presentations.forEach(presentation => {
             const { movements, totalTime, meta } = presentation;
diff --git a/src/client/util/TypedEvent.ts b/src/client/util/TypedEvent.ts
index 9ef2aa8d7..345eff00a 100644
--- a/src/client/util/TypedEvent.ts
+++ b/src/client/util/TypedEvent.ts
@@ -1,5 +1,5 @@
 export interface Listener<T> {
-    (event: T): any;
+    (event: T): unknown;
 }
 
 export interface Disposable {
diff --git a/src/client/util/UndoManager.ts b/src/client/util/UndoManager.ts
index 534ffd2c8..5fd935370 100644
--- a/src/client/util/UndoManager.ts
+++ b/src/client/util/UndoManager.ts
@@ -5,7 +5,7 @@ import { Without } from '../../Utils';
 import { RichTextField } from '../../fields/RichTextField';
 import { SnappingManager } from './SnappingManager';
 
-function getBatchName(target: any, key: string | symbol): string {
+function getBatchName(target: (...args: unknown[]) => unknown, key: string | symbol): string {
     const keyName = key.toString();
     if (target?.constructor?.name) {
         return `${target.constructor.name}.${keyName}`;
@@ -13,19 +13,19 @@ function getBatchName(target: any, key: string | symbol): string {
     return keyName;
 }
 
-function propertyDecorator(target: any, key: string | symbol) {
+function propertyDecorator(target: (...args: unknown[]) => unknown, key: string | symbol) {
     Object.defineProperty(target, key, {
         configurable: true,
         enumerable: false,
         get: function () {
             return 5;
         },
-        set: function (value: any) {
+        set: function (value: (...args: unknown[]) => unknown) {
             Object.defineProperty(this, key, {
                 enumerable: false,
                 writable: true,
                 configurable: true,
-                value: function (...args: any[]) {
+                value: function (...args: unknown[]) {
                     const batch = UndoManager.StartBatch(getBatchName(target, key));
                     try {
                         return value.apply(this, args);
@@ -38,7 +38,8 @@ function propertyDecorator(target: any, key: string | symbol) {
     });
 }
 
-export function undoable(fn: (...args: any[]) => any, batchName: string): (...args: any[]) => any {
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export function undoable<T>(fn: (...args: any[]) => T, batchName: string): (...args: unknown[]) => T {
     return function (...fargs) {
         const batch = UndoManager.StartBatch(batchName);
         try {
@@ -50,13 +51,12 @@ export function undoable(fn: (...args: any[]) => any, batchName: string): (...ar
     };
 }
 
+// eslint-disable-next-line no-redeclare, @typescript-eslint/no-explicit-any
 export function undoBatch(target: any, key: string | symbol, descriptor?: TypedPropertyDescriptor<any>): any;
-// eslint-disable-next-line no-redeclare
-export function undoBatch(fn: (...args: any[]) => any): (...args: any[]) => any;
-// eslint-disable-next-line no-redeclare
-export function undoBatch(target: any, key?: string | symbol, descriptor?: TypedPropertyDescriptor<any>): any {
+// eslint-disable-next-line no-redeclare, @typescript-eslint/no-explicit-any
+export function undoBatch(target: any, key?: string | symbol, descriptor?: TypedPropertyDescriptor<(...args: any[]) => unknown>): any {
     if (!key) {
-        return function (...fargs: any[]) {
+        return function (...fargs: unknown[]) {
             const batch = UndoManager.StartBatch('');
             try {
                 return target.apply(undefined, fargs);
@@ -71,10 +71,10 @@ export function undoBatch(target: any, key?: string | symbol, descriptor?: Typed
     }
     const oldFunction = descriptor.value;
 
-    descriptor.value = function (...args: any[]) {
+    descriptor.value = function (...args: unknown[]) {
         const batch = UndoManager.StartBatch(getBatchName(target, key));
         try {
-            return oldFunction.apply(this, args);
+            return oldFunction?.apply(this, args);
         } finally {
             batch.end();
         }
@@ -83,6 +83,7 @@ export function undoBatch(target: any, key?: string | symbol, descriptor?: Typed
     return descriptor;
 }
 
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace UndoManager {
     export interface UndoEvent {
         undo: () => void;
@@ -99,12 +100,12 @@ export namespace UndoManager {
     export const undoStack: UndoBatch[] = observable([]);
     export const redoStack: UndoBatch[] = observable([]);
     export const batchCounter = observable.box(0);
-    let _fieldPrinter: (val: any) => string = val => val?.toString();
-    export function SetFieldPrinter(printer: (val: any) => string) {
+    let _fieldPrinter: (val: unknown) => string = val => val?.toString?.() || '';
+    export function SetFieldPrinter(printer: (val: unknown) => string) {
         _fieldPrinter = printer;
     }
 
-    export function AddEvent(event: UndoEvent, value?: any): void {
+    export function AddEvent(event: UndoEvent, value?: unknown): void {
         if (currentBatch && batchCounter.get() && !undoing) {
             SnappingManager.PrintToConsole &&
                 console.log(
@@ -220,7 +221,7 @@ export namespace UndoManager {
             batch.end();
         }
     }
-    export const UndoTempBatch = action((success: any) => {
+    export const UndoTempBatch = action((success: boolean) => {
         if (tempEvents && !success) {
             undoing = true;
             for (let i = tempEvents.length - 1; i >= 0; i--) {
@@ -243,7 +244,6 @@ export namespace UndoManager {
         }
 
         undoing = true;
-        // eslint-disable-next-line prettier/prettier
         commands
             .slice()
             .reverse()
diff --git a/src/client/util/reportManager/ReportManager.tsx b/src/client/util/reportManager/ReportManager.tsx
index 2224e642d..c969f9036 100644
--- a/src/client/util/reportManager/ReportManager.tsx
+++ b/src/client/util/reportManager/ReportManager.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/label-has-associated-control */
-/* eslint-disable jsx-a11y/media-has-caption */
 /* eslint-disable react/no-unused-class-component-methods */
 import { Octokit } from '@octokit/core';
 import { Button, Dropdown, DropdownType, IconButton, Type } from 'browndash-components';
@@ -27,7 +25,7 @@ import { BugType, FileData, Priority, ReportForm, ViewState, bugDropdownItems, d
  * Class for reporting and viewing Github issues within the app.
  */
 @observer
-export class ReportManager extends React.Component<{}> {
+export class ReportManager extends React.Component<object> {
     // eslint-disable-next-line no-use-before-define
     public static Instance: ReportManager;
     @observable private isOpen = false;
@@ -109,7 +107,7 @@ export class ReportManager extends React.Component<{}> {
         this.setFetchingIssues(false);
     });
 
-    constructor(props: {}) {
+    constructor(props: object) {
         super(props);
         makeObservable(this);
         ReportManager.Instance = this;
diff --git a/src/client/util/reportManager/ReportManagerComponents.tsx b/src/client/util/reportManager/ReportManagerComponents.tsx
index cecebc648..92f877859 100644
--- a/src/client/util/reportManager/ReportManagerComponents.tsx
+++ b/src/client/util/reportManager/ReportManagerComponents.tsx
@@ -1,8 +1,5 @@
 /* eslint-disable react/require-default-props */
 /* eslint-disable prefer-destructuring */
-/* eslint-disable jsx-a11y/label-has-associated-control */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 /* eslint-disable no-use-before-define */
 import * as React from 'react';
 import ReactMarkdown from 'react-markdown';
@@ -98,7 +95,7 @@ export function IssueCard({ issue, onSelect }: IssueCardProps) {
                 <label className="issue-label">#{issue.number}</label>
                 <div className="issue-tags">
                     {issue.labels.map(label => {
-                        const labelString = typeof label === 'string' ? label : label.name ?? '';
+                        const labelString = typeof label === 'string' ? label : (label.name ?? '');
                         const colors = getLabelColors(labelString);
                         return <Tag key={labelString} text={labelString} backgroundColor={colors[0]} color={colors[1]} />;
                     })}
@@ -295,14 +292,16 @@ export function IssueView({ issue }: IssueViewProps) {
                 <div>
                     <div className="issue-tags">
                         {issue.labels.map(label => {
-                            const labelString = typeof label === 'string' ? label : label.name ?? '';
+                            const labelString = typeof label === 'string' ? label : (label.name ?? '');
                             const colors = getLabelColors(labelString);
                             return <Tag key={labelString} text={labelString} backgroundColor={colors[0]} color={colors[1]} fontSize="12px" />;
                         })}
                     </div>
                 </div>
             )}
-            <ReactMarkdown children={issueBody} className="issue-content" remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]} />
+            <ReactMarkdown className="issue-content" remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]}>
+                {issueBody}
+            </ReactMarkdown>
         </div>
     );
 }
diff --git a/src/client/util/reportManager/reportManagerSchema.ts b/src/client/util/reportManager/reportManagerSchema.ts
index 171c24393..7162371e3 100644
--- a/src/client/util/reportManager/reportManagerSchema.ts
+++ b/src/client/util/reportManager/reportManagerSchema.ts
@@ -66,7 +66,7 @@ export interface Issue {
      */
     url: string;
     user: null | TentacledSimpleUser;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 /**
@@ -94,7 +94,7 @@ export interface PurpleSimpleUser {
     subscriptions_url: string;
     type: string;
     url: string;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 /**
@@ -122,7 +122,7 @@ export interface AssigneeElement {
     subscriptions_url: string;
     type: string;
     url: string;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 /**
@@ -164,7 +164,7 @@ export interface FluffySimpleUser {
     subscriptions_url: string;
     type: string;
     url: string;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 export interface LabelObject {
@@ -175,7 +175,7 @@ export interface LabelObject {
     name?: string;
     node_id?: string;
     url?: string;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 /**
@@ -207,7 +207,7 @@ export interface Milestone {
     title: string;
     updated_at: Date;
     url: string;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 /**
@@ -235,7 +235,7 @@ export interface MilestoneSimpleUser {
     subscriptions_url: string;
     type: string;
     url: string;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 /**
@@ -288,7 +288,7 @@ export interface GitHubApp {
     slug?: string;
     updated_at: Date;
     webhook_secret?: null | string;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 /**
@@ -316,7 +316,7 @@ export interface GitHubAppSimpleUser {
     subscriptions_url: string;
     type: string;
     url: string;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 /**
@@ -336,7 +336,7 @@ export interface PullRequest {
     merged_at?: Date | null;
     patch_url: null | string;
     url: null | string;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 export interface ReactionRollup {
@@ -350,7 +350,7 @@ export interface ReactionRollup {
     rocket: number;
     total_count: number;
     url: string;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 /**
@@ -562,7 +562,7 @@ export interface Repository {
      * Whether to require contributors to sign off on web-based commits
      */
     web_commit_signoff_required?: boolean;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 /**
@@ -575,7 +575,7 @@ export interface LicenseSimple {
     node_id: string;
     spdx_id: null | string;
     url: null | string;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 /**
@@ -628,7 +628,7 @@ export interface RepositorySimpleUser {
     subscriptions_url: string;
     type: string;
     url: string;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 /**
@@ -656,7 +656,7 @@ export interface OwnerObject {
     subscriptions_url: string;
     type: string;
     url: string;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 export interface RepositoryPermissions {
@@ -665,7 +665,7 @@ export interface RepositoryPermissions {
     pull: boolean;
     push: boolean;
     triage?: boolean;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 /**
@@ -809,7 +809,7 @@ export interface TemplateRepository {
     use_squash_pr_title_as_default?: boolean;
     visibility?: string;
     watchers_count?: number;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 export interface Owner {
@@ -831,7 +831,7 @@ export interface Owner {
     subscriptions_url?: string;
     type?: string;
     url?: string;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 export interface TemplateRepositoryPermissions {
@@ -840,7 +840,7 @@ export interface TemplateRepositoryPermissions {
     pull?: boolean;
     push?: boolean;
     triage?: boolean;
-    [property: string]: any;
+    [property: string]: unknown;
 }
 
 export enum StateReason {
@@ -874,5 +874,5 @@ export interface TentacledSimpleUser {
     subscriptions_url: string;
     type: string;
     url: string;
-    [property: string]: any;
+    [property: string]: unknown;
 }
diff --git a/src/client/util/reportManager/reportManagerUtils.ts b/src/client/util/reportManager/reportManagerUtils.ts
index f14967e0a..d51418cbe 100644
--- a/src/client/util/reportManager/reportManagerUtils.ts
+++ b/src/client/util/reportManager/reportManagerUtils.ts
@@ -3,6 +3,7 @@
 import { Octokit } from '@octokit/core';
 import { Networking } from '../../Network';
 import { Issue } from './reportManagerSchema';
+import { Upload } from '../../../server/SharedMediaTypes';
 
 // enums and interfaces
 
@@ -53,7 +54,7 @@ export const emptyReportForm = {
  * Fetches issues from Github.
  * @returns array of all issues
  */
-export const getAllIssues = async (octokit: Octokit): Promise<any[]> => {
+export const getAllIssues = async (octokit: Octokit): Promise<unknown[]> => {
     const res = await octokit.request('GET /repos/{owner}/{repo}/issues', {
         owner: 'brown-dash',
         repo: 'Dash-Web',
@@ -103,7 +104,10 @@ export const fileLinktoServerLink = (fileLink: string): string => {
  * @param link response from file upload
  * @returns server file path
  */
-export const getServerPath = (link: any): string => link.result.accessPaths.agnostic.server as string;
+export const getServerPath = (link: Upload.FileResponse<Upload.FileInformation>): string => {
+    if (link.result instanceof Error) return '';
+    return link.result.accessPaths.agnostic.server;
+};
 
 /**
  * Uploads media files to the server.
@@ -114,11 +118,11 @@ export const uploadFilesToServer = async (mediaFiles: FileData[]): Promise<strin
         // need to always upload to browndash
         const links = await Networking.UploadFilesToServer(mediaFiles.map(file => ({ file: file.file })));
         return (links ?? []).map(getServerPath).map(fileLinktoServerLink);
-    } catch (err) {
-        if (err instanceof Error) {
-            alert(err.message);
+    } catch (result) {
+        if (result instanceof Error) {
+            alert(result.message);
         } else {
-            alert(err);
+            alert(result);
         }
     }
     return undefined;
diff --git a/src/client/util/request-image-size.ts b/src/client/util/request-image-size.ts
index 48cb6e3a5..7a2ecd486 100644
--- a/src/client/util/request-image-size.ts
+++ b/src/client/util/request-image-size.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-var-requires */
 /**
  * request-image-size: Detect image dimensions via request.
  * Licensed under the MIT license.
@@ -9,41 +10,30 @@
  * https://github.com/jo/http-image-size
  */
 
-const request = require('request');
-const imageSize = require('image-size');
+// const imageSize = require('image-size');
 const HttpError = require('standard-http-error');
+import * as request from 'request';
+import { imageSize } from 'image-size';
+import { ISizeCalculationResult } from 'image-size/dist/types/interface';
 
-module.exports = function requestImageSize(options: any) {
-    let opts: any = {
-        encoding: null,
-    };
-
-    if (options && typeof options === 'object') {
-        opts = Object.assign(options, opts);
-    } else if (options && typeof options === 'string') {
-        opts = {
-            uri: options,
-            ...opts,
-        };
-    } else {
+module.exports = function requestImageSize(url: string) {
+    if (!url) {
         return Promise.reject(new Error('You should provide an URI string or a "request" options object.'));
     }
 
-    opts.encoding = null;
-
     return new Promise((resolve, reject) => {
-        const req = request(opts);
+        const req = request(url);
 
-        req.on('response', (res: any) => {
+        req.on('response', res => {
             if (res.statusCode >= 400) {
                 reject(new HttpError(res.statusCode, res.statusMessage));
                 return;
             }
 
             let buffer = Buffer.from([]);
-            let size: any;
+            let size: ISizeCalculationResult;
 
-            res.on('data', (chunk: any) => {
+            res.on('data', chunk => {
                 buffer = Buffer.concat([buffer, chunk]);
 
                 try {
@@ -54,7 +44,7 @@ module.exports = function requestImageSize(options: any) {
                     }
                 } catch (err) {
                     /* empty */
-                    console.log("Error: ", err)
+                    console.log('Error: ', err);
                 }
             });
 
@@ -65,8 +55,6 @@ module.exports = function requestImageSize(options: any) {
                     reject(new Error('Image has no size'));
                     return;
                 }
-
-                size.downloaded = buffer.length;
                 resolve(size);
             });
         });
diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx
index 303672d90..99dee6410 100644
--- a/src/client/views/AntimodeMenu.tsx
+++ b/src/client/views/AntimodeMenu.tsx
@@ -16,7 +16,7 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends Observab
     protected _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
     protected _dragging: boolean = false;
 
-    constructor(props: any) {
+    constructor(props: T) {
         super(props);
         makeObservable(this);
     }
diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx
index d784a14b8..05634f376 100644
--- a/src/client/views/ContextMenu.tsx
+++ b/src/client/views/ContextMenu.tsx
@@ -2,7 +2,7 @@
 /* eslint-disable react/jsx-props-no-spreading */
 /* eslint-disable default-param-last */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, IReactionDisposer, makeObservable, observable } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { DivHeight, DivWidth } from '../../ClientUtils';
@@ -12,7 +12,7 @@ import { ContextMenuItem, ContextMenuProps, OriginalMenuProps } from './ContextM
 import { ObservableReactComponent } from './ObservableReactComponent';
 
 @observer
-export class ContextMenu extends ObservableReactComponent<{}> {
+export class ContextMenu extends ObservableReactComponent<{ noexpand?: boolean }> {
     // eslint-disable-next-line no-use-before-define
     static Instance: ContextMenu;
 
@@ -39,7 +39,7 @@ export class ContextMenu extends ObservableReactComponent<{}> {
     @observable _mouseY: number = -1;
     @observable _shouldDisplay: boolean = false;
 
-    constructor(props: any) {
+    constructor(props: object) {
         super(props);
         makeObservable(this);
         ContextMenu.Instance = this;
@@ -151,21 +151,21 @@ export class ContextMenu extends ObservableReactComponent<{}> {
     @computed get filteredItems(): (OriginalMenuProps | string[])[] {
         const searchString = this._searchString.toLowerCase().split(' ');
         const matches = (descriptions: string[]) => searchString.every(s => descriptions.some(desc => desc.toLowerCase().includes(s)));
-        const flattenItems = (items: ContextMenuProps[], groupFunc: (groupName: any) => string[]) => {
+        const flattenItems = (items: ContextMenuProps[], groupFunc: (groupName: string) => string[]) => {
             let eles: (OriginalMenuProps | string[])[] = [];
 
             const leaves: OriginalMenuProps[] = [];
             items.forEach(item => {
                 const { description } = item;
                 const path = groupFunc(description);
-                if ('subitems' in item) {
+                if (item.subitems) {
                     const children = flattenItems(item.subitems, name => [...groupFunc(description), name]);
                     if (children.length || matches(path)) {
                         eles.push(path);
                         eles = eles.concat(children);
                     }
                 } else if (matches(path)) {
-                    leaves.push(item);
+                    leaves.push(item as OriginalMenuProps);
                 }
             });
 
@@ -182,7 +182,7 @@ export class ContextMenu extends ObservableReactComponent<{}> {
 
     @computed get menuItems() {
         if (!this._searchString) {
-            return this._items.map((item, ind) => <ContextMenuItem key={item.description + ind} {...item} noexpand={this.itemsNeedSearch ? true : (item as any).noexpand} closeMenu={this.closeMenu} />);
+            return this._items.map((item, ind) => <ContextMenuItem key={item.description + ind} {...item} noexpand={this.itemsNeedSearch ? true : item.noexpand} closeMenu={this.closeMenu} />);
         }
         return this.filteredItems.map((value, index) =>
             Array.isArray(value) ? (
@@ -201,7 +201,7 @@ export class ContextMenu extends ObservableReactComponent<{}> {
     }
 
     @computed get itemsNeedSearch() {
-        return this._showSearch ? 1 : this._items.reduce((p, mi) => p + ((mi as any).noexpand ? 1 : (mi as any).subitems?.length || 1), 0) > 15;
+        return this._showSearch ? 1 : this._items.reduce((p, mi) => p + (mi.noexpand ? 1 : mi.subitems?.length || 1), 0) > 15;
     }
 
     _searchRef = React.createRef<HTMLInputElement>(); // bcz: we shouldn't need this, since we set autoFocus on the <input> tag, but for some reason we do...
@@ -211,13 +211,15 @@ export class ContextMenu extends ObservableReactComponent<{}> {
         return (
             <div
                 className="contextMenu-cont"
-                ref={action((r: any) => {
-                    if (r) {
-                        this._width = DivWidth(r);
-                        this._height = DivHeight(r);
-                    }
-                    this._searchRef.current?.focus();
-                })}
+                ref={r =>
+                    runInAction(() => {
+                        if (r) {
+                            this._width = DivWidth(r);
+                            this._height = DivHeight(r);
+                        }
+                        this._searchRef.current?.focus();
+                    })
+                }
                 style={{
                     display: this._display ? '' : 'none',
                     left: this.pageX,
@@ -239,7 +241,6 @@ export class ContextMenu extends ObservableReactComponent<{}> {
                             value={this._searchString}
                             onKeyDown={this.onKeyDown}
                             onChange={this.onChange}
-                            // eslint-disable-next-line jsx-a11y/no-autofocus
                             autoFocus
                         />
                     </span>
diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx
index eb1030eec..3b87ea58b 100644
--- a/src/client/views/ContextMenuItem.tsx
+++ b/src/client/views/ContextMenuItem.tsx
@@ -10,8 +10,10 @@ import { ObservableReactComponent } from './ObservableReactComponent';
 
 export interface OriginalMenuProps {
     description: string;
-    event: (stuff?: any) => void;
+    event: (stuff?: unknown) => void;
     undoable?: boolean;
+    noexpand?: boolean;
+    subitems?: ContextMenuProps[];
     icon: IconProp | JSX.Element; // maybe should be optional (icon?)
     closeMenu?: () => void;
 }
@@ -33,7 +35,7 @@ export class ContextMenuItem extends ObservableReactComponent<ContextMenuProps &
     @observable private _items: Array<ContextMenuProps> = [];
     @observable private overItem = false;
 
-    constructor(props: any) {
+    constructor(props: ContextMenuProps & { selected?: boolean }) {
         super(props);
         makeObservable(this);
     }
@@ -56,7 +58,7 @@ export class ContextMenuItem extends ObservableReactComponent<ContextMenuProps &
         }
     };
 
-    currentTimeout?: any;
+    currentTimeout?: NodeJS.Timeout | undefined;
     static readonly timeout = 300;
     _overPosY = 0;
     _overPosX = 0;
@@ -94,7 +96,7 @@ export class ContextMenuItem extends ObservableReactComponent<ContextMenuProps &
         );
     };
 
-    isJSXElement(val: any): val is JSX.Element {
+    isJSXElement(val: unknown): val is JSX.Element {
         return React.isValidElement(val);
     }
 
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index b7383a37e..dcc5442f0 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Button, ColorPicker, EditableText, Size, Type } from 'browndash-components';
 import { action, computed, makeObservable, observable } from 'mobx';
@@ -46,7 +44,7 @@ export type DocConfig = {
 // DashboardView is the view with the dashboard previews, rendered when the app first loads
 
 @observer
-export class DashboardView extends ObservableReactComponent<{}> {
+export class DashboardView extends ObservableReactComponent<object> {
     public static _urlState: HistoryUtil.DocUrl;
     public static makeDocumentConfig(document: Doc, panelName?: string, width?: number, keyValue?: boolean) {
         return {
@@ -82,7 +80,7 @@ export class DashboardView extends ObservableReactComponent<{}> {
         });
         return doc;
     }
-    constructor(props: any) {
+    constructor(props: object) {
         super(props);
         makeObservable(this);
     }
diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx
index c97edd7f0..b11fa3bd5 100644
--- a/src/client/views/FilterPanel.tsx
+++ b/src/client/views/FilterPanel.tsx
@@ -1,6 +1,4 @@
 /* eslint-disable react/jsx-props-no-spreading */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { action, computed, makeObservable, observable, ObservableMap } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -28,7 +26,7 @@ interface filterProps {
 export class FilterPanel extends ObservableReactComponent<filterProps> {
     @observable _selectedFacetHeaders = new Set<string>();
 
-    constructor(props: any) {
+    constructor(props: filterProps) {
         super(props);
         makeObservable(this);
     }
@@ -41,7 +39,7 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
     }
     @computed get targetDocChildKey() {
         const targetView = DocumentView.getFirstDocumentView(this.Document);
-        return targetView?.ComponentView?.annotationKey ?? targetView?.ComponentView?.fieldKey ?? 'data';
+        return targetView?.ComponentView?.annotationKey || (targetView?.ComponentView?.fieldKey ?? 'data');
     }
     @computed get targetDocChildren() {
         return [...DocListCast(this.Document?.[this.targetDocChildKey] || Doc.ActiveDashboard?.data), ...DocListCast(this.Document[Doc.LayoutFieldKey(this.Document) + '_sidebar'])];
@@ -240,7 +238,7 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
                     {Array.from(this.activeRenderedFacetInfos.keys()).map(
                         // iterate over activeFacetRenderInfos  ==> renderInfo  which you can renderInfo.facetHeader
                         renderInfo => (
-                            <div>
+                            <div key={renderInfo.facetHeader}>
                                 <div className="filterBox-facetHeader">
                                     <div className="filterBox-facetHeader-Header"> </div>
                                     {renderInfo.facetHeader.charAt(0).toUpperCase() + renderInfo.facetHeader.slice(1)}
@@ -308,7 +306,7 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
                 return this.facetValues(facetHeader).map(fval => {
                     const facetValue = fval;
                     return (
-                        <div>
+                        <div key={facetValue}>
                             <input
                                 style={{ width: 20, marginLeft: 20 }}
                                 checked={['check', 'exists'].includes(
@@ -343,7 +341,7 @@ export class FilterPanel extends ObservableReactComponent<filterProps> {
                                             <div className="slider-handles">
                                                 {handles.map(handle => (
                                                     // const value = i === 0 ? defaultValues[0] : defaultValues[1];
-                                                    <div>
+                                                    <div key={handle.id}>
                                                         <Handle key={handle.id} handle={handle} domain={domain} isActive={handle.id === activeHandleID} getHandleProps={getHandleProps} />
                                                     </div>
                                                 ))}
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index e3e252593..804c41091 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -78,7 +78,7 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
     private thumbIdentifier?: number;
     private pointerIdentifier?: number;
 
-    constructor(props: any) {
+    constructor(props: GestureOverlayProps) {
         super(props);
         makeObservable(this);
         GestureOverlay.Instances.push(this);
@@ -94,7 +94,7 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
 
     @action
     onPointerDown = (e: React.PointerEvent) => {
-        if (!(e.target as any)?.className?.toString().startsWith('lm_')) {
+        if (!(e.target as HTMLElement)?.className?.toString().startsWith('lm_')) {
             if ([InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
                 this._points.push({ X: e.clientX, Y: e.clientY });
                 setupMoveUpEvents(this, e, this.onPointerMove, this.onPointerUp, emptyFunction);
@@ -173,8 +173,8 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
                     newPoints.pop();
                     const controlPoints: { X: number; Y: number }[] = [];
 
-                    const bezierCurves = (fitCurve as any)(newPoints, 10);
-                    Array.from(bezierCurves).forEach((curve: any) => {
+                    const bezierCurves = fitCurve.default(newPoints, 10);
+                    Array.from(bezierCurves).forEach(curve => {
                         controlPoints.push({ X: curve[0][0], Y: curve[0][1] });
                         controlPoints.push({ X: curve[1][0], Y: curve[1][1] });
                         controlPoints.push({ X: curve[2][0], Y: curve[2][1] });
@@ -351,7 +351,7 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
         return false;
     };
 
-    dispatchGesture = (gesture: Gestures, stroke?: InkData, text?: any) => {
+    dispatchGesture = (gesture: Gestures, stroke?: InkData, text?: string) => {
         const points = (stroke ?? this._points).slice();
         return (
             document.elementFromPoint(points[0].X, points[0].Y)?.dispatchEvent(
@@ -411,7 +411,7 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
                                 ActiveDash(),
                                 1,
                                 1,
-                                this.InkShape ?? '',
+                                this.InkShape as Gestures,
                                 'none',
                                 1.0,
                                 false
@@ -438,7 +438,7 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
                             ActiveDash(),
                             1,
                             1,
-                            this.InkShape ?? '',
+                            this.InkShape as Gestures,
                             'none',
                             1.0,
                             false
@@ -516,13 +516,7 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
 
 ScriptingGlobals.add('GestureOverlay', GestureOverlay);
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function setToolglass(tool: any) {
-    runInAction(() => {
-        GestureOverlay.Instance.Tool = tool;
-    });
-});
-// eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function setPen(width: any, color: any, fill: any, arrowStart: any, arrowEnd: any, dash: any) {
+ScriptingGlobals.add(function setPen(width: string, color: string, fill: string, arrowStart: string, arrowEnd: string, dash: string) {
     runInAction(() => {
         GestureOverlay.Instance.SavedColor = ActiveInkColor();
         SetActiveInkColor(color);
@@ -543,8 +537,8 @@ ScriptingGlobals.add(function resetPen() {
 }, 'resets the pen tool');
 ScriptingGlobals.add(
     // eslint-disable-next-line prefer-arrow-callback
-    function createText(text: any, x: any, y: any) {
-        GestureOverlay.Instance.dispatchGesture(Gestures.Text, [{ X: x, Y: y }], text);
+    function createText(text: string, X: number, Y: number) {
+        GestureOverlay.Instance.dispatchGesture(Gestures.Text, [{ X, Y }], text);
     },
     'creates a text document with inputted text and coordinates',
     '(text: any, x: any, y: any)'
diff --git a/src/client/views/InkTranscription.tsx b/src/client/views/InkTranscription.tsx
index 1ed8de1be..33db72960 100644
--- a/src/client/views/InkTranscription.tsx
+++ b/src/client/views/InkTranscription.tsx
@@ -240,7 +240,8 @@
 //                 const text = exports['text/plain'];
 
 //                 if (this.currGroup) {
-//                     this.currGroup.transcription = text;
+//                     this.currGroup.text = text;  // transcription text
+//                     this.currGroup.icon_fieldKey = 'transcription'; // use the transcription icon template when iconifying
 //                     this.currGroup.title = text.split('\n')[0];
 //                 }
 
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 784d252a3..2e82371cb 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -20,6 +20,7 @@
     
     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 { Property } from 'csstype';
 import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -28,6 +29,7 @@ import { Doc } from '../../fields/Doc';
 import { InkData, InkField } from '../../fields/InkField';
 import { BoolCast, Cast, NumCast, RTFCast, StrCast } from '../../fields/Types';
 import { TraceMobx } from '../../fields/util';
+import { Gestures } from '../../pen-gestures/GestureTypes';
 import { CognitiveServices } from '../cognitive_services/CognitiveServices';
 import { Docs } from '../documents/Documents';
 import { DocumentType } from '../documents/DocumentTypes';
@@ -35,7 +37,6 @@ import { InteractionUtils } from '../util/InteractionUtils';
 import { SnappingManager } from '../util/SnappingManager';
 import { UndoManager } from '../util/UndoManager';
 import { ContextMenu } from './ContextMenu';
-import { ViewBoxInterface } from './ViewBoxInterface';
 import { ViewBoxAnnotatableComponent } from './DocComponent';
 import { Colors } from './global/globalEnums';
 import { InkControlPtHandles, InkEndPtHandles } from './InkControlPtHandles';
@@ -46,6 +47,7 @@ import { FieldView, FieldViewProps } from './nodes/FieldView';
 import { FormattedTextBox, FormattedTextBoxProps } from './nodes/formattedText/FormattedTextBox';
 import { PinDocView, PinProps } from './PinFuncs';
 import { StyleProp } from './StyleProp';
+import { ViewBoxInterface } from './ViewBoxInterface';
 
 // eslint-disable-next-line @typescript-eslint/no-var-requires
 const { INK_MASK_SIZE } = require('./global/globalCssVariables.module.scss'); // prettier-ignore
@@ -318,8 +320,8 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
                     Colors.MEDIUM_BLUE,
                     screenInkWidth[0],
                     screenSpaceCenterlineStrokeWidth,
-                    StrCast(inkDoc.stroke_lineJoin),
-                    StrCast(this.layoutDoc.stroke_lineCap),
+                    StrCast(inkDoc.stroke_lineJoin) as Property.StrokeLinejoin,
+                    StrCast(this.layoutDoc.stroke_lineCap) as Property.StrokeLinecap,
                     StrCast(inkDoc.stroke_bezier),
                     'none',
                     startMarker,
@@ -328,7 +330,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
                     StrCast(inkDoc.stroke_dash),
                     1,
                     1,
-                    '',
+                    '' as Gestures,
                     'none',
                     1.0,
                     false
@@ -383,8 +385,8 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
             this.strokeColor,
             inkStrokeWidth,
             inkStrokeWidth,
-            StrCast(this.layoutDoc.stroke_lineJoin),
-            StrCast(this.layoutDoc.stroke_lineCap),
+            StrCast(this.layoutDoc.stroke_lineJoin) as Property.StrokeLinejoin,
+            StrCast(this.layoutDoc.stroke_lineCap) as Property.StrokeLinecap,
             StrCast(this.layoutDoc.stroke_bezier),
             !closed ? 'none' : fillColor === 'transparent' ? 'none' : fillColor,
             startMarker,
@@ -393,7 +395,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
             StrCast(this.layoutDoc.stroke_dash),
             inkScaleX,
             inkScaleY,
-            '',
+            '' as Gestures,
             'none',
             1.0,
             false,
@@ -410,8 +412,8 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
                 mask && color === 'transparent' ? this.strokeColor : (highlightColor ?? color),
                 inkStrokeWidth,
                 inkStrokeWidth + NumCast(this.layoutDoc.stroke_borderWidth) + (fillColor ? (closed ? higlightMargin : (highlightIndex ?? 0) + higlightMargin) : higlightMargin),
-                StrCast(this.layoutDoc.stroke_lineJoin),
-                StrCast(this.layoutDoc.stroke_lineCap),
+                StrCast(this.layoutDoc.stroke_lineJoin) as Property.StrokeLinejoin,
+                StrCast(this.layoutDoc.stroke_lineCap) as Property.StrokeLinecap,
                 StrCast(this.layoutDoc.stroke_bezier),
                 !closed || !fillColor || DashColor(fillColor).alpha() === 0 ? 'none' : fillColor,
                 startMarker,
@@ -420,7 +422,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>()
                 StrCast(this.layoutDoc.stroke_dash),
                 inkScaleX,
                 inkScaleY,
-                '',
+                '' as Gestures,
                 this._props.pointerEvents?.() ?? 'visiblePainted',
                 0.0,
                 false,
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx
index 7198c7f05..adbe20a63 100644
--- a/src/client/views/LightboxView.tsx
+++ b/src/client/views/LightboxView.tsx
@@ -1,6 +1,4 @@
 /* eslint-disable no-use-before-define */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Toggle, ToggleType, Type } from 'browndash-components';
@@ -12,7 +10,7 @@ import { emptyFunction } from '../../Utils';
 import { CreateLinkToActiveAudio, Doc, DocListCast, FieldResult, Opt } from '../../fields/Doc';
 import { Id } from '../../fields/FieldSymbols';
 import { InkTool } from '../../fields/InkField';
-import { Cast, NumCast, toList } from '../../fields/Types';
+import { BoolCast, Cast, NumCast, toList } from '../../fields/Types';
 import { SnappingManager } from '../util/SnappingManager';
 import { Transform } from '../util/Transform';
 import { GestureOverlay } from './GestureOverlay';
@@ -28,7 +26,7 @@ interface LightboxViewProps {
     PanelWidth: number;
     PanelHeight: number;
     maxBorder: number[];
-    addSplit: (document: Doc, pullSide: OpenWhereMod, stack?: any, panelName?: string | undefined, keyValue?: boolean | undefined) => boolean;
+    addSplit: (document: Doc, pullSide: OpenWhereMod, stack?: unknown, panelName?: string | undefined, keyValue?: boolean | undefined) => boolean;
 }
 
 const savedKeys = ['freeform_panX', 'freeform_panY', 'freeform_scale', 'layout_scrollTop', 'layout_fieldKey'];
@@ -63,7 +61,7 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
     @computed get leftBorder() { return Math.min(this._props.PanelWidth / 4, this._props.maxBorder[0]); } // prettier-ignore
     @computed get topBorder()  { return Math.min(this._props.PanelHeight / 4, this._props.maxBorder[1]); } // prettier-ignore
 
-    constructor(props: any) {
+    constructor(props: LightboxViewProps) {
         super(props);
         makeObservable(this);
         LightboxView.Instance = this;
@@ -214,7 +212,7 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
     lightboxDocTemplate = () => this._layoutTemplate;
     future = () => this._future;
 
-    renderNavBtn = (left: Opt<string | number>, bottom: Opt<number>, top: number, icon: IconProp, display: any, click: () => void, color?: string) => (
+    renderNavBtn = (left: Opt<string | number>, bottom: Opt<number>, top: number, icon: IconProp, display: boolean, click: () => void, color?: string) => (
         <div
             className="lightboxView-navBtn-frame"
             style={{
@@ -239,7 +237,7 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
     render() {
         let downx = 0;
         let downy = 0;
-        const toggleBtn = (classname: string, tooltip: string, toggleBackground: any, icon: IconProp, icon2: IconProp | string, onClick: () => void) => (
+        const toggleBtn = (classname: string, tooltip: string, toggleBackground: boolean, icon: IconProp, icon2: IconProp | string, onClick: () => void) => (
             <div className={classname}>
                 <Toggle
                     tooltip={tooltip}
@@ -306,18 +304,18 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
                     </GestureOverlay>
                 </div>
 
-                {this.renderNavBtn(0, undefined, this._props.PanelHeight / 2 - 12.5, 'chevron-left', this._doc && this._history.length, this.previous)}
+                {this.renderNavBtn(0, undefined, this._props.PanelHeight / 2 - 12.5, 'chevron-left', this._doc && this._history.length ? true : false, this.previous)}
                 {this.renderNavBtn(
                     this._props.PanelWidth - Math.min(this._props.PanelWidth / 4, this._props.maxBorder[0]),
                     undefined,
                     this._props.PanelHeight / 2 - 12.5,
                     'chevron-right',
-                    this._doc && this._future.length,
+                    this._doc && this._future.length ? true : false,
                     this.next,
                     this.future().length.toString()
                 )}
                 <LightboxTourBtn lightboxDoc={this.lightboxDoc} navBtn={this.renderNavBtn} future={this.future} stepInto={this.stepInto} />
-                {toggleBtn('lightboxView-navBtn', 'toggle reading view', this._doc?._layout_fitWidth, 'book-open', 'book', this.toggleFitWidth)}
+                {toggleBtn('lightboxView-navBtn', 'toggle reading view', BoolCast(this._doc?._layout_fitWidth), 'book-open', 'book', this.toggleFitWidth)}
                 {toggleBtn('lightboxView-tabBtn', 'open document in a tab', false, 'file-download', '', this.downloadDoc)}
                 {toggleBtn('lightboxView-penBtn', 'toggle pen annotation', Doc.ActiveTool === InkTool.Pen, 'pen', '', this.togglePen)}
                 {toggleBtn('lightboxView-exploreBtn', 'toggle navigate only mode', SnappingManager.ExploreMode, 'globe-americas', '', this.toggleExplore)}
@@ -326,7 +324,7 @@ export class LightboxView extends ObservableReactComponent<LightboxViewProps> {
     }
 }
 interface LightboxTourBtnProps {
-    navBtn: (left: Opt<string | number>, bottom: Opt<number>, top: number, icon: IconProp, display: any, click: () => void, color?: string) => JSX.Element;
+    navBtn: (left: Opt<string | number>, bottom: Opt<number>, top: number, icon: IconProp, display: boolean, click: () => void, color?: string) => JSX.Element;
     // eslint-disable-next-line react/no-unused-prop-types
     future: () => Opt<Doc[]>;
     stepInto: () => void;
@@ -335,7 +333,7 @@ interface LightboxTourBtnProps {
 @observer
 export class LightboxTourBtn extends React.Component<LightboxTourBtnProps> {
     render() {
-        return this.props.navBtn('50%', 0, 0, 'chevron-down', this.props.lightboxDoc(), this.props.stepInto, '');
+        return this.props.navBtn('50%', 0, 0, 'chevron-down', this.props.lightboxDoc() ? true : false, this.props.stepInto, '');
     }
 }
 
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 43b9a6b39..044162e4e 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -50,6 +50,7 @@ import { ScreenshotBox } from './nodes/ScreenshotBox';
 import { ScriptingBox } from './nodes/ScriptingBox';
 import { VideoBox } from './nodes/VideoBox';
 import { WebBox } from './nodes/WebBox';
+import { CalendarBox } from './nodes/calendarBox/CalendarBox';
 import { DashDocCommentView } from './nodes/formattedText/DashDocCommentView';
 import { DashDocView } from './nodes/formattedText/DashDocView';
 import { DashFieldView } from './nodes/formattedText/DashFieldView';
@@ -60,6 +61,8 @@ import { SummaryView } from './nodes/formattedText/SummaryView';
 import { ImportElementBox } from './nodes/importBox/ImportElementBox';
 import { PresBox, PresElementBox } from './nodes/trails';
 import { SearchBox } from './search/SearchBox';
+import { Node } from 'prosemirror-model';
+import { EditorView } from 'prosemirror-view';
 
 dotenv.config();
 
@@ -83,7 +86,7 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' };
     setTimeout(() => {
         // prevent zooming browser
         document.getElementById('root')!.addEventListener('wheel', event => event.ctrlKey && event.preventDefault(), true);
-        const startload = (document as any).startLoad;
+        const startload = (document as unknown as { startLoad: number }).startLoad; // see index.html in deploy/
         const loading = Date.now() - (startload ? Number(startload) : Date.now() - 3000);
         console.log('Loading Time = ' + loading);
         const d = new Date();
@@ -99,12 +102,12 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' };
         // initialize plugins and classes that require plugins
         CollectionDockingView.Init(TabDocView);
         FormattedTextBox.Init((tbox: FormattedTextBox) => ({
-            dashComment(node: any, view: any, getPos: any) { return new DashDocCommentView(node, view, getPos); }, // prettier-ignore
-            dashDoc(node: any, view: any, getPos: any)     { return new DashDocView(node, view, getPos, tbox); }, // prettier-ignore
-            dashField(node: any, view: any, getPos: any)   { return new DashFieldView(node, view, getPos, tbox); }, // prettier-ignore
-            equation(node: any, view: any, getPos: any)    { return new EquationView(node, view, getPos, tbox); }, // prettier-ignore
-            summary(node: any, view: any, getPos: any)     { return new SummaryView(node, view, getPos); }, // prettier-ignore
-            footnote(node: any, view: any, getPos: any)    { return new FootnoteView(node, view, getPos); }, // prettier-ignore
+            dashComment(node: Node, view: EditorView, getPos: () => number | undefined) { return new DashDocCommentView(node, view, getPos); }, // prettier-ignore
+            dashDoc(node: Node, view: EditorView, getPos: () => number | undefined)     { return new DashDocView(node, view, getPos, tbox); }, // prettier-ignore
+            dashField(node: Node, view: EditorView, getPos: () => number | undefined)   { return new DashFieldView(node, view, getPos, tbox); }, // prettier-ignore
+            equation(node: Node, view: EditorView, getPos: () => number | undefined)    { return new EquationView(node, view, getPos, tbox); }, // prettier-ignore
+            summary(node: Node, view: EditorView, getPos: () => number | undefined)     { return new SummaryView(node, view, getPos); }, // prettier-ignore
+            footnote(node: Node, view: EditorView, getPos: () => number | undefined)    { return new FootnoteView(node, view, getPos); }, // prettier-ignore
         }));
         CollectionFreeFormInfoUI.Init();
         LinkFollower.Init();
@@ -141,6 +144,7 @@ FieldLoader.ServerLoadStatus = { requested: 0, retrieved: 0, message: 'cache' };
             ChatBox,
             DiagramBox,
             HTMLtag,
+            CalendarBox,
             ComparisonBox,
             LoadingBox,
             PhysicsSimulationBox,
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index ef1bcfb64..ac30c5a14 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable node/no-unpublished-import */
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faBuffer, faHireAHelper } from '@fortawesome/free-brands-svg-icons';
 import * as far from '@fortawesome/free-regular-svg-icons';
@@ -7,7 +6,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, configure, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-// eslint-disable-next-line import/no-relative-packages
+import ResizeObserver from 'resize-observer-polyfill';
 import '../../../node_modules/browndash-components/dist/styles/global.min.css';
 import { ClientUtils, lightOrDark, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents } from '../../ClientUtils';
 import { emptyFunction } from '../../Utils';
@@ -58,7 +57,6 @@ import { ImageLabelHandler } from './collections/collectionFreeForm/ImageLabelHa
 import { MarqueeOptionsMenu } from './collections/collectionFreeForm/MarqueeOptionsMenu';
 import { CollectionLinearView } from './collections/collectionLinear';
 import { LinkMenu } from './linking/LinkMenu';
-import { AudioBox } from './nodes/AudioBox';
 import { SchemaCSVPopUp } from './nodes/DataVizBox/SchemaCSVPopUp';
 import { DocButtonState } from './nodes/DocumentLinksButton';
 import { DocumentView, DocumentViewInternal } from './nodes/DocumentView';
@@ -77,11 +75,11 @@ import { AnchorMenu } from './pdf/AnchorMenu';
 import { GPTPopup } from './pdf/GPTPopup/GPTPopup';
 import { TopBar } from './topbar/TopBar';
 
+// eslint-disable-next-line @typescript-eslint/no-var-requires
 const { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } = require('./global/globalCssVariables.module.scss'); // prettier-ignore
-const _global = (window /* browser */ || global) /* node */ as any;
 
 @observer
-export class MainView extends ObservableReactComponent<{}> {
+export class MainView extends ObservableReactComponent<object> {
     // eslint-disable-next-line no-use-before-define
     public static Instance: MainView;
     public static Live: boolean = false;
@@ -92,7 +90,7 @@ export class MainView extends ObservableReactComponent<{}> {
     @observable private _dashUIWidth: number = 0; // width of entire main dashboard region including left menu buttons and properties panel (but not including the dashboard selector button row)
     @observable private _dashUIHeight: number = 0; // height of entire main dashboard region including top menu buttons
     @observable private _panelContent: string = 'none';
-    @observable private _sidebarContent: any = Doc.MyLeftSidebarPanel;
+    @observable private _sidebarContent: Doc = Doc.MyLeftSidebarPanel;
     @observable private _leftMenuFlyoutWidth: number = 0;
     @computed get _hideUI() {
         return this.mainDoc && this.mainDoc._type_collection !== CollectionViewType.Docking;
@@ -152,7 +150,7 @@ export class MainView extends ObservableReactComponent<{}> {
         }
     };
     headerBarDocWidth = () => this.mainDocViewWidth();
-    headerBarDocHeight = () => (this._hideUI ? 0 : this.headerBarHeight ?? 0);
+    headerBarDocHeight = () => (this._hideUI ? 0 : (this.headerBarHeight ?? 0));
     topMenuHeight = () => (this._hideUI ? 0 : 35);
     topMenuWidth = returnZero; // value is ignored ...
     leftMenuWidth = () => (this._hideUI ? 0 : Number(LEFT_MENU_WIDTH.replace('px', '')));
@@ -169,7 +167,7 @@ export class MainView extends ObservableReactComponent<{}> {
         reaction(
             // when a multi-selection occurs, remove focus from all active elements to allow keyboad input to go only to global key manager to act upon selection
             () => DocumentView.Selected().slice(),
-            views => views.length > 1 && (document.activeElement as any)?.blur !== undefined && (document.activeElement as any)!.blur()
+            views => views.length > 1 && document.activeElement instanceof HTMLElement && document.activeElement?.blur()
         );
         reaction(
             () => Doc.MyDockedBtns.linearView_IsOpen,
@@ -234,9 +232,9 @@ export class MainView extends ObservableReactComponent<{}> {
         tag.src = 'https://www.youtube.com/iframe_api';
         const firstScriptTag = document.getElementsByTagName('script')[0];
         firstScriptTag.parentNode!.insertBefore(tag, firstScriptTag);
-        document.addEventListener('dash', (e: any) => {
+        document.addEventListener('dash', (e: Event) => {
             // event used by chrome plugin to tell Dash which document to focus on
-            const id = GetDocFromUrl(e.detail);
+            const id = GetDocFromUrl((e as Event & { detail: string }).detail);
             DocServer.GetRefField(id).then(doc => (doc instanceof Doc ? DocumentView.showDocument(doc, { willPan: false }) : null));
         });
         document.addEventListener('linkAnnotationToDash', Hypothesis.linkListener);
@@ -253,12 +251,12 @@ export class MainView extends ObservableReactComponent<{}> {
         // document.removeEventListener('linkAnnotationToDash', Hypothesis.linkListener);
     }
 
-    constructor(props: any) {
+    constructor(props: object) {
         super(props);
         makeObservable(this);
         DocumentViewInternal.addDocTabFunc = MainView.addDocTabFunc_impl;
         MainView.Instance = this;
-        DashboardView._urlState = HistoryUtil.parseUrl(window.location) || ({} as any);
+        DashboardView._urlState = HistoryUtil.parseUrl(window.location) ?? { type: 'doc', docId: '' };
 
         // causes errors to be generated when modifying an observable outside of an action
         configure({ enforceActions: 'observed' });
@@ -293,7 +291,7 @@ export class MainView extends ObservableReactComponent<{}> {
                 fa.faExternalLinkAlt,
                 fa.faCalendar,
                 fa.faSquare,
-                far.faSquare as any,
+                far.faSquare,
                 fa.faConciergeBell,
                 fa.faWindowRestore,
                 fa.faFolder,
@@ -445,7 +443,7 @@ export class MainView extends ObservableReactComponent<{}> {
                 fa.faHandPaper,
                 fa.faMap,
                 fa.faUser,
-                faHireAHelper as any,
+                faHireAHelper,
                 fa.faTrashRestore,
                 fa.faUsers,
                 fa.faWrench,
@@ -456,14 +454,14 @@ export class MainView extends ObservableReactComponent<{}> {
                 fa.faArchive,
                 fa.faBezierCurve,
                 fa.faCircle,
-                far.faCircle as any,
+                far.faCircle,
                 fa.faLongArrowAltRight,
                 fa.faPenFancy,
                 fa.faAngleDoubleRight,
                 fa.faAngleDoubleDown,
                 fa.faAngleDoubleLeft,
                 fa.faAngleDoubleUp,
-                faBuffer as any,
+                faBuffer,
                 fa.faExpand,
                 fa.faUndo,
                 fa.faSlidersH,
@@ -570,7 +568,6 @@ export class MainView extends ObservableReactComponent<{}> {
         );
         DocumentManager.removeOverlayViews();
         Doc.linkFollowUnhighlight();
-        AudioBox.Enabled = true;
         const targets = document.elementsFromPoint(e.x, e.y);
         if (targets.length) {
             let targClass = targets[0].className.toString();
@@ -590,18 +587,6 @@ export class MainView extends ObservableReactComponent<{}> {
         document.addEventListener('pointerdown', this.globalPointerDown, true);
         document.addEventListener('pointermove', this.globalPointerMove, true);
         document.addEventListener('pointerup', this.globalPointerClick, true);
-        document.addEventListener(
-            'click',
-            (e: MouseEvent) => {
-                if (!e.cancelBubble) {
-                    const pathstr = (e as any)?.path?.map((p: any) => p.classList?.toString()).join();
-                    if (pathstr?.includes('libraryFlyout')) {
-                        DocumentView.DeselectAll();
-                    }
-                }
-            },
-            false
-        );
         document.oncontextmenu = () => false;
     };
 
@@ -777,7 +762,7 @@ export class MainView extends ObservableReactComponent<{}> {
             <div key="libFlyout" className="mainView-libraryFlyout" style={{ minWidth: this._leftMenuFlyoutWidth, width: this._leftMenuFlyoutWidth }}>
                 <div className="mainView-contentArea">
                     <DocumentView
-                        Document={this._sidebarContent.proto || this._sidebarContent}
+                        Document={DocCast(this._sidebarContent.proto, this._sidebarContent)}
                         addDocument={undefined}
                         addDocTab={DocumentViewInternal.addDocTabFunc}
                         pinToPres={DocumentView.PinDoc}
@@ -889,7 +874,7 @@ export class MainView extends ObservableReactComponent<{}> {
                 className="mainView-dashboardArea"
                 ref={r => {
                     r &&
-                        new _global.ResizeObserver(
+                        new ResizeObserver(
                             action(() => {
                                 this._dashUIWidth = r.getBoundingClientRect().width;
                                 this._dashUIHeight = r.getBoundingClientRect().height;
@@ -976,11 +961,11 @@ export class MainView extends ObservableReactComponent<{}> {
                     {[
                         ...SnappingManager.HorizSnapLines.map((l, i) => (
                             // eslint-disable-next-line react/no-array-index-key
-                            <line key={'horiz' + i} x1="0" y1={l} x2="2000" y2={l} stroke={lightOrDark(dragPar.layoutDoc.backgroundColor ?? 'gray')} opacity={0.3} strokeWidth={1} strokeDasharray="2 2" />
+                            <line key={'horiz' + i} x1="0" y1={l} x2="2000" y2={l} stroke={lightOrDark(StrCast(dragPar.layoutDoc.backgroundColor, 'gray'))} opacity={0.3} strokeWidth={1} strokeDasharray="2 2" />
                         )),
                         ...SnappingManager.VertSnapLines.map((l, i) => (
                             // eslint-disable-next-line react/no-array-index-key
-                            <line key={'vert' + i} y1={this.topOfMainDocContent.toString()} x1={l} y2="2000" x2={l} stroke={lightOrDark(dragPar.layoutDoc.backgroundColor ?? 'gray')} opacity={0.3} strokeWidth={1} strokeDasharray="2 2" />
+                            <line key={'vert' + i} y1={this.topOfMainDocContent.toString()} x1={l} y2="2000" x2={l} stroke={lightOrDark(StrCast(dragPar.layoutDoc.backgroundColor, 'gray'))} opacity={0.3} strokeWidth={1} strokeDasharray="2 2" />
                         )),
                     ]}
                 </svg>
@@ -1038,7 +1023,7 @@ export class MainView extends ObservableReactComponent<{}> {
                 }
                 ref={r => {
                     r &&
-                        new _global.ResizeObserver(
+                        new ResizeObserver(
                             action(() => {
                                 this._windowWidth = r.getBoundingClientRect().width;
                                 this._windowHeight = r.getBoundingClientRect().height;
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index a7907a565..7bf10467e 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -3,6 +3,7 @@ import { observer } from 'mobx-react';
 import { computedFn } from 'mobx-utils';
 import * as React from 'react';
 import ReactLoading from 'react-loading';
+import ResizeObserver from 'resize-observer-polyfill';
 import { returnEmptyDoclist, returnEmptyFilter, returnTrue, setupMoveUpEvents } from '../../ClientUtils';
 import { Utils, emptyFunction } from '../../Utils';
 import { Doc } from '../../fields/Doc';
@@ -18,8 +19,6 @@ import './OverlayView.scss';
 import { DefaultStyleProvider } from './StyleProvider';
 import { DocumentView, DocumentViewInternal } from './nodes/DocumentView';
 
-const _global = (window /* browser */ || global) /* node */ as any;
-
 export type OverlayDisposer = () => void;
 
 export type OverlayElementOptions = {
@@ -109,19 +108,19 @@ export class OverlayWindow extends ObservableReactComponent<OverlayWindowProps>
 }
 
 @observer
-export class OverlayView extends ObservableReactComponent<{}> {
+export class OverlayView extends ObservableReactComponent<object> {
     // eslint-disable-next-line no-use-before-define
     public static Instance: OverlayView;
     @observable.shallow _elements: JSX.Element[] = [];
 
-    constructor(props: any) {
+    constructor(props: object) {
         super(props);
         makeObservable(this);
         if (!OverlayView.Instance) {
             OverlayView.Instance = this;
-            new _global.ResizeObserver(
-                action((entries: any) => {
-                    Array.from(entries).forEach((entry: any) => {
+            new ResizeObserver(
+                action(entries => {
+                    Array.from(entries).forEach(entry => {
                         Doc.MyOverlayDocs.forEach(docIn => {
                             const doc = docIn;
                             if (NumCast(doc.overlayX) > entry.contentRect.width - 10) {
@@ -162,17 +161,17 @@ export class OverlayView extends ObservableReactComponent<{}> {
 
     @action
     addWindow(contents: JSX.Element, options: OverlayElementOptions): OverlayDisposer {
-        const remove = action(() => {
-            const index = this._elements.indexOf(contents);
+        const remove = action((wincontents: JSX.Element) => {
+            const index = this._elements.indexOf(wincontents);
             if (index !== -1) this._elements.splice(index, 1);
         });
         const wincontents = (
-            <OverlayWindow onClick={remove} key={Utils.GenerateGuid()} overlayOptions={options}>
+            <OverlayWindow onClick={() => remove(wincontents)} key={Utils.GenerateGuid()} overlayOptions={options}>
                 {contents}
             </OverlayWindow>
         );
         this._elements.push(wincontents);
-        return remove;
+        return () => remove(wincontents);
     }
 
     removeOverlayDoc = (docs: Doc | Doc[]) => toList(docs).every(Doc.RemFromMyOverlay);
diff --git a/src/client/views/ScriptingRepl.tsx b/src/client/views/ScriptingRepl.tsx
index 1a2eb460f..2de867746 100644
--- a/src/client/views/ScriptingRepl.tsx
+++ b/src/client/views/ScriptingRepl.tsx
@@ -1,6 +1,4 @@
 /* eslint-disable react/no-array-index-key */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
@@ -14,21 +12,26 @@ import { OverlayView } from './OverlayView';
 import './ScriptingRepl.scss';
 import { DocumentIconContainer } from './nodes/DocumentIcon';
 import { DocumentView } from './nodes/DocumentView';
+import { returnFalse, setupMoveUpEvents } from '../../ClientUtils';
+import { emptyFunction } from '../../Utils';
+import { ObjectField } from '../../fields/ObjectField';
+import { RefField } from '../../fields/RefField';
+import { Doc, FieldResult, FieldType, Opt } from '../../fields/Doc';
 
 interface replValueProps {
     scrollToBottom: () => void;
-    value: any;
+    value: Opt<FieldResult | Promise<RefField | undefined>>;
     name?: string;
 }
 @observer
 export class ScriptingValueDisplay extends ObservableReactComponent<replValueProps> {
-    constructor(props: any) {
+    constructor(props: replValueProps) {
         super(props);
         makeObservable(this);
     }
 
     render() {
-        const val = this._props.name ? this._props.value[this._props.name] : this._props.value;
+        const val = this._props.value instanceof Doc && this._props.name ? this._props.value[this._props.name] : this._props.value;
         const title = (name: string) => (
             <>
                 {this._props.name ? <b>{this._props.name} : </b> : <> </>}
@@ -47,13 +50,14 @@ export class ScriptingValueDisplay extends ObservableReactComponent<replValuePro
 }
 interface ReplProps {
     scrollToBottom: () => void;
-    value: { [key: string]: any };
+    value: Opt<FieldResult | Promise<RefField | undefined>>;
     name?: string;
 }
+@observer
 export class ScriptingObjectDisplay extends ObservableReactComponent<ReplProps> {
     @observable collapsed = true;
 
-    constructor(props: any) {
+    constructor(props: ReplProps) {
         super(props);
         makeObservable(this);
     }
@@ -74,10 +78,12 @@ export class ScriptingObjectDisplay extends ObservableReactComponent<ReplProps>
                 {name}
             </>
         );
+        if (val === undefined) return '--undefined--';
+        if (val instanceof Promise) return '...Promise...';
         if (this.collapsed) {
             return (
                 <div className="scriptingObject-collapsed">
-                    <span onClick={this.toggle} className="scriptingObject-icon scriptingObject-iconCollapsed">
+                    <span onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, this.toggle)} className="scriptingObject-icon scriptingObject-iconCollapsed">
                         <FontAwesomeIcon icon="caret-right" size="sm" />
                     </span>
                     {title} (+{Object.keys(val).length})
@@ -94,8 +100,7 @@ export class ScriptingObjectDisplay extends ObservableReactComponent<ReplProps>
                 </div>
                 <div className="scriptingObject-fields">
                     {Object.keys(val).map(key => (
-                        // eslint-disable-next-line react/jsx-props-no-spreading
-                        <ScriptingValueDisplay {...this._props} name={key} />
+                        <ScriptingValueDisplay name={key} key={key} value={this._props.value} scrollToBottom={this._props.scrollToBottom} />
                     ))}
                 </div>
             </div>
@@ -104,13 +109,13 @@ export class ScriptingObjectDisplay extends ObservableReactComponent<ReplProps>
 }
 
 @observer
-export class ScriptingRepl extends ObservableReactComponent<{}> {
-    constructor(props: any) {
+export class ScriptingRepl extends ObservableReactComponent<object> {
+    constructor(props: object) {
         super(props);
         makeObservable(this);
     }
 
-    @observable private commands: { command: string; result: any }[] = [];
+    @observable private commands: { command: string; result: unknown }[] = [];
     private commandsHistory: string[] = [];
 
     @observable private commandString: string = '';
@@ -120,13 +125,11 @@ export class ScriptingRepl extends ObservableReactComponent<{}> {
 
     private commandsRef = React.createRef<HTMLDivElement>();
 
-    private args: any = {};
-
     getTransformer = (): Transformer => ({
         transformer: context => {
             const knownVars: { [name: string]: number } = {};
             const usedDocuments: number[] = [];
-            ScriptingGlobals.getGlobals().forEach((global: any) => {
+            ScriptingGlobals.getGlobals().forEach((global: string) => {
                 knownVars[global] = 1;
             });
             return root => {
@@ -168,7 +171,7 @@ export class ScriptingRepl extends ObservableReactComponent<{}> {
         switch (e.key) {
             case 'Enter': {
                 e.stopPropagation();
-                const docGlobals: { [name: string]: any } = {};
+                const docGlobals: { [name: string]: FieldType } = {};
                 DocumentView.allViews().forEach((dv, i) => {
                     docGlobals[`d${i}`] = dv.Document;
                 });
@@ -176,19 +179,20 @@ export class ScriptingRepl extends ObservableReactComponent<{}> {
                 const script = CompileScript(this.commandString, { typecheck: false, addReturn: true, editable: true, params: { args: 'any' }, transformer: this.getTransformer(), globals });
                 if (!script.compiled) {
                     this.commands.push({ command: this.commandString, result: script.errors });
+                    this.maybeScrollToBottom();
                     return;
                 }
-                const result = undoable(() => script.run({ args: this.args }, () => this.commands.push({ command: this.commandString, result: e.toString() })), 'run:' + this.commandString)();
+                const result = undoable(() => script.run({}, e => this.commands.push({ command: this.commandString, result: e as string })), 'run:' + this.commandString)();
                 if (result.success) {
                     this.commands.push({ command: this.commandString, result: result.result });
                     this.commandsHistory.push(this.commandString);
 
-                    this.maybeScrollToBottom();
-
                     this.commandString = '';
                     this.commandBuffer = '';
                     this.historyIndex = -1;
                 }
+
+                this.maybeScrollToBottom();
                 break;
             }
             case 'ArrowUp': {
@@ -232,7 +236,7 @@ export class ScriptingRepl extends ObservableReactComponent<{}> {
     private shouldScroll: boolean = false;
     private maybeScrollToBottom = () => {
         const ele = this.commandsRef.current;
-        if (ele && ele.scrollTop === ele.scrollHeight - ele.offsetHeight) {
+        if (ele && Math.abs(Math.ceil(ele.scrollTop) - (ele.scrollHeight - ele.offsetHeight)) < 2) {
             this.shouldScroll = true;
             this.forceUpdate();
         }
@@ -240,14 +244,14 @@ export class ScriptingRepl extends ObservableReactComponent<{}> {
 
     private scrollToBottom() {
         const ele = this.commandsRef.current;
-        ele && ele.scroll({ behavior: 'auto', top: ele.scrollHeight });
+        ele?.scroll({ behavior: 'smooth', top: ele.scrollHeight });
     }
 
-    componentDidUpdate(prevProps: Readonly<{}>) {
+    componentDidUpdate(prevProps: Readonly<object>) {
         super.componentDidUpdate(prevProps);
         if (this.shouldScroll) {
             this.shouldScroll = false;
-            this.scrollToBottom();
+            setTimeout(() => this.scrollToBottom(), 0);
         }
     }
 
@@ -269,7 +273,7 @@ export class ScriptingRepl extends ObservableReactComponent<{}> {
                                 {command || <br />}
                             </div>
                             <div className="scriptingRepl-commandResult" style={{ background: SnappingManager.userBackgroundColor }}>
-                                <ScriptingValueDisplay scrollToBottom={this.maybeScrollToBottom} value={result} />
+                                <ScriptingValueDisplay scrollToBottom={this.maybeScrollToBottom} value={result as ObjectField | RefField} />
                             </div>
                         </div>
                     ))}
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 8a07a6bd7..b111904f3 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -21,7 +21,7 @@ import { undoBatch, UndoManager } from '../util/UndoManager';
 import { TreeSort } from './collections/TreeSort';
 import { Colors } from './global/globalEnums';
 import { DocumentView, DocumentViewProps } from './nodes/DocumentView';
-import { FieldViewProps, StyleProviderFuncType } from './nodes/FieldView';
+import { FieldViewProps } from './nodes/FieldView';
 import { StyleProp } from './StyleProp';
 import './StyleProvider.scss';
 
@@ -46,7 +46,7 @@ export function styleFromLayoutString(doc: Doc, props: FieldViewProps, scale: nu
         // bcz: this executes a script to convert a property expression string:  { script }  into a value
         ScriptField.MakeFunction(expr, { this: Doc.name, scale: 'number' })?.script.run({ this: doc, scale }).result?.toString() ?? '';
     divKeys.forEach((prop: string) => {
-        const p = (props as any)[prop];
+        const p = (props as FieldViewProps & { [key: string]: unknown })[prop];
         typeof p === 'string' && (style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer));
     });
     return style;
@@ -69,7 +69,7 @@ export function SetFilterOpener(func: () => void) {
 
 // a preliminary implementation of a dash style sheet for setting rendering properties of documents nested within a Tab
 //
-export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & DocumentViewProps>, property: string) : StyleProviderFuncType {
+export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps & DocumentViewProps>, property: string) {
     const remoteDocHeader = 'author;author_date;noMargin';
     const isCaption = property.includes(':caption');
     const isAnchor = property.includes(':anchor');
diff --git a/src/client/views/ViewBoxInterface.ts b/src/client/views/ViewBoxInterface.ts
index c633f34fb..dce64ab92 100644
--- a/src/client/views/ViewBoxInterface.ts
+++ b/src/client/views/ViewBoxInterface.ts
@@ -18,6 +18,9 @@ export abstract class ViewBoxInterface<P> extends ObservableReactComponent<React
     abstract get Document(): Doc;
     abstract get dataDoc(): Doc;
     abstract get fieldKey(): string;
+    get annotationKey(): string {
+        return ''; //
+    }
     promoteCollection?: () => void; // moves contents of collection to parent
     updateIcon?: () => void; // updates the icon representation of the document
     getAnchor?: (addAsAnnotation: boolean, pinData?: PinProps) => Doc; // returns an Anchor Doc that represents the current state of the doc's componentview (e.g., the current playhead location of a an audio/video box)
diff --git a/src/client/views/collections/CollectionCalendarView.tsx b/src/client/views/collections/CollectionCalendarView.tsx
index a08a7c7c1..9eb16917b 100644
--- a/src/client/views/collections/CollectionCalendarView.tsx
+++ b/src/client/views/collections/CollectionCalendarView.tsx
@@ -6,11 +6,11 @@ import { dateRangeStrToDates, returnTrue } from '../../../ClientUtils';
 import { Doc, DocListCast } from '../../../fields/Doc';
 import { StrCast } from '../../../fields/Types';
 import { CollectionStackingView } from './CollectionStackingView';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
 
 @observer
 export class CollectionCalendarView extends CollectionSubView() {
-    constructor(props: any) {
+    constructor(props: SubCollectionViewProps) {
         super(props);
         makeObservable(this);
     }
diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx
index de46180e6..28a769896 100644
--- a/src/client/views/collections/CollectionCardDeckView.tsx
+++ b/src/client/views/collections/CollectionCardDeckView.tsx
@@ -18,7 +18,7 @@ import { StyleProp } from '../StyleProp';
 import { DocumentView } from '../nodes/DocumentView';
 import { GPTPopup, GPTPopupMode } from '../pdf/GPTPopup/GPTPopup';
 import './CollectionCardDeckView.scss';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
 
 enum cardSortings {
     Time = 'time',
@@ -68,7 +68,7 @@ export class CollectionCardView extends CollectionSubView() {
         }
     };
 
-    constructor(props: any) {
+    constructor(props: SubCollectionViewProps) {
         super(props);
         makeObservable(this);
     }
@@ -86,11 +86,11 @@ export class CollectionCardView extends CollectionSubView() {
     }
 
     @computed get cardSort_customField() {
-        return StrCast(this.Document.cardSort_customField) as any as 'chat' | 'star' | 'idea' | 'like';
+        return StrCast(this.Document.cardSort_customField) as 'chat' | 'star' | 'idea' | 'like';
     }
 
     @computed get cardSort() {
-        return StrCast(this.Document.cardSort) as any as cardSortings;
+        return StrCast(this.Document.cardSort) as cardSortings;
     }
     /**
      * how much to scale down the contents of the view so that everything will fit
@@ -428,7 +428,6 @@ export class CollectionCardView extends CollectionSubView() {
         return (
             <div className="card-button-container" style={{ width: `${totalWidth}px` }}>
                 {numberRange(amButtons).map(i => (
-                    // eslint-disable-next-line jsx-a11y/control-has-associated-label
                     <button
                         key={i}
                         type="button"
@@ -496,8 +495,8 @@ export class CollectionCardView extends CollectionSubView() {
                 className="collectionCardView-outer"
                 ref={this.createDashEventsTarget}
                 style={{
-                    background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor),
-                    color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color),
+                    background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string,
+                    color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string,
                 }}>
                 <div
                     className="card-wrapper"
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 2adad68e0..c969c39e5 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 /* eslint-disable react/jsx-props-no-spreading */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { computed, makeObservable } from 'mobx';
@@ -18,7 +16,7 @@ import { DocumentView } from '../nodes/DocumentView';
 import { FieldViewProps } from '../nodes/FieldView';
 import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
 import './CollectionCarouselView.scss';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
 
 enum cardMode {
     PRACTICE = 'practice',
@@ -35,7 +33,7 @@ export class CollectionCarouselView extends CollectionSubView() {
     get practiceField() { return this.fieldKey + "_practice"; } // prettier-ignore
     get starField()     { return this.fieldKey + "_star"; } // prettier-ignore
 
-    constructor(props: any) {
+    constructor(props: SubCollectionViewProps) {
         super(props);
         makeObservable(this);
     }
@@ -124,7 +122,7 @@ export class CollectionCarouselView extends CollectionSubView() {
         this.advance(e);
     };
 
-    captionStyleProvider = (doc: Doc | undefined, captionProps: Opt<FieldViewProps>, property: string): any => {
+    captionStyleProvider = (doc: Doc | undefined, captionProps: Opt<FieldViewProps>, property: string) => {
         // first look for properties on the document in the carousel, then fallback to properties on the container
         const childValue = doc?.['caption_' + property] ? this._props.styleProvider?.(doc, captionProps, property) : undefined;
         return childValue ?? this._props.styleProvider?.(this.layoutDoc, captionProps, property);
@@ -161,7 +159,7 @@ export class CollectionCarouselView extends CollectionSubView() {
                         onDoubleClickScript={this.onContentDoubleClick}
                         onClickScript={this.onContentClick}
                         isDocumentActive={this._props.childDocumentsActive?.() ? this._props.isDocumentActive : this._props.isContentActive}
-                        isContentActive={this._props.childContentsActive ?? this._props.isContentActive() === false ? returnFalse : emptyFunction}
+                        isContentActive={(this._props.childContentsActive ?? this._props.isContentActive() === false) ? returnFalse : emptyFunction}
                         hideCaptions={!!carouselShowsCaptions} // hide captions if the carousel is configured to show the captions
                         renderDepth={this._props.renderDepth + 1}
                         LayoutTemplate={this._props.childLayoutTemplate}
@@ -177,7 +175,7 @@ export class CollectionCarouselView extends CollectionSubView() {
                         key="caption"
                         onWheel={StopEvent}
                         style={{
-                            borderRadius: this._props.styleProvider?.(this.layoutDoc, captionProps, StyleProp.BorderRounding),
+                            borderRadius: this._props.styleProvider?.(this.layoutDoc, captionProps, StyleProp.BorderRounding) as string,
                             marginRight: this.marginX,
                             marginLeft: this.marginX,
                             width: `calc(100% - ${this.marginX * 2}px)`,
@@ -218,8 +216,8 @@ export class CollectionCarouselView extends CollectionSubView() {
                 ref={this.createDashEventsTarget}
                 onContextMenu={this.specificMenu}
                 style={{
-                    background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor),
-                    color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color),
+                    background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string,
+                    color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string,
                 }}>
                 {this.content}
                 {/* Displays a message to the user to add more flashcards if they are in practice mode and no flashcards are there. */}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 5a142cc6e..e0aa79c7b 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -1,14 +1,15 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
 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';
+import ResizeObserver from 'resize-observer-polyfill';
 import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, DivHeight, DivWidth, incrementTitleCopy, returnTrue, UpdateIcon } from '../../../ClientUtils';
 import { Doc, DocListCast, Field, Opt } from '../../../fields/Doc';
 import { AclAdmin, AclEdit, DocData } from '../../../fields/DocSymbols';
 import { Id } from '../../../fields/FieldSymbols';
 import { InkTool } from '../../../fields/InkField';
 import { List } from '../../../fields/List';
+import { FieldType } from '../../../fields/ObjectField';
 import { ImageCast, NumCast, StrCast } from '../../../fields/Types';
 import { ImageField } from '../../../fields/URLField';
 import { GetEffectiveAcl, inheritParentAcls, SetPropSetterCb } from '../../../fields/util';
@@ -31,17 +32,15 @@ import { UndoStack } from '../UndoStack';
 import './CollectionDockingView.scss';
 import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
 
-const _global = (window /* browser */ || global) /* node */ as any;
-
 @observer
 export class CollectionDockingView extends CollectionSubView() {
-    static tabClass: JSX.Element | null = null;
+    static tabClass: unknown = null;
     /**
      * Initialize by assigning the add split method to DocumentView and by
      * configuring golden layout to render its documents using the specified React component
      * @param ele - typically would be set to TabDocView
      */
-    public static Init(ele: JSX.Element | null) {
+    public static Init(ele: unknown) {
         this.tabClass = ele;
         DocumentView.addSplit = CollectionDockingView.AddSplit;
     }
@@ -54,11 +53,13 @@ export class CollectionDockingView extends CollectionSubView() {
     private _flush: UndoManager.Batch | undefined;
     private _unmounting = false;
     private _ignoreStateChange = '';
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    private _goldenLayout: any = null;
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     public tabMap: Set<any> = new Set();
     public get HasFullScreen() {
         return this._goldenLayout._maximisedItem !== null;
     }
-    private _goldenLayout: any = null;
     static _highlightStyleSheet = addStyleSheet();
 
     constructor(props: SubCollectionViewProps) {
@@ -66,8 +67,8 @@ export class CollectionDockingView extends CollectionSubView() {
         makeObservable(this);
         if (this._props.renderDepth < 0) CollectionDockingView.Instance = this;
         // Why is this here?
-        (window as any).React = React;
-        (window as any).ReactDOM = ReactDOM;
+        (window as unknown as { React: unknown }).React = React;
+        (window as unknown as { ReactDOM: unknown }).ReactDOM = ReactDOM;
         DragManager.StartWindowDrag = this.StartOtherDrag;
         this.Document.myTrails; // this is equivalent to having a prefetchProxy for myTrails which is needed for the My Trails button in the UI which assumes that Doc.ActiveDashboard.myTrails is legit...
     }
@@ -89,10 +90,11 @@ export class CollectionDockingView extends CollectionSubView() {
     };
 
     tabItemDropped = () => DragManager.CompleteWindowDrag?.(false);
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     tabDragStart = (proxy: any, finishDrag?: (aborted: boolean) => void) => {
         this._flush = this._flush ?? UndoManager.StartBatch('tab move');
-        const dashDoc = proxy?._contentItem?.tab?.DashDoc as Doc;
-        dashDoc && (DragManager.DocDragData = new DragManager.DocumentDragData([proxy._contentItem.tab.DashDoc]));
+        //const dashDoc = proxy?._contentItem?.tab?.DashDoc as Doc;
+        //dashDoc && (DragManager.DocDragData = new DragManager.DocumentDragData([proxy._contentItem.tab.DashDoc]));
         DragManager.CompleteWindowDrag = (aborted: boolean) => {
             if (aborted) {
                 proxy._dragListener.AbortDrag();
@@ -130,12 +132,13 @@ export class CollectionDockingView extends CollectionSubView() {
     }
 
     @undoBatch
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     public static ReplaceTab(document: Doc, mods: OpenWhereMod, stack: any, panelName: string, addToSplit?: boolean, keyValue?: boolean): boolean {
         const instance = CollectionDockingView.Instance;
         if (!instance) return false;
         const newConfig = DashboardView.makeDocumentConfig(document, panelName, undefined, keyValue);
         if (!panelName && stack) {
-            const activeContentItemIndex = stack.contentItems.findIndex((item: any) => item.config === stack._activeContentItem.config);
+            const activeContentItemIndex = stack.contentItems.findIndex((item: { config: unknown }) => item.config === stack._activeContentItem.config);
             const newContentItem = stack.layoutManager.createContentItem(newConfig, instance._goldenLayout);
             stack.addChild(newContentItem.contentItems[0], undefined);
             stack.contentItems[activeContentItemIndex].remove();
@@ -155,6 +158,7 @@ export class CollectionDockingView extends CollectionSubView() {
     }
 
     @undoBatch
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     public static ToggleSplit(doc: Doc, location: OpenWhereMod, stack?: any, panelName?: string, keyValue?: boolean) {
         return Array.from(CollectionDockingView.Instance?.tabMap.keys() ?? []).findIndex(tab => tab.DashDoc === doc) !== -1 ? CollectionDockingView.CloseSplit(doc) : CollectionDockingView.AddSplit(doc, location, stack, panelName, keyValue);
     }
@@ -163,6 +167,7 @@ export class CollectionDockingView extends CollectionSubView() {
     //  Creates a split on any side of the docking view based on the passed input pullSide and then adds the Document to the requested side
     //
     @action
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     public static AddSplit(document: Doc, pullSide: OpenWhereMod, stack?: any, panelName?: string, keyValue?: boolean) {
         if (document?._type_collection === CollectionViewType.Docking && !keyValue) return DashboardView.openDashboard(document);
         if (!CollectionDockingView.Instance) return false;
@@ -321,7 +326,7 @@ export class CollectionDockingView extends CollectionSubView() {
      * @param target
      * @param title
      */
-    titleChanged = (target: any, value: any) => {
+    titleChanged = (target: Doc, value: FieldType) => {
         const title = Field.toString(value);
         if (title.startsWith('@') && !title.substring(1).match(/[()[\]@]/) && title.length > 1) {
             const embedding = DocListCast(target.proto_embeddings).lastElement();
@@ -340,7 +345,7 @@ export class CollectionDockingView extends CollectionSubView() {
                 () => DocumentView.LightboxDoc(),
                 doc => setTimeout(() => !doc && this.onResize())
             );
-            new _global.ResizeObserver(this.onResize).observe(this._containerRef.current);
+            new ResizeObserver(this.onResize).observe(this._containerRef.current);
             this._reactionDisposer = reaction(
                 () => StrCast(this.Document.dockingConfig),
                 config => {
@@ -429,7 +434,7 @@ export class CollectionDockingView extends CollectionSubView() {
     @action
     onPointerDown = (e: React.PointerEvent): void => {
         let hitFlyout = false;
-        for (let par = e.target as any; !hitFlyout && par; par = par.parentElement) {
+        for (let par = e.target as HTMLElement | null; !hitFlyout && par; par = par.parentElement) {
             hitFlyout = par.className === 'dockingViewButtonSelector';
         }
         if (!hitFlyout) {
@@ -514,6 +519,7 @@ export class CollectionDockingView extends CollectionSubView() {
         return changesMade;
     };
 
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     tabDestroyed = (tab: any) => {
         this._flush = this._flush ?? UndoManager.StartBatch('tab movement');
         const dashDoc = tab.DashDoc;
@@ -531,18 +537,21 @@ export class CollectionDockingView extends CollectionSubView() {
             const { fieldKey } = CollectionDockingView.Instance.props;
             Doc.RemoveDocFromList(dview, fieldKey, dashDoc);
             this.tabMap.delete(tab);
-            tab._disposers && Object.values(tab._disposers).forEach((disposer: any) => disposer?.());
+            tab._disposers && Object.values(tab._disposers).forEach(disposer => (disposer as () => void)());
             this.stateChanged();
         }
     };
-    tabCreated = (tab: any) => {
+    tabCreated = (tab: { contentItem: { element: HTMLElement[] } }) => {
         this.tabMap.add(tab);
-        tab.contentItem.element[0]?.firstChild?.firstChild?.InitTab?.(tab); // have to explicitly initialize tabs that reuse contents from previous tabs (ie, when dragging a tab around a new tab is created for the old content)
+        // InitTab is added to the tab's HTMLElement in TabDocView
+        const tabdocviewContent = tab.contentItem.element[0]?.firstChild?.firstChild as unknown as { InitTab?: (tab: object) => void };
+        tabdocviewContent?.InitTab?.(tab); // have to explicitly initialize tabs that reuse contents from previous tabs (ie, when dragging a tab around a new tab is created for the old content)
     };
 
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     stackCreated = (stackIn: any) => {
         const stack = stackIn.header ? stackIn : stackIn.origin;
-        stack.header?.element.on('mousedown', (e: any) => {
+        stack.header?.element.on('mousedown', (e: MouseEvent) => {
             const dashboard = Doc.ActiveDashboard;
             if (dashboard && e.target === stack.header?.element[0] && e.button === 2) {
                 dashboard.pane_count = NumCast(dashboard.pane_count) + 1;
@@ -595,7 +604,7 @@ export class CollectionDockingView extends CollectionSubView() {
                 })
             );
 
-        stack.element.click((e: any) => {
+        stack.element.click((e: { originalEvent: MouseEvent }) => {
             if (stack.contentItems.length === 0 && Array.from(document.elementsFromPoint(e.originalEvent.x, e.originalEvent.y)).some(ele => ele?.className === 'empty-tabs-message')) {
                 addNewDoc();
             }
@@ -633,7 +642,7 @@ export class CollectionDockingView extends CollectionSubView() {
 
 ScriptingGlobals.add(
     // eslint-disable-next-line prefer-arrow-callback
-    function openInLightbox(doc: any) {
+    function openInLightbox(doc: Doc) {
         CollectionDockingView.Instance?._props.addDocTab(doc, OpenWhere.lightboxAlways);
     },
     'opens up document in a lightbox',
@@ -641,33 +650,22 @@ ScriptingGlobals.add(
 );
 ScriptingGlobals.add(
     // eslint-disable-next-line prefer-arrow-callback
-    function openDoc(doc: any, where: OpenWhere) {
+    function openDoc(doc: Doc | string, where: OpenWhere) {
         switch (where) {
             case OpenWhere.addRight:
-                return CollectionDockingView.AddSplit(doc, OpenWhereMod.right);
+                return doc instanceof Doc && CollectionDockingView.AddSplit(doc, OpenWhereMod.right);
             case OpenWhere.overlay:
             default:
-                // prettier-ignore
                 switch (doc) {
                     case '<ScriptingRepl />': return OverlayView.Instance.addWindow(<ScriptingRepl />, { x: 300, y: 100, width: 200, height: 200, title: 'Scripting REPL' });
                     case "<UndoStack />": return OverlayView.Instance.addWindow(<UndoStack />, { x: 300, y: 100, width: 200, height: 200, title: 'Undo stack' });
-                    default: 
-                }
-                Doc.AddToMyOverlay(doc);
-                return true;
+                    default: return doc instanceof Doc && Doc.AddToMyOverlay(doc);
+                } // prettier-ignore
         }
     },
     'opens up document in location specified',
     '(doc: any)'
 );
-ScriptingGlobals.add(
-    // eslint-disable-next-line prefer-arrow-callback
-    function openRepl() {
-        return 'openRepl';
-    },
-    'opens up document in screen overlay layer',
-    '(doc: any)'
-);
 // eslint-disable-next-line prefer-arrow-callback
 ScriptingGlobals.add(async function snapshotDashboard() {
     const batch = UndoManager.StartBatch('snapshot');
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 9a6f1e2eb..710c00841 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -1,6 +1,3 @@
-/* eslint-disable jsx-a11y/control-has-associated-label */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, makeObservable, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
@@ -16,7 +13,7 @@ import { DragManager } from '../../util/DragManager';
 import { CompileScript } from '../../util/Scripting';
 import { SnappingManager } from '../../util/SnappingManager';
 import { Transform } from '../../util/Transform';
-import { undoBatch } from '../../util/UndoManager';
+import { undoBatch, undoable } from '../../util/UndoManager';
 import { EditableView } from '../EditableView';
 import { ObservableReactComponent } from '../ObservableReactComponent';
 import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
@@ -37,13 +34,13 @@ interface CMVFieldRowProps {
     createDropTarget: (ele: HTMLDivElement) => void;
     screenToLocalTransform: () => Transform;
     setDocHeight: (key: string, thisHeight: number) => void;
-    refList: any[];
+    refList: Element[];
     showHandle: boolean;
 }
 
 @observer
 export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVFieldRowProps> {
-    constructor(props: any) {
+    constructor(props: CMVFieldRowProps) {
         super(props);
         makeObservable(this);
     }
@@ -73,7 +70,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
     private _dropDisposer?: DragManager.DragDropDisposer;
     private _headerRef: React.RefObject<HTMLDivElement> = React.createRef();
     private _contRef: React.RefObject<HTMLDivElement> = React.createRef();
-    private _ele: any;
+    private _ele: HTMLDivElement | null = null;
 
     createRowDropRef = (ele: HTMLDivElement | null) => {
         this._dropDisposer?.();
@@ -118,7 +115,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
         return false;
     });
 
-    getValue = (value: string): any => {
+    getValue = (value: string) => {
         const parsed = parseInt(value);
         if (!isNaN(parsed)) return parsed;
         if (value.toLowerCase().indexOf('true') > -1) return true;
@@ -173,7 +170,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
         return docs ? !!docs.splice(0, 0, newDoc) : this._props.parent._props.addDocument?.(newDoc) || false; // should really extend addDocument to specify insertion point (at beginning of list)
     };
 
-    deleteRow = undoBatch(
+    deleteRow = undoable(
         action(() => {
             this._createEmbeddingSelected = false;
             const key = this._props.pivotField;
@@ -182,11 +179,12 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
                 const index = this._props.parent.colHeaderData.indexOf(this._props.headingObject);
                 this._props.parent.colHeaderData.splice(index, 1);
             }
-        })
+        }),
+        'delete row'
     );
 
     @action
-    collapseSection = (e: any) => {
+    collapseSection = (e: PointerEvent) => {
         this._createEmbeddingSelected = false;
         this.toggleVisibility();
         e.stopPropagation();
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index b2f0280a5..7b9475590 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -1,7 +1,3 @@
-/* eslint-disable jsx-a11y/label-has-associated-control */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
-/* eslint-disable jsx-a11y/control-has-associated-label */
 /* eslint-disable react/no-unused-class-component-methods */
 /* eslint-disable react/sort-comp */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index 16c474996..e1f0a3e41 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -30,9 +30,8 @@ import { StyleProp } from '../StyleProp';
 import './CollectionNoteTakingView.scss';
 import { CollectionNoteTakingViewColumn } from './CollectionNoteTakingViewColumn';
 import { CollectionNoteTakingViewDivider } from './CollectionNoteTakingViewDivider';
-import { CollectionSubView } from './CollectionSubView';
-
-const _global = (window /* browser */ || global) /* node */ as any;
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
+import { Property } from 'csstype';
 
 /**
  * CollectionNoteTakingView is a column-based view for displaying documents. In this view, the user can (1)
@@ -52,9 +51,9 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     public DividerWidth = 16;
     @observable docsDraggedRowCol: number[] = [];
     @observable _scroll = 0;
-    @observable _refList: any[] = [];
+    @observable _refList: HTMLElement[] = [];
 
-    constructor(props: any) {
+    constructor(props: SubCollectionViewProps) {
         super(props);
         makeObservable(this);
     }
@@ -78,7 +77,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
         return colHeaderData ?? ([] as SchemaHeaderField[]);
     }
     @computed get headerMargin() {
-        return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HeaderMargin);
+        return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HeaderMargin) as number;
     }
     @computed get xMargin() {
         return NumCast(this.layoutDoc._xMargin, 5);
@@ -216,7 +215,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     // let's dive in and get the actual document we want to drag/move around
     focusDocument = (doc: Doc, options: FocusViewOptions) => {
         Doc.BrushDoc(doc);
-        const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName('documentView-node')).find((node: any) => node.id === doc[Id]);
+        const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName('documentView-node')).find(node => node.id === doc[Id]);
         if (found) {
             const { top } = found.getBoundingClientRect();
             const localTop = this.ScreenToLocalBoxXf().transformPoint(0, top);
@@ -295,7 +294,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
                 addDocument={this._props.addDocument}
                 moveDocument={this._props.moveDocument}
                 removeDocument={this._props.removeDocument}
-                contentPointerEvents={StrCast(this.layoutDoc.childContentPointerEvents) as any}
+                contentPointerEvents={StrCast(this.layoutDoc.childContentPointerEvents) as Property.PointerEvents}
                 whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged}
                 addDocTab={this._props.addDocTab}
                 pinToPres={this._props.pinToPres}
@@ -313,14 +312,14 @@ export class CollectionNoteTakingView extends CollectionSubView() {
 
     // how to get the width of a document. Currently returns the width of the column (minus margins)
     // if a note doc. Otherwise, returns the normal width (for graphs, images, etc...)
-    getDocWidth(d: Doc) {
+    getDocWidth = (d: Doc) => {
         const heading = !d[this.notetakingCategoryField] ? 'unset' : Field.toString(d[this.notetakingCategoryField] as FieldType);
         const existingHeader = this.colHeaderData.find(sh => sh.heading === heading);
         const existingWidth = this.layoutDoc._notetaking_columns_autoSize ? 1 / (this.colHeaderData.length ?? 1) : existingHeader?.width ? existingHeader.width : 0;
         const maxWidth = existingWidth > 0 ? existingWidth * this.availableWidth : this.maxColWidth;
         const width = d.layout_fitWidth ? maxWidth : NumCast(d._width);
         return Math.min(maxWidth - CollectionNoteTakingViewColumn.ColumnMargin, width < maxWidth ? width : maxWidth);
-    }
+    };
 
     // how to get the height of a document. Nothing special here.
     getDocHeight(d?: Doc) {
@@ -364,7 +363,8 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     // onPointerMove is used to preview where a document will drop in a column once a drag is complete.
     @action
     onPointerMove = (force: boolean, ex: number, ey: number) => {
-        if (this.childDocList?.includes(DragManager.DocDragData?.draggedDocuments?.lastElement() as any) || force || SnappingManager.CanEmbed) {
+        const dragDoc = DragManager.DraggedDocs?.lastElement();
+        if ((dragDoc && this.childDocList?.includes(dragDoc)) || force || SnappingManager.CanEmbed) {
             // get the current docs for the column based on the mouse's x coordinate
             const xCoord = this.ScreenToLocalBoxXf().transformPoint(ex, ey)[0] - 2 * this.gridGap;
             const colDocs = this.getDocsFromXCoord(xCoord);
@@ -500,7 +500,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
         super.onExternalDrop(
             e,
             {},
-            undoBatch(
+            undoable(
                 action(docus => {
                     this.onPointerMove(true, e.clientX, e.clientY);
                     docus?.map((doc: Doc) => this.addDocument(doc));
@@ -513,7 +513,8 @@ export class CollectionNoteTakingView extends CollectionSubView() {
                         docs.splice(targInd, 0, newDoc);
                     }
                     this.removeDocDragHighlight();
-                })
+                }),
+                'drop into note view'
             )
         );
     };
@@ -673,7 +674,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
         return this.isContentActive() === false ? 'none' : undefined;
     }
 
-    observer = new _global.ResizeObserver(() => this._props.setHeight?.(this.headerMargin + Math.max(...this._refList.map(DivHeight))));
+    observer = new ResizeObserver(() => this._props.setHeight?.(this.headerMargin + Math.max(...this._refList.map(DivHeight))));
 
     render() {
         TraceMobx();
diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
index 44ab1968d..8c6a6b551 100644
--- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable jsx-a11y/control-has-associated-label */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
@@ -16,7 +15,7 @@ import { SnappingManager } from '../../util/SnappingManager';
 import { Transform } from '../../util/Transform';
 import { undoBatch, undoable } from '../../util/UndoManager';
 import { ContextMenu } from '../ContextMenu';
-import { EditableView } from '../EditableView';
+import { EditableProps, EditableView } from '../EditableView';
 import { ObservableReactComponent } from '../ObservableReactComponent';
 import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
 import './CollectionNoteTakingView.scss';
@@ -24,7 +23,7 @@ import './CollectionNoteTakingView.scss';
 interface CSVFieldColumnProps {
     Document: Doc;
     TemplateDataDocument: Opt<Doc>;
-    backgroundColor?: (() => string) | undefined;
+    backgroundColor?: () => string | undefined;
     docList: Doc[];
     heading: string;
     pivotField: string;
@@ -35,15 +34,15 @@ interface CSVFieldColumnProps {
     yMargin: number;
     numGroupColumns: number;
     gridGap: number;
-    headings: () => object[];
+    headings: () => [SchemaHeaderField, Doc[]][];
     select: (ctrlPressed: boolean) => void;
     isContentActive: () => boolean | undefined;
     renderChildren: (docs: Doc[]) => JSX.Element[];
     addDocument: (doc: Doc | Doc[]) => boolean;
     createDropTarget: (ele: HTMLDivElement) => void;
     screenToLocalTransform: () => Transform;
-    refList: any[];
-    editableViewProps: () => any;
+    refList: HTMLElement[];
+    editableViewProps: () => EditableProps;
     resizeColumns: (headers: SchemaHeaderField[]) => boolean;
     maxColWidth: number;
     dividerWidth: number;
@@ -103,7 +102,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
         return true;
     };
 
-    getValue = (value: string): any => {
+    getValue = (value: string) => {
         const parsed = parseInt(value);
         if (!isNaN(parsed)) return parsed;
         if (value.toLowerCase().indexOf('true') > -1) return true;
@@ -272,7 +271,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
                 style={{
                     width: this.columnWidth,
                     background: this._hover && SnappingManager.IsDragging ? '#b4b4b4' : 'inherit',
-                    marginLeft: this._props.headings().findIndex((h: any) => h[0] === this._props.headingObject) === 0 ? NumCast(this._props.Document.xMargin) : 0,
+                    marginLeft: this._props.headings().findIndex(h => h[0] === this._props.headingObject) === 0 ? NumCast(this._props.Document.xMargin) : 0,
                 }}>
                 <div className="collectionNoteTakingViewFieldColumn" key={this._heading} ref={this.createColumnDropRef}>
                     {this.innards}
diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx
index 5b3f625db..eea128803 100644
--- a/src/client/views/collections/CollectionPileView.tsx
+++ b/src/client/views/collections/CollectionPileView.tsx
@@ -1,10 +1,8 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { action, computed, IReactionDisposer, makeObservable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { returnFalse, setupMoveUpEvents } from '../../../ClientUtils';
-import { Doc, DocListCast } from '../../../fields/Doc';
+import { Doc, DocListCast, FieldResult } from '../../../fields/Doc';
 import { ScriptField } from '../../../fields/ScriptField';
 import { NumCast, StrCast, toList } from '../../../fields/Types';
 import { emptyFunction } from '../../../Utils';
@@ -15,15 +13,15 @@ import { OpenWhere } from '../nodes/OpenWhere';
 import { computePassLayout, computeStarburstLayout } from './collectionFreeForm';
 import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
 import './CollectionPileView.scss';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
 import { DocumentView } from '../nodes/DocumentView';
 
 @observer
 export class CollectionPileView extends CollectionSubView() {
-    _originalChrome: any = '';
+    _originalChrome: FieldResult = '';
     _disposers: { [name: string]: IReactionDisposer } = {};
 
-    constructor(props: any) {
+    constructor(props: SubCollectionViewProps) {
         super(props);
         makeObservable(this);
     }
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index b03f0cffa..08f3f3d65 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -1,8 +1,5 @@
 /* eslint-disable react/jsx-props-no-spreading */
-/* eslint-disable jsx-a11y/alt-text */
 /* eslint-disable no-use-before-define */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import { computedFn } from 'mobx-utils';
@@ -34,7 +31,7 @@ import { LabelBox } from '../nodes/LabelBox';
 import { OpenWhere } from '../nodes/OpenWhere';
 import { ObservableReactComponent } from '../ObservableReactComponent';
 import './CollectionStackedTimeline.scss';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
 
 export type CollectionStackedTimelineProps = {
     Play: () => void;
@@ -72,7 +69,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
         );
         this.SelectingRegions.clear();
     }
-    constructor(props: any) {
+    constructor(props: SubCollectionViewProps & CollectionStackedTimelineProps) {
         super(props);
         makeObservable(this);
     }
@@ -182,7 +179,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
         });
 
     anchorStart = (anchor: Doc) => NumCast(anchor._timecodeToShow, NumCast(anchor[this._props.startTag]));
-    anchorEnd = (anchor: Doc, val: any = null) => NumCast(anchor._timecodeToHide, NumCast(anchor[this._props.endTag], val) ?? null);
+    anchorEnd = (anchor: Doc, val?: number) => NumCast(anchor._timecodeToHide, NumCast(anchor[this._props.endTag], val) ?? null);
 
     // converts screen pixel offset to time
     // prettier-ignore
@@ -192,13 +189,13 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
     @computed get rangeClick() {
         // prettier-ignore
         return ScriptField.MakeFunction('stackedTimeline.clickAnchor(this, clientX)',
-            { stackedTimeline: 'any', clientX: 'number' }, { stackedTimeline: this as any }
+            { stackedTimeline: 'any', clientX: 'number' }, { stackedTimeline: 'string' /* should be CollectionStackedTimeline */ }
         )!;
     }
     @computed get rangePlay() {
         // prettier-ignore
         return ScriptField.MakeFunction('stackedTimeline.playOnClick(this, clientX)', 
-            { stackedTimeline: 'any', clientX: 'number' }, { stackedTimeline: this as any })!;
+            { stackedTimeline: 'any', clientX: 'number' }, { stackedTimeline: 'string'  /* should be CollectionStackedTimeline */})!;
     }
     rangeClickScript = () => this.rangeClick;
     rangePlayScript = () => this.rangePlay;
@@ -426,7 +423,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
         const anchor =
             docAnchor ??
             Docs.Create.LabelDocument({
-                title: ComputedField.MakeFunction(`this["${endTag}"] ? "#" + formatToTime(this["${startTag}"]) + "-" + formatToTime(this["${endTag}"]) : "#" + formatToTime(this["${startTag}"])`) as any,
+                title: ComputedField.MakeFunction(`this["${endTag}"] ? "#" + formatToTime(this["${startTag}"]) + "-" + formatToTime(this["${endTag}"]) : "#" + formatToTime(this["${startTag}"])`) as unknown as string, // title can take a function or a string
                 _label_minFontSize: 12,
                 _label_maxFontSize: 24,
                 _dragOnlyWithinContainer: true,
@@ -777,8 +774,8 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch
     @action
     onAnchorDown = (e: React.PointerEvent, anchor: Doc, left: boolean): void => {
         const newTime = (timeDownEv: PointerEvent) => {
-            const rect = (timeDownEv.target as any).getBoundingClientRect();
-            return this._props.toTimeline(timeDownEv.clientX - rect.x, rect.width);
+            const rect = (timeDownEv.target as HTMLElement).getBoundingClientRect?.();
+            return !rect ? 0 : this._props.toTimeline(timeDownEv.clientX - rect.x, rect.width);
         };
         const changeAnchor = (time: number | undefined) => {
             const timelineOnly = Cast(anchor[this._props.startTag], 'number', null) !== undefined;
@@ -892,7 +889,7 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch
     }
 }
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function formatToTime(time: number): any {
+ScriptingGlobals.add(function formatToTime(time: number): string {
     return formatTime(time);
 });
 // eslint-disable-next-line prefer-arrow-callback
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 56d2a6c9c..03ade6579 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -1,6 +1,5 @@
 /* eslint-disable react/jsx-props-no-spreading */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-// eslint-disable-next-line import/no-extraneous-dependencies
 import * as CSS from 'csstype';
 import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
@@ -34,9 +33,7 @@ import { StyleProp } from '../StyleProp';
 import { CollectionMasonryViewFieldRow } from './CollectionMasonryViewFieldRow';
 import './CollectionStackingView.scss';
 import { CollectionStackingViewFieldColumn } from './CollectionStackingViewFieldColumn';
-import { CollectionSubView } from './CollectionSubView';
-
-const _global = (window /* browser */ || global) /* node */ as any;
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
 
 export type collectionStackingViewProps = {
     sortFunc?: (a: Doc, b: Doc) => number;
@@ -57,8 +54,9 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
     _docXfs: { height: () => number; width: () => number; stackedDocTransform: () => Transform }[] = [];
     // Doesn't look like this field is being used anywhere. Obsolete?
     _columnStart: number = 0;
+    _oldWheel: HTMLElement | null = null;
 
-    @observable _refList: any[] = [];
+    @observable _refList: HTMLElement[] = [];
     // map of node headers to their heights. Used in Masonry
     @observable _heightMap = new Map<string, number>();
     // Assuming that this is the current css cursor style
@@ -85,7 +83,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
     }
     // how much margin we give the header
     @computed get headerMargin() {
-        return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HeaderMargin);
+        return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HeaderMargin) as number;
     }
     @computed get xMargin() {
         return NumCast(this.layoutDoc._xMargin, Math.max(3, 0.05 * this._props.PanelWidth()));
@@ -118,7 +116,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
         return this._props.PanelWidth() - this.gridGap;
     }
 
-    constructor(props: any) {
+    constructor(props: SubCollectionViewProps) {
         super(props);
         makeObservable(this);
         if (this.colHeaderData === undefined) {
@@ -260,7 +258,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
     focusDocument = (doc: Doc, options: FocusViewOptions) => {
         Doc.BrushDoc(doc);
 
-        const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName('documentView-node')).find((node: any) => node.id === doc[Id]);
+        const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName('documentView-node')).find(node => node.id === doc[Id]);
         if (found) {
             const { top } = found.getBoundingClientRect();
             const localTop = this.ScreenToLocalBoxXf().transformPoint(0, top);
@@ -344,7 +342,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
                 LayoutTemplateString={this._props.childLayoutString}
                 NativeWidth={this._props.childIgnoreNativeSize ? returnZero : this._props.childLayoutFitWidth?.(doc) || (this.childFitWidth(doc) && !Doc.NativeWidth(doc)) ? width : undefined} // explicitly ignore nativeWidth/height if childIgnoreNativeSize is set- used by PresBox
                 NativeHeight={this._props.childIgnoreNativeSize ? returnZero : this._props.childLayoutFitWidth?.(doc) || (this.childFitWidth(doc) && !Doc.NativeHeight(doc)) ? height : undefined}
-                dontCenter={this._props.childIgnoreNativeSize ? 'xy' : (StrCast(this.layoutDoc.layout_dontCenter) as any)}
+                dontCenter={this._props.childIgnoreNativeSize ? 'xy' : (StrCast(this.layoutDoc.layout_dontCenter) as 'x' | 'y' | 'xy')}
                 dontRegisterView={BoolCast(this.layoutDoc.childDontRegisterViews, this._props.dontRegisterView)} // used to be true if DataDoc existed, but template textboxes won't layout_autoHeight resize if dontRegisterView is set, but they need to.
                 rootSelected={this.rootSelected}
                 showTitle={this._props.childlayout_showTitle}
@@ -363,7 +361,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
                 addDocument={this._props.addDocument}
                 moveDocument={this._props.moveDocument}
                 removeDocument={this._props.removeDocument}
-                contentPointerEvents={StrCast(this.layoutDoc.childContentPointerEvents) as any}
+                contentPointerEvents={StrCast(this.layoutDoc.childContentPointerEvents) as CSS.Property.PointerEvents | undefined}
                 whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged}
                 addDocTab={this._props.addDocTab}
                 pinToPres={this._props.pinToPres}
@@ -623,7 +621,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
         if (!e.isPropagationStopped()) {
             const cm = ContextMenu.Instance;
             const options = cm.findByDescription('Options...');
-            const optionItems: ContextMenuProps[] = options && 'subitems' in options ? options.subitems : [];
+            const optionItems: ContextMenuProps[] = options?.subitems ?? [];
             optionItems.push({ description: `${this.layoutDoc._columnsFill ? 'Variable Size' : 'Autosize'} Column`, event: () => { this.layoutDoc._columnsFill = !this.layoutDoc._columnsFill; }, icon: 'plus' }); // prettier-ignore
             optionItems.push({ description: `${this.layoutDoc._layout_autoHeight ? 'Variable Height' : 'Auto Height'}`, event: () => { this.layoutDoc._layout_autoHeight = !this.layoutDoc._layout_autoHeight; }, icon: 'plus' }); // prettier-ignore
             optionItems.push({ description: 'Clear All', event: () => { this.dataDoc[this.fieldKey ?? 'data'] = new List([]); } , icon: 'times' }); // prettier-ignore
@@ -688,10 +686,9 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
         return this._props.isContentActive() === false ? 'none' : undefined;
     }
 
-    observer = new _global.ResizeObserver(() => this._props.setHeight?.(this.headerMargin + (this.isStackingView ? Math.max(...this._refList.map(DivHeight)) : this._refList.reduce((p, r) => p + DivHeight(r), 0))));
+    observer = new ResizeObserver(() => this._props.setHeight?.(this.headerMargin + (this.isStackingView ? Math.max(...this._refList.map(DivHeight)) : this._refList.reduce((p, r) => p + DivHeight(r), 0))));
 
     onPassiveWheel = (e: WheelEvent) => e.stopPropagation();
-    _oldWheel: any;
     render() {
         TraceMobx();
         const editableViewProps = {
@@ -722,8 +719,8 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
                         }}
                         style={{
                             overflowY: this.isContentActive() ? 'auto' : 'hidden',
-                            background: this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor),
-                            pointerEvents: (this._props.pointerEvents?.() as any) ?? this.backgroundEvents,
+                            background: this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor) as string,
+                            pointerEvents: this._props.pointerEvents?.() ?? this.backgroundEvents,
                         }}
                         onScroll={action(e => {
                             this._scroll = e.currentTarget.scrollTop;
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index b7169ece0..5782d407e 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -22,7 +22,7 @@ import { DragManager } from '../../util/DragManager';
 import { dropActionType } from '../../util/DropActionTypes';
 import { ImageUtils } from '../../util/Import & Export/ImageUtils';
 import { SnappingManager } from '../../util/SnappingManager';
-import { UndoManager, undoBatch } from '../../util/UndoManager';
+import { UndoManager } from '../../util/UndoManager';
 import { ViewBoxBaseComponent } from '../DocComponent';
 import { FieldViewProps } from '../nodes/FieldView';
 import { DocumentView } from '../nodes/DocumentView';
@@ -227,7 +227,6 @@ export function CollectionSubView<X>() {
             }
         }
 
-        @undoBatch
         // eslint-disable-next-line @typescript-eslint/no-unused-vars
         protected onGesture(e: Event, ge: GestureUtils.GestureEvent) {}
 
@@ -294,7 +293,6 @@ export function CollectionSubView<X>() {
             return false;
         }
 
-        @undoBatch
         protected async onExternalDrop(e: React.DragEvent, options: DocumentOptions, completed?: (docs: Doc[]) => void) {
             if (e.ctrlKey) {
                 e.stopPropagation(); // bcz: this is a hack to stop propagation when dropping an image on a text document with shift+ctrl
@@ -386,7 +384,7 @@ export function CollectionSubView<X>() {
                         addDocument(htmlDoc);
                         if (srcWeb) {
                             const iframe = DocumentView.Selected()[0].ContentDiv?.getElementsByTagName('iframe')?.[0];
-                            const focusNode = iframe?.contentDocument?.getSelection()?.focusNode as any;
+                            const focusNode = iframe?.contentDocument?.getSelection()?.focusNode;
                             if (focusNode) {
                                 const anchor = srcWeb?.ComponentView?.getAnchor?.(true);
                                 anchor && DocUtils.MakeLink(htmlDoc, anchor, {});
@@ -465,23 +463,6 @@ export function CollectionSubView<X>() {
                 if (item.kind === 'file') {
                     const file = item.getAsFile();
                     file?.type && files.push(file);
-
-                    file?.type === 'application/json' &&
-                        ClientUtils.readUploadedFileAsText(file).then(result => {
-                            const json = JSON.parse(result as string);
-                            addDocument(
-                                Docs.Create.TreeDocument(
-                                    json['rectangular-puzzle'].crossword.clues[0].clue.map((c: any) => {
-                                        const label = Docs.Create.LabelDocument({ title: c['#text'], _width: 120, _height: 20 });
-                                        const proto = Doc.GetProto(label);
-                                        proto._width = 120;
-                                        proto._height = 20;
-                                        return proto;
-                                    }),
-                                    { _width: 150, _height: 600, title: 'across', backgroundColor: 'white', _createDocOnCR: true }
-                                )
-                            );
-                        });
                 }
             }
             this.slowLoadDocuments(files, options, generatedDocuments, text, completed, addDocument).then(batch.end);
diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx
index 0369e4a2a..8a24db330 100644
--- a/src/client/views/collections/CollectionTimeView.tsx
+++ b/src/client/views/collections/CollectionTimeView.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { action, computed, makeObservable, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -18,7 +16,7 @@ import { ContextMenuProps } from '../ContextMenuItem';
 import { FieldsDropdown } from '../FieldsDropdown';
 import { PinDocView } from '../PinFuncs';
 import { DocumentView } from '../nodes/DocumentView';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
 import './CollectionTimeView.scss';
 import { ViewDefBounds, computePivotLayout, computeTimelineLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines';
 import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
@@ -32,7 +30,7 @@ export class CollectionTimeView extends CollectionSubView() {
     @observable _viewDefDivClick: Opt<ScriptField> = undefined;
     @observable _focusPivotField: Opt<string> = undefined;
 
-    constructor(props: any) {
+    constructor(props: SubCollectionViewProps) {
         super(props);
         makeObservable(this);
     }
@@ -51,7 +49,7 @@ export class CollectionTimeView extends CollectionSubView() {
 
     getAnchor = (addAsAnnotation: boolean) => {
         const anchor = Docs.Create.ConfigDocument({
-            title: ComputedField.MakeFunction(`"${this.pivotField}"])`) as any,
+            title: ComputedField.MakeFunction(`"${this.pivotField}"])`) as unknown as string, // title can take a functiono or a string
             annotationOn: this.Document,
         });
         PinDocView(anchor, { pinData: { type_collection: true, pivot: true, filters: true } }, this.Document);
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 285598600..ff316cfbd 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,8 +1,7 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
-import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
+import ResizeObserver from 'resize-observer-polyfill';
 import { DivHeight, returnAll, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnNone, returnOne, returnTrue, returnZero } from '../../../ClientUtils';
 import { Doc, DocListCast, Opt, StrListCast } from '../../../fields/Doc';
 import { DocData } from '../../../fields/DocSymbols';
@@ -19,7 +18,7 @@ import { dropActionType } from '../../util/DropActionTypes';
 import { ScriptingGlobals } from '../../util/ScriptingGlobals';
 import { SnappingManager } from '../../util/SnappingManager';
 import { Transform } from '../../util/Transform';
-import { undoBatch, UndoManager } from '../../util/UndoManager';
+import { undoable, undoBatch, UndoManager } from '../../util/UndoManager';
 import { ContextMenu } from '../ContextMenu';
 import { ContextMenuProps } from '../ContextMenuItem';
 import { EditableView } from '../EditableView';
@@ -27,13 +26,11 @@ import { DocumentView } from '../nodes/DocumentView';
 import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
 import { StyleProp } from '../StyleProp';
 import { CollectionFreeFormView } from './collectionFreeForm';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
 import './CollectionTreeView.scss';
 import { TreeViewType } from './CollectionTreeViewType';
 import { TreeView } from './TreeView';
 
-const _global = (window /* browser */ || global) /* node */ as any;
-
 export type collectionTreeViewProps = {
     treeViewExpandedView?: 'fields' | 'layout' | 'links' | 'data';
     treeViewOpen?: boolean;
@@ -55,10 +52,10 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
     private _titleRef?: HTMLDivElement | HTMLInputElement | null;
     private _disposers: { [name: string]: IReactionDisposer } = {};
     private _isDisposing = false; // notes that instance is in process of being disposed
-    private refList: Set<any> = new Set(); // list of tree view items to monitor for height changes
-    private observer: any; // observer for monitoring tree view items.
+    private refList: Set<HTMLElement> = new Set(); // list of tree view items to monitor for height changes
+    private observer: ResizeObserver | undefined; // observer for monitoring tree view items.
 
-    constructor(props: any) {
+    constructor(props: SubCollectionViewProps & collectionTreeViewProps) {
         super(props);
         makeObservable(this);
     }
@@ -113,14 +110,14 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
             !this._props.dontRegisterView && this._props.setHeight?.(bodyHeight + titleHeight);
         }
     };
-    unobserveHeight = (ref: any) => {
+    unobserveHeight = (ref: HTMLElement) => {
         this.refList.delete(ref);
         this.layoutDoc.layout_autoHeight && this.computeHeight();
     };
-    observeHeight = (ref: any) => {
+    observeHeight = (ref: HTMLElement) => {
         if (ref) {
             this.refList.add(ref);
-            this.observer = new _global.ResizeObserver(() => {
+            this.observer = new ResizeObserver(() => {
                 if (this.layoutDoc.layout_autoHeight && ref && this.refList.size && !SnappingManager.IsDragging) {
                     this.computeHeight();
                 }
@@ -216,7 +213,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
         ContextMenu.Instance.addItem({ description: 'Options...', subitems: layoutItems, icon: 'eye' });
         if (!Doc.noviceMode) {
             const existingOnClick = ContextMenu.Instance.findByDescription('OnClick...');
-            const onClicks: ContextMenuProps[] = existingOnClick && 'subitems' in existingOnClick ? existingOnClick.subitems : [];
+            const onClicks: ContextMenuProps[] = existingOnClick.subitems ?? [];
             onClicks.push({ description: 'Edit onChecked Script', event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.Document, undefined, 'onCheckedClick'), 'edit onCheckedClick'), icon: 'edit' });
             !existingOnClick && ContextMenu.Instance.addItem({ description: 'OnClick...', noexpand: true, subitems: onClicks, icon: 'mouse-pointer' });
         }
@@ -234,11 +231,11 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
                 maxHeight={72}
                 height="auto"
                 GetValue={() => StrCast(this.dataDoc.title)}
-                SetValue={undoBatch((value: string, shift: boolean, enter: boolean) => {
+                SetValue={undoable((value: string, shift: boolean, enter: boolean) => {
                     if (enter && this.Document.treeView_Type === TreeViewType.outline) this.makeTextCollection(this.treeChildren);
                     this.dataDoc.title = value;
                     return true;
-                })}
+                }, 'set doc title')}
             />
         );
     }
@@ -285,7 +282,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
     @observable _renderCount = 1;
     @computed get treeViewElements() {
         TraceMobx();
-        const dragAction = StrCast(this.Document.childDragAction) as any as dropActionType;
+        const dragAction = StrCast(this.Document.childDragAction) as dropActionType;
         const treeAddDoc = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => this.addDoc(doc, relativeTo, before);
         const moveDoc = (d: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this._props.moveDocument?.(d, target, addDoc) || false;
         if (this._renderCount < this.treeChildren.length)
@@ -333,9 +330,11 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
         return this.dataDoc === null ? null : (
             <div
                 className="collectionTreeView-titleBar"
-                ref={action((r: any) => {
-                    (this._titleRef = r) && (this._titleHeight = r.getBoundingClientRect().height * this.ScreenToLocalBoxXf().Scale);
-                })}
+                ref={r =>
+                    runInAction(() => {
+                        (this._titleRef = r) && (this._titleHeight = r.getBoundingClientRect().height * this.ScreenToLocalBoxXf().Scale);
+                    })
+                }
                 key={this.Document[Id]}
                 style={!this.outlineMode ? { marginLeft: this.marginX(), paddingTop: this.marginTop() } : {}}>
                 {this.outlineMode ? this.documentTitle : this.editableTitle}
@@ -410,8 +409,8 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
 
     @observable _headerHeight = 0;
     @computed get content() {
-        const background = () => this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor);
-        const color = () => this._props.styleProvider?.(this.Document, this._props, StyleProp.Color);
+        const background = () => this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor) as string;
+        const color = () => this._props.styleProvider?.(this.Document, this._props, StyleProp.Color) as string;
         const pointerEvents = () => (this._props.isContentActive() === false ? 'none' : undefined);
         const titleBar = this._props.treeViewHideTitle || this.Document.treeView_HideTitle ? null : this.titleBar;
         return (
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index f50f7394b..ee5c4afc0 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -6,6 +6,7 @@ import { IReactionDisposer, ObservableSet, action, computed, makeObservable, obs
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import * as ReactDOM from 'react-dom/client';
+import ResizeObserver from 'resize-observer-polyfill';
 import { ClientUtils, DashColor, lightOrDark, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../../ClientUtils';
 import { emptyFunction } from '../../../Utils';
 import { Doc, Opt } from '../../../fields/Doc';
@@ -41,8 +42,6 @@ import { CollectionView } from './CollectionView';
 import './TabDocView.scss';
 import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
 
-const _global = (window /* browser */ || global) /* node */ as any;
-
 interface TabMinimapViewProps {
     document: Doc;
     tabView: () => DocumentView | undefined;
@@ -183,6 +182,7 @@ export class TabMinimapView extends ObservableReactComponent<TabMinimapViewProps
 interface TabDocViewProps {
     documentId: FieldId;
     keyValue?: boolean;
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     glContainer: any;
 }
 @observer
@@ -327,10 +327,12 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
     get view() {
         return this._view;
     }
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     _lastTab: any;
     _lastView: DocumentView | undefined;
 
     @action
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     init = (tab: any, doc: Opt<Doc>) => {
         if (tab.contentItem === tab.header.parent.getActiveContentItem()) this._activated = true;
         if (tab.DashDoc !== doc && doc && tab.contentItem?.config.type !== 'stack') {
@@ -357,10 +359,11 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
             titleEle.size = StrCast(doc.title).length + 3;
             titleEle.value = doc.title;
             titleEle.onkeydown = (e: KeyboardEvent) => e.stopPropagation();
-            titleEle.onchange = (e: any) => {
+            titleEle.onchange = (e: InputEvent) => {
                 undoable(() => {
-                    titleEle.size = e.currentTarget.value.length + 3;
-                    doc[DocData].title = e.currentTarget.value;
+                    const target = e.currentTarget as unknown as { value: string };
+                    titleEle.size = target?.value.length + 3;
+                    doc[DocData].title = target?.value ?? '';
                 }, 'edit tab title')();
             };
 
@@ -449,8 +452,8 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
             };
 
             // select the tab document when the tab is directly clicked and activate the tab whenver the tab document is selected
-            titleEle.onpointerdown = action((e: any) => {
-                if (e.target.className !== 'lm_iconWrap') {
+            titleEle.onpointerdown = action((e: PointerEvent) => {
+                if ((e.target as HTMLElement)?.className !== 'lm_iconWrap') {
                     if (this.view) DocumentView.SelectView(this.view, false);
                     else this._activated = true;
                     if (Date.now() - titleEle.lastClick < 1000) titleEle.select();
@@ -482,7 +485,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
             tab.closeElement
                 .off('click') // unbind the current click handler
                 .click(() => {
-                    Object.values(tab._disposers).forEach((disposer: any) => disposer?.());
+                    Object.values(tab._disposers).forEach(disposer => (disposer as () => void)());
                     DocumentView.DeselectAll();
                     UndoManager.RunInBatch(() => tab.contentItem.remove(), 'delete tab');
                 });
@@ -490,8 +493,8 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
     };
 
     componentDidMount() {
-        new _global.ResizeObserver(
-            action((entries: any) => {
+        new ResizeObserver(
+            action(entries => {
                 // eslint-disable-next-line no-restricted-syntax
                 for (const entry of entries) {
                     this._panelWidth = entry.contentRect.width;
@@ -524,6 +527,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
     public static DontSelectOnActivate = 'dontSelectOnActivate';
 
     @action.bound
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     private onActiveContentItemChanged(contentItem: any) {
         if (!contentItem || (this.stack === contentItem.parent && ((contentItem?.tab === this.tab && !this._isActive) || (contentItem?.tab !== this.tab && this._isActive)))) {
             this._activated = this._isActive = !contentItem || contentItem?.tab === this.tab;
@@ -650,13 +654,13 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
                             this._view && DocumentView.removeView(this._view);
                         }
                         this._lastTab = this.tab;
-                        (this._mainCont as any).InitTab = (tab: any) => this.init(tab, this._document);
+                        (this._mainCont as { InitTab?: (tab: object) => void }).InitTab = (tab: object) => this.init(tab, this._document);
                         DocServer.GetRefField(this._props.documentId).then(
                             action(doc => {
                                 doc instanceof Doc && (this._document = doc) && this.tab && this.init(this.tab, this._document);
                             })
                         );
-                        new _global.ResizeObserver(action(() => this._forceInvalidateScreenToLocal++)).observe(ref);
+                        ref && new ResizeObserver(action(() => this._forceInvalidateScreenToLocal++)).observe(ref);
                     }
                 }}>
                 {this.docView}
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 161d93788..54053d038 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -1,10 +1,7 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { IconButton, Size } from 'browndash-components';
-import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx';
+import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { ClientUtils, lightOrDark, return18, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, setupMoveUpEvents, simulateMouseClick } from '../../../ClientUtils';
@@ -41,14 +38,15 @@ import { CollectionView } from './CollectionView';
 import { TreeSort } from './TreeSort';
 import './TreeView.scss';
 
+// eslint-disable-next-line @typescript-eslint/no-var-requires
 const { TREE_BULLET_WIDTH } = require('../global/globalCssVariables.module.scss'); // prettier-ignore
 
 export interface TreeViewProps {
     treeView: CollectionTreeView;
     // eslint-disable-next-line no-use-before-define
     parentTreeView: TreeView | CollectionTreeView | undefined;
-    observeHeight: (ref: any) => void;
-    unobserveHeight: (ref: any) => void;
+    observeHeight: (ref: HTMLDivElement) => void;
+    unobserveHeight: (ref: HTMLDivElement) => void;
     prevSibling?: Doc;
     Document: Doc;
     dataDoc?: Doc;
@@ -188,7 +186,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
     moving: boolean = false;
     @undoBatch move = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => {
         if (this.Document !== target && addDoc !== returnFalse) {
-            const canAdd1 = (this._props.parentTreeView as any).dropping || !(ComputedField.WithoutComputed(() => FieldValue(this._props.parentTreeView?.Document.data)) instanceof ComputedField);
+            const canAdd1 = (this._props.parentTreeView as TreeView).dropping || !(ComputedField.WithoutComputed(() => FieldValue(this._props.parentTreeView?.Document.data)) instanceof ComputedField);
 
             // bcz: this should all be running in a Temp undo batch instead of hackily testing for returnFalse
             if (canAdd1 && this._props.removeDoc?.(doc) === true) {
@@ -263,7 +261,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
         return runningChildren;
     };
 
-    static GetRunningChildren = new Map<Doc, any>();
+    static GetRunningChildren = new Map<Doc, () => FieldResult[]>();
     static ToggleChildrenRun = new Map<Doc, () => void>();
     constructor(props: TreeViewProps) {
         super(props);
@@ -285,7 +283,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
         TreeView.GetRunningChildren.set(this.Document, () => this.getRunningChildren(this.childDocs));
     }
 
-    _treeEle: any;
+    _treeEle: HTMLDivElement | null = null;
     protected createTreeDropTarget = (ele: HTMLDivElement) => {
         this._treedropDisposer?.();
         ele && ((this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this), this.Document, this.preTreeDrop.bind(this))), this.Document);
@@ -524,7 +522,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
                     return toList(docs).reduce((flg, iDoc) => flg && innerAdd(iDoc), true as boolean);
                 };
                 contentElement = TreeView.GetChildElements(
-                    toList(contents as any),
+                    contents instanceof Doc ? [contents] : DocListCast(contents),
                     this.treeView,
                     this,
                     doc,
@@ -572,9 +570,11 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
             rows.push(
                 <div style={{ display: 'flex', overflow: 'auto' }} key={key}>
                     <span
-                        ref={action((r: any) => {
-                            if (r) leftOffset.width = r.getBoundingClientRect().width;
-                        })}
+                        ref={r =>
+                            runInAction(() => {
+                                if (r) leftOffset.width = r.getBoundingClientRect().width;
+                            })
+                        }
                         style={{ fontWeight: 'bold' }}>
                         {key + ':'}
                         &nbsp;
@@ -608,7 +608,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
         return rows;
     }
 
-    _renderTimer: any;
+    _renderTimer: NodeJS.Timeout | undefined;
     @observable _renderCount = 1;
     @computed get renderContent() {
         TraceMobx();
@@ -754,7 +754,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
     }
 
     get onCheckedClick() {
-        return this.Document.type === DocumentType.COL ? undefined : this._props.onCheckedClick?.() ?? ScriptCast(this.Document.onCheckedClick);
+        return this.Document.type === DocumentType.COL ? undefined : (this._props.onCheckedClick?.() ?? ScriptCast(this.Document.onCheckedClick));
     }
 
     @action
@@ -779,7 +779,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
         TraceMobx();
         const iconType = (this.treeView._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.TreeViewIcon + (this.treeViewOpen ? ':treeOpen' : !this.childDocs.length ? ':empty' : '')) as string) || 'question';
         const color = SettingsManager.userColor;
-        const checked = this.onCheckedClick ? this.Document.treeView_Checked ?? 'unchecked' : undefined;
+        const checked = this.onCheckedClick ? (this.Document.treeView_Checked ?? 'unchecked') : undefined;
         return (
             <div
                 className={`bullet${this.treeView.outlineMode ? '-outline' : ''}`}
@@ -789,7 +789,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
                 style={
                     this.treeView.outlineMode
                         ? {
-                              opacity: this.titleStyleProvider?.(this.Document, this.treeView._props, StyleProp.Opacity),
+                              opacity: this.titleStyleProvider?.(this.Document, this.treeView._props, StyleProp.Opacity) as number,
                           }
                         : {
                               pointerEvents: this._props.isContentActive() ? 'all' : undefined,
@@ -829,7 +829,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
     @action
     expandNextviewType = () => {
         if (this.treeViewOpen && !this.Document.isFolder && !this.treeView.outlineMode && !this.Document.treeView_ExpandedViewLock) {
-            const next = (modes: any[]) => modes[(modes.indexOf(StrCast(this.treeViewExpandedView)) + 1) % modes.length];
+            const next = (modes: string[]) => modes[(modes.indexOf(StrCast(this.treeViewExpandedView)) + 1) % modes.length];
             this.Document.treeView_ExpandedView = next(this.validExpandViewTypes);
         }
         this.treeViewOpen = true;
@@ -897,13 +897,13 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
     onChildDoubleClick = () => ScriptCast(this.treeView.Document.treeView_ChildDoubleClick, !this.treeView.outlineMode ? this._openScript?.() : null);
 
     refocus = () => this.treeView._props.focus(this.treeView.Document, {});
-    ignoreEvent = (e: any) => {
+    ignoreEvent = (e: React.MouseEvent) => {
         if (this._props.isContentActive(true)) {
             e.stopPropagation();
             e.preventDefault();
         }
     };
-    titleStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string): any => {
+    titleStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string) => {
         if (!doc || doc !== this.Document) return this._props?.treeView?._props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView
 
         const { treeView } = this;
@@ -938,7 +938,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
         }
         return treeView._props.styleProvider?.(doc, props, property);
     };
-    embeddedStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string): any => {
+    embeddedStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string) => {
         if (property.startsWith(StyleProp.Decorations)) return null;
         return this._props?.treeView?._props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView
     };
@@ -990,28 +990,30 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
                     this._editTitle = e;
                 })}
                 GetValue={() => StrCast(this.Document.title)}
-                OnTab={undoBatch((shift?: boolean) => {
+                OnTab={undoable((shift?: boolean) => {
                     if (!shift) this._props.indentDocument?.(true);
                     else this._props.outdentDocument?.(true);
-                })}
-                OnEmpty={undoBatch(() => this.treeView.outlineMode && this._props.removeDoc?.(this.Document))}
+                }, 'create new tree Doc')}
+                OnEmpty={undoable(() => this.treeView.outlineMode && this._props.removeDoc?.(this.Document), 'remove tree doc')}
                 OnFillDown={() => this.treeView.fileSysMode && this.makeFolder()}
-                SetValue={undoBatch((value: string, shiftKey: boolean, enterKey: boolean) => {
+                SetValue={undoable((value: string, shiftKey: boolean, enterKey: boolean) => {
                     Doc.SetInPlace(this.Document, 'title', value, false);
-                    this.treeView.outlineMode && enterKey && this.makeTextCollection();
-                })}
+                    return this.treeView.outlineMode && enterKey && this.makeTextCollection();
+                }, 'set tree doc title')}
             />
         ) : (
             <DocumentView
                 key="title"
-                ref={action((r: any) => {
-                    this._docRef = r || undefined;
-                    if (this._docRef && TreeView._editTitleOnLoad?.id === this.Document[Id] && TreeView._editTitleOnLoad.parent === this._props.parentTreeView) {
-                        this._docRef.select(false);
-                        this.setEditTitle(this._docRef);
-                        TreeView._editTitleOnLoad = undefined;
-                    }
-                })}
+                ref={r =>
+                    runInAction(() => {
+                        this._docRef = r || undefined;
+                        if (this._docRef && TreeView._editTitleOnLoad?.id === this.Document[Id] && TreeView._editTitleOnLoad.parent === this._props.parentTreeView) {
+                            this._docRef.select(false);
+                            this.setEditTitle(this._docRef);
+                            TreeView._editTitleOnLoad = undefined;
+                        }
+                    })
+                }
                 Document={this.Document}
                 fitWidth={returnTrue}
                 scriptContext={this}
@@ -1068,9 +1070,11 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
                 </div>
                 <div
                     className="treeView-rightButtons"
-                    ref={action((r: any) => {
-                        r && (this.headerEleWidth = r.getBoundingClientRect().width);
-                    })}>
+                    ref={r =>
+                        runInAction(() => {
+                            r && (this.headerEleWidth = r.getBoundingClientRect().width);
+                        })
+                    }>
                     {this.titleButtons}
                 </div>
             </>
@@ -1090,7 +1094,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
                             this,
                             e,
                             () => {
-                                (this._dref ?? this._docRef)?.startDragging(e.clientX, e.clientY, '' as any);
+                                (this._dref ?? this._docRef)?.startDragging(e.clientX, e.clientY, undefined);
                                 return true;
                             },
                             returnFalse,
@@ -1272,8 +1276,8 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
         firstLevel: boolean,
         whenChildContentsActiveChanged: (isActive: boolean) => void,
         dontRegisterView: boolean | undefined,
-        observerHeight: (ref: any) => void,
-        unobserveHeight: (ref: any) => void,
+        observerHeight: (ref: HTMLElement) => void,
+        unobserveHeight: (ref: HTMLElement) => void,
         contextMenuItems: { script: ScriptField; filter: ScriptField; label: string; icon: string }[],
         // TODO: [AL] add these
         AddToMap?: (treeViewDoc: Doc, index: number[]) => void,
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
index fc39cafaa..c17371151 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
@@ -12,7 +12,7 @@ import './CollectionFreeFormView.scss';
  * returns a truthy value
  */
 // eslint-disable-next-line no-use-before-define
-export type infoArc = [() => any, (res?: any) => infoState];
+export type infoArc = [() => unknown, (res?: unknown) => infoState];
 
 export const StateMessage = Symbol('StateMessage');
 export const StateMessageGIF = Symbol('StateMessageGIF');
@@ -20,9 +20,9 @@ export const StateEntryFunc = Symbol('StateEntryFunc');
 export class infoState {
     [StateMessage]: string = '';
     [StateMessageGIF]?: string = '';
-    [StateEntryFunc]?: () => any;
+    [StateEntryFunc]?: () => unknown;
     [key: string]: infoArc;
-    constructor(message: string, arcs: { [key: string]: infoArc }, messageGif?: string, entryFunc?: () => any) {
+    constructor(message: string, arcs: { [key: string]: infoArc }, messageGif?: string, entryFunc?: () => unknown) {
         this[StateMessage] = message;
         Object.assign(this, arcs);
         this[StateMessageGIF] = messageGif;
@@ -44,7 +44,7 @@ export function InfoState(
     msg: string, //
     arcs: { [key: string]: infoArc },
     gif?: string,
-    entryFunc?: () => any
+    entryFunc?: () => unknown
 ) {
     // eslint-disable-next-line new-cap
     return new infoState(msg, arcs, gif, entryFunc);
@@ -52,7 +52,7 @@ export function InfoState(
 
 export interface CollectionFreeFormInfoStateProps {
     infoState: infoState;
-    next: (state: infoState) => any;
+    next: (state: infoState) => unknown;
     close: () => void;
 }
 
@@ -61,7 +61,7 @@ export class CollectionFreeFormInfoState extends ObservableReactComponent<Collec
     _disposers: IReactionDisposer[] = [];
     @observable _expanded = false;
 
-    constructor(props: any) {
+    constructor(props: CollectionFreeFormInfoStateProps) {
         super(props);
         makeObservable(this);
     }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx
index e543b4008..bc9dd022c 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx
@@ -54,8 +54,8 @@ export class CollectionFreeFormPannableContents extends ObservableReactComponent
             <div
                 className={'collectionfreeformview' + (this._props.viewDefDivClick ? '-viewDef' : '-none')}
                 onScroll={e => {
-                    const target = e.target as any;
-                    if (getComputedStyle(target)?.overflow === 'visible') {
+                    const { target } = e;
+                    if (target instanceof Element && getComputedStyle(target)?.overflow === 'visible') {
                         target.scrollTop = target.scrollLeft = 0; // if collection is visible, scrolling messes things up since there are no scroll bars
                     }
                 }}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 39c3da7a5..c4cf8dee7 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,6 +1,7 @@
 /* eslint-disable react/jsx-props-no-spreading */
 import { Bezier } from 'bezier-js';
 import { Colors } from 'browndash-components';
+import { Property } from 'csstype';
 import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import { computedFn } from 'mobx-utils';
@@ -8,7 +9,6 @@ import * as React from 'react';
 import { ClientUtils, DashColor, lightOrDark, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, UpdateIcon } from '../../../../ClientUtils';
 import { DateField } from '../../../../fields/DateField';
 import { Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../../fields/Doc';
-import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveEraserWidth, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, SetActiveInkColor, SetActiveInkWidth } from '../../nodes/DocumentView';
 import { DocData, Height, Width } from '../../../../fields/DocSymbols';
 import { Id } from '../../../../fields/FieldSymbols';
 import { InkData, InkField, InkTool, Segment } from '../../../../fields/InkField';
@@ -31,13 +31,13 @@ import { CompileScript } from '../../../util/Scripting';
 import { ScriptingGlobals } from '../../../util/ScriptingGlobals';
 import { freeformScrollMode, SnappingManager } from '../../../util/SnappingManager';
 import { Transform } from '../../../util/Transform';
-import { undoable, undoBatch, UndoManager } from '../../../util/UndoManager';
+import { undoable, UndoManager } from '../../../util/UndoManager';
 import { Timeline } from '../../animationtimeline/Timeline';
 import { ContextMenu } from '../../ContextMenu';
 import { InkingStroke } from '../../InkingStroke';
 import { CollectionFreeFormDocumentView } from '../../nodes/CollectionFreeFormDocumentView';
 import { SchemaCSVPopUp } from '../../nodes/DataVizBox/SchemaCSVPopUp';
-import { ActiveFillColor, DocumentView } from '../../nodes/DocumentView';
+import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveEraserWidth, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, DocumentView, SetActiveInkColor, SetActiveInkWidth } from '../../nodes/DocumentView';
 import { FieldViewProps } from '../../nodes/FieldView';
 import { FocusViewOptions } from '../../nodes/FocusViewOptions';
 import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
@@ -121,7 +121,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
     @observable _marqueeViewRef = React.createRef<MarqueeView>();
     @observable _brushedView: { width: number; height: number; panX: number; panY: number } | undefined = undefined; // highlighted region of freeform canvas used by presentations to indicate a region
     @observable GroupChildDrag: boolean = false; // child document view being dragged.  needed to update drop areas of groups when a group item is dragged.
-    @observable _childPointerEvents: 'none' | 'all' | 'visiblePainted' | undefined = undefined;
+    @observable _childPointerEvents: Property.PointerEvents | undefined = undefined;
     @observable _lightboxDoc: Opt<Doc> = undefined;
     @observable _paintedId = 'id' + Utils.GenerateGuid().replace(/-/g, '');
     @observable _keyframeEditing = false;
@@ -441,8 +441,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         return true;
     }
 
-    @undoBatch
-    internalAnchorAnnoDrop(e: Event, de: DragManager.DropEvent, annoDragData: DragManager.AnchorAnnoDragData) {
+    internalAnchorAnnoDrop = undoable((e: Event, de: DragManager.DropEvent, annoDragData: DragManager.AnchorAnnoDragData) => {
         const dropCreator = annoDragData.dropDocCreator;
         const [xp, yp] = this.screenToFreeformContentsXf.transformPoint(de.x, de.y);
         annoDragData.dropDocCreator = (annotationOn: Doc | undefined) => {
@@ -455,10 +454,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             return dropDoc || this.Document;
         };
         return true;
-    }
+    }, 'anchor drop');
 
-    @undoBatch
-    internalLinkDrop(e: Event, de: DragManager.DropEvent, linkDragData: DragManager.LinkDragData) {
+    internalLinkDrop = undoable((e: Event, de: DragManager.DropEvent, linkDragData: DragManager.LinkDragData) => {
         if (this.DocumentView?.() && linkDragData.linkDragView.containerViewPath?.().includes(this.DocumentView())) {
             const [x, y] = this.screenToFreeformContentsXf.transformPoint(de.x, de.y);
             //  do nothing if link is dropped into any freeform view parent of dragged document
@@ -474,9 +472,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             return added;
         }
         return false;
-    }
+    }, 'link drop');
 
-    onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
+    onInternalDrop = (e: Event, de: DragManager.DropEvent): boolean => {
         if (de.complete.annoDragData?.dragDocument && super.onInternalDrop(e, de)) return this.internalAnchorAnnoDrop(e, de, de.complete.annoDragData);
         if (de.complete.linkDragData) return this.internalLinkDrop(e, de, de.complete.linkDragData);
         if (de.complete.docDragData?.droppedDocuments.length) return this.internalDocDrop(e, de, de.complete.docDragData);
@@ -522,8 +520,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         }
     };
 
-    @undoBatch
-    onGesture = (e: Event, ge: GestureUtils.GestureEvent) => {
+    onGesture = undoable((e: Event, ge: GestureUtils.GestureEvent) => {
         switch (ge.gesture) {
             case Gestures.Text:
                 if (ge.text) {
@@ -566,7 +563,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 e.stopPropagation();
             }
         }
-    };
+    }, 'gesture');
     @action
     onEraserUp = (): void => {
         this._deleteList.lastElement()?._props.removeDocument?.(this._deleteList.map(ink => ink.Document));
@@ -1484,8 +1481,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         const childData = entry.pair.data;
         return (
             <CollectionFreeFormDocumentView
-                // eslint-disable-next-line react/jsx-props-no-spreading
-                {...OmitKeys(entry, ['replica', 'pair']).omit}
+                // eslint-disable-next-line react/jsx-props-no-spreading, @typescript-eslint/no-explicit-any
+                {...(OmitKeys(entry, ['replica', 'pair']).omit as any)}
                 key={childLayout[Id] + (entry.replica || '')}
                 Document={childLayout}
                 reactParent={this}
@@ -1771,7 +1768,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
                 this._disposers.pointerevents = reaction(
                     () => this.childPointerEvents,
                     pointerevents => {
-                        this._childPointerEvents = pointerevents as 'none' | 'all' | 'visiblePainted' | undefined;
+                        this._childPointerEvents = pointerevents as Property.PointerEvents | undefined;
                     },
                     { fireImmediately: true }
                 );
@@ -1849,8 +1846,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         this._showEraserCircle = true;
     };
 
-    @undoBatch
-    promoteCollection = () => {
+    promoteCollection = undoable(() => {
         const childDocs = this.childDocs.slice();
         childDocs.forEach(docIn => {
             const doc = docIn;
@@ -1859,10 +1855,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             doc.y = scr?.[1];
         });
         this._props.addDocTab(childDocs, OpenWhere.inParentFromScreen);
-    };
+    }, 'promote collection');
 
-    @undoBatch
-    layoutDocsInGrid = () => {
+    layoutDocsInGrid = undoable(() => {
         const docs = this.childLayoutPairs.map(pair => pair.layout);
         const width = Math.max(...docs.map(doc => NumCast(doc._width))) + 20;
         const height = Math.max(...docs.map(doc => NumCast(doc._height))) + 20;
@@ -1872,40 +1867,37 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
             doc.x = NumCast(this.Document[this.panXFieldKey]) + (i % dim) * width - (width * dim) / 2;
             doc.y = NumCast(this.Document[this.panYFieldKey]) + Math.floor(i / dim) * height - (height * dim) / 2;
         });
-    };
+    }, 'layout docs in grid');
 
-    @undoBatch
-    toggleNativeDimensions = () => Doc.toggleNativeDimensions(this.layoutDoc, 1, this.nativeWidth, this.nativeHeight);
+    toggleNativeDimensions = undoable(() => Doc.toggleNativeDimensions(this.layoutDoc, 1, this.nativeWidth, this.nativeHeight), 'toggle native dimensions');
 
     ///
     /// resetView restores a freeform collection to unit scale and centered at (0,0)  UNLESS
     ///  the view is a group, in which case this does nothing (since Groups calculate their own scale and center)
     ///
-    @undoBatch
-    resetView = () => {
+    resetView = undoable(() => {
         this.layoutDoc[this.panXFieldKey] = NumCast(this.dataDoc[this.panXFieldKey + '_reset']);
         this.layoutDoc[this.panYFieldKey] = NumCast(this.dataDoc[this.panYFieldKey + '_reset']);
         this.layoutDoc[this.scaleFieldKey] = NumCast(this.dataDoc[this.scaleFieldKey + '_reset'], 1);
-    };
+    }, 'reset view');
     ///
     /// resetView restores a freeform collection to unit scale and centered at (0,0)  UNLESS
     ///  the view is a group, in which case this does nothing (since Groups calculate their own scale and center)
     ///
-    @undoBatch
-    toggleResetView = () => {
+    toggleResetView = undoable(() => {
         this.dataDoc[this.autoResetFieldKey] = !this.dataDoc[this.autoResetFieldKey];
         if (this.dataDoc[this.autoResetFieldKey]) {
             this.dataDoc[this.panXFieldKey + '_reset'] = this.layoutDoc[this.panXFieldKey];
             this.dataDoc[this.panYFieldKey + '_reset'] = this.layoutDoc[this.panYFieldKey];
             this.dataDoc[this.scaleFieldKey + '_reset'] = this.layoutDoc[this.scaleFieldKey];
         }
-    };
+    }, 'toggle reset view');
 
     onContextMenu = () => {
         if (this._props.isAnnotationOverlay || !ContextMenu.Instance) return;
 
         const appearance = ContextMenu.Instance.findByDescription('Appearance...');
-        const appearanceItems = appearance && 'subitems' in appearance ? appearance.subitems : [];
+        const appearanceItems = appearance?.subitems ?? [];
         !this.Document.isGroup && appearanceItems.push({ description: 'Reset View', event: this.resetView, icon: 'compress-arrows-alt' });
         !this.Document.isGroup && appearanceItems.push({ description: 'Toggle Auto Reset View', event: this.toggleResetView, icon: 'compress-arrows-alt' });
         if (this._props.setContentViewBox === emptyFunction) {
@@ -1932,7 +1924,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         !appearance && ContextMenu.Instance.addItem({ description: 'Appearance...', subitems: appearanceItems, icon: 'eye' });
 
         const options = ContextMenu.Instance.findByDescription('Options...');
-        const optionItems = options && 'subitems' in options ? options.subitems : [];
+        const optionItems = options?.subitems ?? [];
         !this._props.isAnnotationOverlay &&
             !Doc.noviceMode &&
             optionItems.push({
@@ -1956,12 +1948,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
         }
         !options && ContextMenu.Instance.addItem({ description: 'Options...', subitems: optionItems, icon: 'eye' });
         const mores = ContextMenu.Instance.findByDescription('More...');
-        const moreItems = mores && 'subitems' in mores ? mores.subitems : [];
+        const moreItems = mores?.subitems ?? [];
         !mores && ContextMenu.Instance.addItem({ description: 'More...', subitems: moreItems, icon: 'eye' });
     };
 
-    @undoBatch
-    transcribeStrokes = () => {
+    transcribeStrokes = undoable(() => {
         if (this.Document.isGroup && this.Document.transcription) {
             const text = StrCast(this.Document.transcription);
             const lines = text.split('\n');
@@ -1969,7 +1960,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
 
             this.addDocument(Docs.Create.TextDocument(text, { title: lines[0], x: NumCast(this.layoutDoc.x) + NumCast(this.layoutDoc._width) + 20, y: NumCast(this.layoutDoc.y), _width: 200, _height: height }));
         }
-    };
+    }, 'transcribe strokes');
 
     @action
     dragEnding = () => {
diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
index eac0dc0e1..3af8464c2 100644
--- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
+++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
@@ -1,8 +1,7 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@mui/material';
 import { Toggle, ToggleType, Type } from 'browndash-components';
+import { Property } from 'csstype';
 import { IReactionDisposer, action, makeObservable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -22,8 +21,7 @@ import { UndoStack } from '../../UndoStack';
 import { DocumentLinksButton } from '../../nodes/DocumentLinksButton';
 import { DocumentView } from '../../nodes/DocumentView';
 import { LinkDescriptionPopup } from '../../nodes/LinkDescriptionPopup';
-import { CollectionSubView } from '../CollectionSubView';
-import './CollectionLinearView.scss';
+import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView';
 
 /**
  * CollectionLinearView is the class for rendering the horizontal collection
@@ -39,7 +37,7 @@ export class CollectionLinearView extends CollectionSubView() {
     private _widthDisposer?: IReactionDisposer;
     private _selectedDisposer?: IReactionDisposer;
 
-    constructor(props: any) {
+    constructor(props: SubCollectionViewProps) {
         super(props);
         makeObservable(this);
     }
@@ -239,7 +237,7 @@ export class CollectionLinearView extends CollectionSubView() {
                             className="collectionLinearView-content"
                             style={{
                                 height: this.dimension(),
-                                flexDirection: flexDir as any,
+                                flexDirection: flexDir as Property.FlexDirection,
                                 gap: flexGap,
                             }}>
                             {this.childLayoutPairs.map(pair => this.getDisplayDoc(pair.layout))}
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 9deed4de4..59349da8b 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@mui/material';
 import { action, computed, IReactionDisposer, makeObservable, observable, runInAction } from 'mobx';
@@ -7,7 +5,7 @@ import { observer } from 'mobx-react';
 import * as React from 'react';
 import { returnFalse, setupMoveUpEvents } from '../../../ClientUtils';
 import { DateField } from '../../../fields/DateField';
-import { Doc } from '../../../fields/Doc';
+import { Doc, Opt } from '../../../fields/Doc';
 import { DocData } from '../../../fields/DocSymbols';
 import { ComputedField } from '../../../fields/ScriptField';
 import { Cast, DateCast, NumCast } from '../../../fields/Types';
@@ -44,9 +42,9 @@ import { OpenWhere } from './OpenWhere';
  */
 
 // used as a wrapper class for MediaStream from MediaDevices API
-declare class MediaRecorder {
-    constructor(e: any); // whatever MediaRecorder has
-}
+// declare class MediaRecorder {
+//     constructor(e: unknown); // whatever MediaRecorder has
+// }
 
 export enum mediaState {
     PendingRecording = 'pendingRecording',
@@ -61,9 +59,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         return FieldView.LayoutString(AudioBox, fieldKey);
     }
 
-    public static Enabled = false;
-
-    constructor(props: any) {
+    constructor(props: FieldViewProps) {
         super(props);
         makeObservable(this);
     }
@@ -74,12 +70,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     _dropDisposer?: DragManager.DragDropDisposer;
     _disposers: { [name: string]: IReactionDisposer } = {};
     _ele: HTMLAudioElement | null = null; // <audio> ref
-    _recorder: any; // MediaRecorder
+    _recorder: Opt<MediaRecorder>; // MediaRecorder
     _recordStart = 0;
     _pauseStart = 0; // time when recording is paused (used to keep track of recording timecodes)
     _pausedTime = 0;
     _stream: MediaStream | undefined; // passed to MediaRecorder, records device input audio
-    _play: any = null; // timeout for playback
+    _play: NodeJS.Timeout | null = null; // timeout for playback
 
     @observable _stackedTimeline: CollectionStackedTimeline | null | undefined = undefined; // CollectionStackedTimeline ref
     @observable _finished: boolean = false; // has playback reached end of clip
@@ -133,7 +129,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             this.mediaState = mediaState.Paused;
             this.setPlayheadTime(NumCast(this.layoutDoc.clipStart));
         } else {
-            this.mediaState = undefined as any as mediaState;
+            this.mediaState = undefined as unknown as mediaState;
         }
     }
 
@@ -185,11 +181,11 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     // play back the audio from seekTimeInSeconds, fullPlay tells whether clip is being played to end vs link range
     @action
     playFrom = (seekTimeInSeconds: number, endTime?: number, fullPlay: boolean = false) => {
-        clearTimeout(this._play); // abort any previous clip ending
+        this._play && clearTimeout(this._play); // abort any previous clip ending
         if (isNaN(this._ele?.duration ?? Number.NaN)) {
             // audio element isn't loaded yet... wait 1/2 second and try again
             setTimeout(() => this.playFrom(seekTimeInSeconds, endTime), 500);
-        } else if (this.timeline && this._ele && AudioBox.Enabled) {
+        } else if (this.timeline && this._ele) {
             // trimBounds override requested playback bounds
             const end = Math.min(this.timeline.trimEnd, endTime ?? this.timeline.trimEnd);
             const start = Math.max(this.timeline.trimStart, seekTimeInSeconds);
@@ -253,8 +249,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         this._recorder = new MediaRecorder(this._stream);
         this.dataDoc[this.fieldKey + '_recordingStart'] = new DateField();
         DocViewUtils.ActiveRecordings.push(this);
-        this._recorder.ondataavailable = async (e: any) => {
-            const [{ result }] = await Networking.UploadFilesToServer({ file: e.data });
+        this._recorder.ondataavailable = async (e: BlobEvent) => {
+            const file: Blob & { name?: string; lastModified?: number; webkitRelativePath?: string } = e.data;
+            file.name = '';
+            file.lastModified = 0;
+            file.webkitRelativePath = '';
+            const [{ result }] = await Networking.UploadFilesToServer({ file: file as Blob & { name: string; lastModified: number; webkitRelativePath: string } });
             if (!(result instanceof Error)) {
                 this.Document[this.fieldKey] = new AudioField(result.accessPaths.agnostic.client);
             }
@@ -331,9 +331,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     };
 
     // for play button
-    Play = (e?: any) => {
-        e?.stopPropagation?.();
-
+    Play = () => {
         if (this.timeline && this._ele) {
             const eleTime = this._ele.currentTime;
 
@@ -363,7 +361,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             this.mediaState = mediaState.Paused;
 
             // if paused in the middle of playback, prevents restart on next play
-            if (!this._finished) clearTimeout(this._play);
+            if (!this._finished && this._play) clearTimeout(this._play);
         }
     };
     // pause playback and remove from playback list
@@ -374,7 +372,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     };
 
     // for dictation button, creates a text document for dictation
-    onFile = (e: any) => {
+    onFile = (e: React.PointerEvent) => {
         setupMoveUpEvents(
             this,
             e,
@@ -419,7 +417,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             action(() => {
                 this._pauseStart = new Date().getTime();
                 this._paused = true;
-                this._recorder.pause();
+                this._recorder?.pause();
             }),
             false
         );
@@ -435,7 +433,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             action(() => {
                 this._paused = false;
                 this._pausedTime += new Date().getTime() - this._pauseStart;
-                this._recorder.resume();
+                this._recorder?.resume();
             }),
             false
         );
@@ -620,14 +618,10 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                         <div
                             className="audiobox-button"
                             title={this.mediaState === mediaState.Paused ? 'play' : 'pause'}
-                            onPointerDown={
-                                this.mediaState === mediaState.Paused
-                                    ? this.Play
-                                    : e => {
-                                          e.stopPropagation();
-                                          this.Pause();
-                                      }
-                            }>
+                            onPointerDown={e => {
+                                e.stopPropagation();
+                                this.mediaState === mediaState.Paused ? this.Play() : this.Pause();
+                            }}>
                             <FontAwesomeIcon icon={this.mediaState === mediaState.Paused ? 'play' : 'pause'} size="1x" />
                         </div>
 
@@ -743,7 +737,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     // returns the html audio element
     @computed get audio() {
         return (
-            // eslint-disable-next-line jsx-a11y/media-has-caption
             <audio
                 ref={this.setRef}
                 className={`audiobox-control${this._props.isContentActive() ? '-interactive' : ''}`}
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 9a383c1e4..d51b1cd3a 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -119,7 +119,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         super.componentDidUpdate(prevProps);
         this.WrapperKeys.forEach(
             action(keys => {
-                (this as any)[keys.upper] = (this.props as any)[keys.lower];
+                (this as unknown as { [key: string]: unknown })[keys.upper] = (this.props as { [key: string]: unknown })[keys.lower];
             })
         );
     }
@@ -148,7 +148,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
             (p, val) => {
                 p[val.key] = Cast(doc[`${val.key}_indexed`], listSpec('number'), fillIn ? [NumCast(doc[val.key], val.val)] : []).reduce(
                     (prev, v, i) => ((i <= Math.round(time) && v !== undefined) || prev === undefined ? v : prev),
-                    undefined as any as number
+                    undefined as unknown as number
                 );
                 return p;
             },
@@ -159,7 +159,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     public static getStringValues(doc: Doc, time: number) {
         return CollectionFreeFormDocumentView.animStringFields.reduce(
             (p, val) => {
-                p[val] = Cast(doc[`${val}_indexed`], listSpec('string'), [StrCast(doc[val])]).reduce((prev, v, i) => ((i <= Math.round(time) && v !== undefined) || prev === undefined ? v : prev), undefined as any as string);
+                p[val] = Cast(doc[`${val}_indexed`], listSpec('string'), [StrCast(doc[val])]).reduce((prev, v, i) => ((i <= Math.round(time) && v !== undefined) || prev === undefined ? v : prev), undefined as unknown as string);
                 return p;
             },
             {} as { [val: string]: Opt<string> }
@@ -202,15 +202,15 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         docs.forEach(doc => {
             this.animFields.forEach(val => {
                 const findexed = Cast(doc[`${val.key}_indexed`], listSpec('number'), null);
-                findexed?.length <= timecode + 1 && findexed.push(undefined as any as number);
+                findexed?.length <= timecode + 1 && findexed.push(undefined as unknown as number);
             });
             this.animStringFields.forEach(val => {
                 const findexed = Cast(doc[`${val}_indexed`], listSpec('string'), null);
-                findexed?.length <= timecode + 1 && findexed.push(undefined as any as string);
+                findexed?.length <= timecode + 1 && findexed.push(undefined as unknown as string);
             });
             this.animDataFields(doc).forEach(val => {
                 const findexed = Cast(doc[`${val}_indexed`], listSpec(InkField), null);
-                findexed?.length <= timecode + 1 && findexed.push(undefined as any);
+                findexed?.length <= timecode + 1 && findexed.push(undefined as unknown as InkField);
             });
         });
         return newTimer;
@@ -286,7 +286,6 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     localRotation = () => this._props.rotation;
     render() {
         TraceMobx();
-
         return (
             <div
                 className={CollectionFreeFormDocumentView.CollectionFreeFormDocViewClassName}
@@ -304,10 +303,19 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                     <DocumentView
                         // eslint-disable-next-line react/jsx-props-no-spreading
                         {...OmitKeys(this._props,this.WrapperKeys.map(val => val.lower)).omit} // prettier-ignore
+                        Document={this._props.Document}
+                        renderDepth={this._props.renderDepth}
+                        isContentActive={this._props.isContentActive}
+                        childFilters={this._props.childFilters}
+                        childFiltersByRanges={this._props.childFilters}
+                        pinToPres={this._props.pinToPres}
+                        addDocTab={this._props.addDocTab}
+                        searchFilterDocs={this._props.searchFilterDocs}
+                        focus={this._props.focus}
+                        whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged}
                         reactParent={this}
                         DataTransition={this.DataTransition}
                         LocalRotation={this.localRotation}
-                        CollectionFreeFormDocumentView={this.returnThis}
                         styleProvider={this.styleProvider}
                         ScreenToLocalTransform={this.screenToLocalTransform}
                         isGroupActive={this.isGroupActive}
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index efaf6807a..1eae163df 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -162,14 +162,14 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
             () => this.clearDoc(which)
         );
     };
-    docStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string): any => {
+    docStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string) => {
         switch (property) {
             case StyleProp.PointerEvents: return 'none';
             default:                      return this._props.styleProvider?.(doc, props, property);
         } // prettier-ignore
     };
-    moveDoc1 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => toList(docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_1'), true);
-    moveDoc2 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => toList(docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_2'), true);
+    moveDoc1 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => toList(docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_1'), true);
+    moveDoc2 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => toList(docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_2'), true);
     remDoc1 = (docs: Doc | Doc[]) => toList(docs).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_1'), true);
     remDoc2 = (docs: Doc | Doc[]) => toList(docs).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_2'), true);
 
@@ -420,7 +420,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
 }
 
 Docs.Prototypes.TemplateMap.set(DocumentType.COMPARISON, {
-    data: '',
     layout: { view: ComparisonBox, dataField: 'data' },
     options: {
         acl: '',
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index baf8693ca..69277b054 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -50,7 +50,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     sidebarAddDoc: ((doc: Doc | Doc[], sidebarKey?: string | undefined) => boolean) | undefined;
     crop: ((region: Doc | undefined, addCrop?: boolean) => Doc | undefined) | undefined;
     @observable _marqueeing: number[] | undefined = undefined;
-    @observable _savedAnnotations = new ObservableMap<number, (HTMLDivElement & { marqueeing?: boolean})[]>();
+    @observable _savedAnnotations = new ObservableMap<number, (HTMLDivElement & { marqueeing?: boolean })[]>();
 
     constructor(props: FieldViewProps) {
         super(props);
@@ -150,7 +150,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         const visibleAnchor = AnchorMenu.Instance.GetAnchor?.(undefined, addAsAnnotation);
         const anchor = !pinProps
             ? this.Document
-            : this._vizRenderer?.getAnchor(pinProps) ??
+            : (this._vizRenderer?.getAnchor(pinProps) ??
               visibleAnchor ??
               Docs.Create.ConfigDocument({
                   title: 'ImgAnchor:' + this.Document.title,
@@ -161,7 +161,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                   // when we clear selection -> we should have it so chartBox getAnchor returns undefined
                   // this is for when we want the whole doc (so when the chartBox getAnchor returns without a marker)
                   /* put in some options */
-              });
+              }));
         anchor.config_dataViz = this.dataVizView;
         anchor.config_dataVizAxes = this.axes.length ? new List<string>(this.axes) : undefined;
         anchor.dataViz_selectedRows = Field.Copy(this.layoutDoc.dataViz_selectedRows);
@@ -450,7 +450,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
      *      it appears to the right of this document, with the
      *      parameters passed in being used to create an initial display
      */
-    createFilteredDoc = (axes?: any) => {
+    createFilteredDoc = (axes?: string[]) => {
         const embedding = Doc.MakeEmbedding(this.Document!);
         embedding._layout_showSidebar = false;
         embedding._dataViz = DataVizView.LINECHART;
diff --git a/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx b/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx
index 60bc8df18..a6a6a6b46 100644
--- a/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx
+++ b/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/label-has-associated-control */
-/* eslint-disable jsx-a11y/alt-text */
 import { IconButton } from 'browndash-components';
 import { action, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
index d2e82284e..7179356b2 100644
--- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx
+++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-noninteractive-tabindex */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
 import { Button, Type } from 'browndash-components';
 import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
@@ -24,7 +22,7 @@ const { DATA_VIZ_TABLE_ROW_HEIGHT } = require('../../../global/globalCssVariable
 interface TableBoxProps {
     Document: Doc;
     layoutDoc: Doc;
-    records: { [key: string]: any }[];
+    records: { [key: string]: unknown }[];
     selectAxes: (axes: string[]) => void;
     selectTitleCol: (titleCol: string) => void;
     axes: string[];
@@ -48,14 +46,14 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
     @observable settingTitle: boolean = false; // true when setting a title column
     @observable hasRowsToFilter: boolean = false; // true when any rows are selected
     @observable filtering: boolean = false; // true when the filtering menu is open
-    @observable filteringColumn: any = ''; // column to filter
+    @observable filteringColumn = ''; // column to filter
     @observable filteringType: string = 'Value'; // "Value" or "Range"
-    filteringVal: any[] = ['', '']; // value or range to filter the column with
+    filteringVal = ['', '']; // value or range to filter the column with
 
     @observable _scrollTop = -1;
     @observable _tableHeight = 0;
     @observable _tableContainerHeight = 0;
-    constructor(props: any) {
+    constructor(props: TableBoxProps) {
         super(props);
         makeObservable(this);
     }
@@ -141,17 +139,21 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
             e,
             moveEv => {
                 // dragging off a column to create a brushed DataVizBox
-                const sourceAnchorCreator = () => this._props.docView?.()!.Document!;
+                const sourceAnchorCreator = () => this._props.docView?.()?.Document || this._props.Document;
                 const targetCreator = (annotationOn: Doc | undefined) => {
-                    const embedding = Doc.MakeEmbedding(this._props.docView?.()!.Document!);
-                    embedding._dataViz = DataVizView.TABLE;
-                    embedding._dataViz_axes = new List<string>([col]);
-                    embedding._dataViz_parentViz = this._props.Document;
-                    embedding.annotationOn = annotationOn;
-                    embedding.histogramBarColors = Field.Copy(this._props.layoutDoc.histogramBarColors);
-                    embedding.defaultHistogramColor = this._props.layoutDoc.defaultHistogramColor;
-                    embedding.pieSliceColors = Field.Copy(this._props.layoutDoc.pieSliceColors);
-                    return embedding;
+                    const doc = this._props.docView?.()?.Document;
+                    if (doc) {
+                        const embedding = Doc.MakeEmbedding(doc);
+                        embedding._dataViz = DataVizView.TABLE;
+                        embedding._dataViz_axes = new List<string>([col]);
+                        embedding._dataViz_parentViz = this._props.Document;
+                        embedding.annotationOn = annotationOn;
+                        embedding.histogramBarColors = Field.Copy(this._props.layoutDoc.histogramBarColors);
+                        embedding.defaultHistogramColor = this._props.layoutDoc.defaultHistogramColor;
+                        embedding.pieSliceColors = Field.Copy(this._props.layoutDoc.pieSliceColors);
+                        return embedding;
+                    }
+                    return this._props.Document;
                 };
                 if (this._props.docView?.() && !ClientUtils.isClick(moveEv.clientX, moveEv.clientY, downX, downY, Date.now())) {
                     DragManager.StartAnchorAnnoDrag(moveEv.target instanceof HTMLElement ? [moveEv.target] : [], new DragManager.AnchorAnnoDragData(this._props.docView()!, sourceAnchorCreator, targetCreator), downX, downY, {
@@ -188,9 +190,9 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
     /**
      * These functions handle the filtering popup for when the "filter" button is pressed to select rows
      */
-    filter = undoable((e: any) => {
-        let start: any;
-        let end: any;
+    filter = undoable((e: React.MouseEvent) => {
+        let start: string | number;
+        let end: string | number;
         if (this.filteringType === 'Range') {
             start = Number.isNaN(Number(this.filteringVal[0])) ? this.filteringVal[0] : Number(this.filteringVal[0]);
             end = Number.isNaN(Number(this.filteringVal[1])) ? this.filteringVal[1] : Number(this.filteringVal[1]);
@@ -204,8 +206,8 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
                     }
                 }
             } else {
-                let compare = this._props.records[rowID][this.filteringColumn];
-                if (compare as Number) compare = Number(compare);
+                let compare = this._props.records[rowID][this.filteringColumn] as string | number;
+                if (Number(compare) == compare) compare = Number(compare);
                 if (start <= compare && compare <= end) {
                     if (!NumListCast(this._props.layoutDoc.dataViz_selectedRows).includes(rowID)) {
                         this.tableRowClick(e, rowID);
@@ -218,11 +220,11 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
         this.filteringVal = ['', ''];
     }, 'filter table');
     @action
-    setFilterColumn = (e: any) => {
+    setFilterColumn = (e: React.ChangeEvent<HTMLSelectElement>) => {
         this.filteringColumn = e.currentTarget.value;
     };
     @action
-    setFilterType = (e: any) => {
+    setFilterType = (e: React.ChangeEvent<HTMLSelectElement>) => {
         this.filteringType = e.currentTarget.value;
     };
     changeFilterValue = action((e: React.ChangeEvent<HTMLInputElement>) => {
@@ -240,7 +242,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
             <div className="tableBox-filterPopup" style={{ right: this._props.width * 0.05 }}>
                 <div className="tableBox-filterPopup-selectColumn">
                     Column:
-                    <select className="tableBox-filterPopup-selectColumn-each" value={this.filteringColumn !== '' ? this.filteringColumn : this.columns[0]} onChange={e => this.setFilterColumn(e)}>
+                    <select className="tableBox-filterPopup-selectColumn-each" value={this.filteringColumn !== '' ? this.filteringColumn : this.columns[0]} onChange={this.setFilterColumn}>
                         {this.columns.map(column => (
                             <option className="" key={column} value={column}>
                                 {' '}
@@ -250,7 +252,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
                     </select>
                 </div>
                 <div className="tableBox-filterPopup-setValue">
-                    <select className="tableBox-filterPopup-setValue-each" value={this.filteringType} onChange={e => this.setFilterType(e)}>
+                    <select className="tableBox-filterPopup-setValue-each" value={this.filteringType} onChange={this.setFilterType}>
                         <option className="" key="Value" value="Value">
                             {' '}
                             {'Value'}{' '}
@@ -307,7 +309,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
                     )}
                 </div>
                 <div className="tableBox-filterPopup-setFilter">
-                    <Button onClick={action(e => this.filter(e))} text="Set Filter" type={Type.SEC} color="black" />
+                    <Button onClick={this.filter} text="Set Filter" type={Type.SEC} color="black" />
                 </div>
             </div>
         );
@@ -451,7 +453,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
                                                 if (this._props.titleCol === col) colSelected = true;
                                                 return (
                                                     <td key={this.columns.indexOf(col)} style={{ border: colSelected ? '3px solid black' : '1px solid black', fontWeight: colSelected ? 'bolder' : 'normal' }}>
-                                                        <div className="tableBox-cell">{this._props.records[rowId][col]}</div>
+                                                        <div className="tableBox-cell">{this._props.records[rowId][col] as string | number}</div>
                                                     </td>
                                                 );
                                             })}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 192c7875e..8a2c4e530 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -43,26 +43,37 @@ interface HTMLtagProps {
 @observer
 export class HTMLtag extends React.Component<HTMLtagProps> {
     click = () => {
-        const clickScript = (this.props as any).onClick as Opt<ScriptField>;
+        const clickScript = this.props.onClick as Opt<ScriptField>;
         clickScript?.script.run({ this: this.props.Document, scale: this.props.scaling });
     };
-    onInput = (e: React.FormEvent<HTMLDivElement>) => {
-        const onInputScript = (this.props as any).onInput as Opt<ScriptField>;
-        onInputScript?.script.run({ this: this.props.Document, value: (e.target as any).textContent });
+    onInput = (e: React.FormEvent<unknown>) => {
+        const onInputScript = this.props.onInput as Opt<ScriptField>;
+        onInputScript?.script.run({ this: this.props.Document, value: (e.target as HTMLElement).textContent });
     };
     render() {
-        const style: { [key: string]: any } = {};
-        const divKeys = OmitKeys(this.props, ['children', 'dragStarting', 'dragEnding', 'htmltag', 'scaling', 'Document', 'key', 'onInput', 'onClick', '__proto__']).omit;
-        const replacer = (match: any, expr: string) =>
+        const style: { [key: string]: unknown } = {};
+        const divKeys = OmitKeys(this.props, [
+            'children', //
+            'dragStarting',
+            'dragEnding',
+            'htmltag',
+            'scaling',
+            'Document',
+            'key',
+            'onInput',
+            'onClick',
+            '__proto__',
+        ]).omit;
+        const replacer = (match: string, expr: string) =>
             // bcz: this executes a script to convert a property expression string:  { script }  into a value
             (ScriptField.MakeFunction(expr, { this: Doc.name, scale: 'number' })?.script.run({ this: this.props.Document, scale: this.props.scaling }).result as string) || '';
         Object.keys(divKeys).forEach((prop: string) => {
-            const p = (this.props as any)[prop] as string;
+            const p = (this.props as unknown as { [key: string]: string })[prop] as string;
             style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer);
         });
         const Tag = this.props.htmltag as keyof JSX.IntrinsicElements;
         return (
-            <Tag style={style} onClick={this.click} onInput={this.onInput as any}>
+            <Tag style={style} onClick={this.click} onInput={this.onInput}>
                 {this.props.children}
             </Tag>
         );
@@ -78,12 +89,12 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte
     /**
      * Set of all available rendering componets for Docs (e.g., ImageBox, CollectionFreeFormView, etc)
      */
-    private static Components: { [key: string]: any };
-    public static Init(defaultLayoutString: string, components: { [key: string]: any }) {
+    private static Components: { [key: string]: DocumentContentsViewProps };
+    public static Init(defaultLayoutString: string, components: { [key: string]: DocumentContentsViewProps }) {
         DocumentContentsView.DefaultLayoutString = defaultLayoutString;
         DocumentContentsView.Components = components;
     }
-    constructor(props: any) {
+    constructor(props: DocumentContentsViewProps) {
         super(props);
         makeObservable(this);
     }
@@ -132,13 +143,13 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte
             ...this._props,
             Document: this.layoutDoc ?? this._props.Document,
             TemplateDataDocument: templateDataDoc instanceof Promise ? undefined : templateDataDoc,
-            onClick: onClick as any as React.MouseEventHandler, // pass onClick script as if it were a real function -- it will be interpreted properly in the HTMLtag
-            onInput: onInput as any as React.FormEventHandler,
+            onClick: onClick as unknown as React.MouseEventHandler, // pass onClick script as if it were a real function -- it will be interpreted properly in the HTMLtag
+            onInput: onInput as unknown as React.FormEventHandler,
         };
         return {
             props: {
                 ...OmitKeys(list, [...docOnlyProps], '').omit,
-            },
+            } as BindingProps,
         };
     }
 
@@ -151,11 +162,11 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte
         let layoutFrame = this.layout;
 
         // replace code content with a script  >{content}<   as in  <HTMLdiv>{this.title}</HTMLdiv>
-        const replacer = (match: any, prefix: string, expr: string, postfix: string) => prefix + ((ScriptField.MakeFunction(expr, { this: Doc.name })?.script.run({ this: this._props.Document }).result as string) || '') + postfix;
+        const replacer = (match: string, prefix: string, expr: string, postfix: string) => prefix + ((ScriptField.MakeFunction(expr, { this: Doc.name })?.script.run({ this: this._props.Document }).result as string) || '') + postfix;
         layoutFrame = layoutFrame.replace(/(>[^{]*)[^=]\{([^.'][^<}]+)\}([^}]*<)/g, replacer);
 
         // replace HTML<tag> with corresponding HTML tag as in:  <HTMLdiv> becomes  <HTMLtag Document={props.Document} htmltag='div'>
-        const replacer2 = (match: any, p1: string) => `<HTMLtag Document={props.Document} scaling='${this._props.NativeDimScaling?.() || 1}' htmltag='${p1}'`;
+        const replacer2 = (match: string, p1: string) => `<HTMLtag Document={props.Document} scaling='${this._props.NativeDimScaling?.() || 1}' htmltag='${p1}'`;
         layoutFrame = layoutFrame.replace(/<HTML([a-zA-Z0-9_-]+)/g, replacer2);
 
         // replace /HTML<tag> with </HTMLdiv>  as in:  </HTMLdiv> becomes  </HTMLtag>
@@ -194,6 +205,7 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte
                 bindings={bindings}
                 jsx={layoutFrame}
                 showWarnings
+                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                 onError={(test: any) => {
                     console.log('DocumentContentsView:' + test, bindings, layoutFrame);
                 }}
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 0c5156339..c35a329c9 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@mui/material';
 import { action, computed, makeObservable, observable, runInAction } from 'mobx';
@@ -55,7 +53,7 @@ export class DocumentLinksButton extends ObservableReactComponent<DocumentLinksB
     @observable public static StartLinkView: DocumentView | undefined = undefined;
     @observable public static AnnotationId: string | undefined = undefined;
     @observable public static AnnotationUri: string | undefined = undefined;
-    constructor(props: any) {
+    constructor(props: DocumentLinksButtonProps) {
         super(props);
         makeObservable(this);
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 0f2905d5b..5ae232aa9 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,6 +1,7 @@
 /* eslint-disable no-use-before-define */
 /* eslint-disable react/jsx-props-no-spreading */
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
+import { Property } from 'csstype';
 import { Howl } from 'howler';
 import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
@@ -32,7 +33,7 @@ import { UPDATE_SERVER_CACHE } from '../../util/LinkManager';
 import { ScriptingGlobals } from '../../util/ScriptingGlobals';
 import { SearchUtil } from '../../util/SearchUtil';
 import { SnappingManager } from '../../util/SnappingManager';
-import { UndoManager, undoBatch, undoable } from '../../util/UndoManager';
+import { UndoManager, undoable } from '../../util/UndoManager';
 import { ContextMenu } from '../ContextMenu';
 import { ContextMenuProps } from '../ContextMenuItem';
 import { DocComponent } from '../DocComponent';
@@ -65,7 +66,7 @@ export interface DocumentViewProps extends FieldViewSharedProps {
     hideLinkAnchors?: boolean;
     hideLinkButton?: boolean;
     hideCaptions?: boolean;
-    contentPointerEvents?: 'none' | 'all' | undefined; // pointer events allowed for content of a document view.  eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents
+    contentPointerEvents?: Property.PointerEvents | undefined; // pointer events allowed for content of a document view.  eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents
     dontCenter?: 'x' | 'y' | 'xy';
     childHideDecorationTitle?: boolean;
     childHideResizeHandles?: boolean;
@@ -116,7 +117,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
     @observable _titleDropDownInnerWidth = 0; // width of menu dropdown when setting doc title
     @observable _mounted = false; // turn off all pointer events if component isn't yet mounted (enables nested Docs in alternate UI textboxes that appear on hover which otherwise would grab focus from the text box, reverting to the original UI )
     @observable _isContentActive: boolean | undefined = undefined;
-    @observable _pointerEvents: 'none' | 'all' | 'visiblePainted' | undefined = undefined;
+    @observable _pointerEvents: Property.PointerEvents | undefined = undefined;
     @observable _componentView: Opt<ViewBoxInterface<FieldViewProps>> = undefined; // needs to be accessed from DocumentView wrapper class
     @observable _animateScaleTime: Opt<number> = undefined; // milliseconds for animating between views.  defaults to 300 if not uset
     @observable _animateScalingTo = 0;
@@ -216,7 +217,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
             { fireImmediately: true }
         );
         this._disposers.pointerevents = reaction(
-            () => this.style(this.Document, StyleProp.PointerEvents) as 'all' | 'none' | 'visiblePainted' | undefined,
+            () => this.style(this.Document, StyleProp.PointerEvents) as Property.PointerEvents | undefined,
             pointerevents => {
                 this._pointerEvents = pointerevents;
             },
@@ -243,7 +244,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
         Object.values(this._disposers).forEach(disposer => disposer?.());
     }
 
-    startDragging(x: number, y: number, dropAction: dropActionType, hideSource = false) {
+    startDragging(x: number, y: number, dropAction: dropActionType | undefined, hideSource = false) {
         const docView = this._docView;
         if (this._mainCont.current && docView) {
             const views = DocumentView.Selected().filter(dv => dv.ContentDiv);
@@ -310,7 +311,8 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
                 const defaultDblclick = this._props.defaultDoubleClick?.() || this.Document.defaultDoubleClick;
                 undoable(() => {
                     if (this.onDoubleClickHdlr?.script) {
-                        this.onDoubleClickHdlr.script.run(scriptProps, console.log).result?.select && this._props.select(false);
+                        const res = this.onDoubleClickHdlr.script.run(scriptProps, console.log).result as { select: boolean };
+                        res.select && this._props.select(false);
                     } else if (!Doc.IsSystem(this.Document) && defaultDblclick !== 'ignore') {
                         this._props.addDocTab(this.Document, OpenWhere.lightboxAlways);
                         DocumentView.DeselectAll();
@@ -558,7 +560,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
         if (!this.Document.isFolder) {
             const templateDoc = Cast(this.Document[StrCast(this.Document.layout_fieldKey)], Doc, null);
             const appearance = cm.findByDescription('Appearance...');
-            const appearanceItems: ContextMenuProps[] = appearance && 'subitems' in appearance ? appearance.subitems : [];
+            const appearanceItems = appearance?.subitems ?? [];
 
             if (this._props.renderDepth === 0) {
                 appearanceItems.splice(0, 0, { description: 'Open in Lightbox', event: () => DocumentView.SetLightboxDoc(this.Document), icon: 'external-link-alt' });
@@ -574,7 +576,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
             // creates menu for the user to select how to reveal the flashcards
             if (this.Document._layout_isFlashcard) {
                 const revealOptions = cm.findByDescription('Reveal Options');
-                const revealItems: ContextMenuProps[] = revealOptions && 'subitems' in revealOptions ? revealOptions.subitems : [];
+                const revealItems = revealOptions?.subitems ?? [];
                 revealItems.push({ description: 'Hover', event: () => { this.layoutDoc[`_${this._props.fieldKey}_revealOp`] = 'hover'; }, icon: 'hand-point-up' }); // prettier-ignore
                 revealItems.push({ description: 'Flip', event: () => { this.layoutDoc[`_${this._props.fieldKey}_revealOp`] = 'flip'; }, icon: 'rotate' }); // prettier-ignore
                 !revealOptions && cm.addItem({ description: 'Reveal Options', addDivider: false, noexpand: true, subitems: revealItems, icon: 'layer-group' });
@@ -582,15 +584,16 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
 
             if (this._props.bringToFront) {
                 const zorders = cm.findByDescription('ZOrder...');
-                const zorderItems: ContextMenuProps[] = zorders && 'subitems' in zorders ? zorders.subitems : [];
+                const zorderItems = zorders?.subitems ?? [];
                 zorderItems.push({ description: 'Bring to Front', event: () => DocumentView.Selected().forEach(dv => dv._props.bringToFront?.(dv.Document, false)), icon: 'arrow-up' });
                 zorderItems.push({ description: 'Send to Back', event: () => DocumentView.Selected().forEach(dv => dv._props.bringToFront?.(dv.Document, true)), icon: 'arrow-down' });
                 zorderItems.push({
                     description: !this.layoutDoc._keepZDragged ? 'Keep ZIndex when dragged' : 'Allow ZIndex to change when dragged',
-                    event: undoBatch(
+                    event: undoable(
                         action(() => {
                             this.layoutDoc._keepZWhenDragged = !this.layoutDoc._keepZWhenDragged;
-                        })
+                        }),
+                        'set zIndex drag'
                     ),
                     icon: 'hand-point-up',
                 });
@@ -599,7 +602,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
 
             if (!Doc.IsSystem(this.Document) && !this.Document.hideClickBehaviors && !this._props.hideClickBehaviors) {
                 const existingOnClick = cm.findByDescription('OnClick...');
-                const onClicks: ContextMenuProps[] = existingOnClick && 'subitems' in existingOnClick ? existingOnClick.subitems : [];
+                const onClicks = existingOnClick?.subitems ?? [];
 
                 onClicks.push({ description: 'Enter Portal', event: undoable(() => DocUtils.makeIntoPortal(this.Document, this.layoutDoc, this._allLinks), 'make into portal'), icon: 'window-restore' });
                 !Doc.noviceMode && onClicks.push({ description: 'Toggle Detail', event: this.setToggleDetail, icon: 'concierge-bell' });
@@ -624,7 +627,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
             }
 
             const more = cm.findByDescription('More...');
-            const moreItems = more && 'subitems' in more ? more.subitems : [];
+            const moreItems = more?.subitems ?? [];
             if (!Doc.IsSystem(this.Document)) {
                 if (!Doc.noviceMode) {
                     moreItems.push({ description: 'Make View of Metadata Field', event: () => Doc.MakeMetadataFieldTemplate(this.Document, this._props.TemplateDataDocument), icon: 'concierge-bell' });
@@ -648,7 +651,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
         cm.addItem({ description: 'General...', noexpand: false, subitems: constantItems, icon: 'question' });
 
         const help = cm.findByDescription('Help...');
-        const helpItems: ContextMenuProps[] = help && 'subitems' in help ? help.subitems : [];
+        const helpItems = help?.subitems ?? [];
         !Doc.noviceMode && helpItems.push({ description: 'Text Shortcuts Ctrl+/', event: () => this._props.addDocTab(Docs.Create.PdfDocument('/assets/cheat-sheet.pdf', { _width: 300, _height: 300 }), OpenWhere.addRight), icon: 'keyboard' });
         !Doc.noviceMode && helpItems.push({ description: 'Print Document in Console', event: () => console.log(this.Document), icon: 'hand-point-right' });
         !Doc.noviceMode && helpItems.push({ description: 'Print DataDoc in Console', event: () => console.log(this.dataDoc), icon: 'hand-point-right' });
@@ -844,7 +847,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
                                 .map(field => Field.toKeyValueString(this.Document, field))
                                 .join('\\')
                         }
-                        SetValue={undoBatch((input: string) => {
+                        SetValue={undoable((input: string) => {
                             if (input?.startsWith('$')) {
                                 if (this.layoutDoc.layout_showTitle) {
                                     this.layoutDoc._layout_showTitle = input?.substring(1) ? input.substring(1) : undefined;
@@ -855,7 +858,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
                                 Doc.SetField(targetDoc, showTitle, input);
                             }
                             return true;
-                        })}
+                        }, 'set title')}
                     />
                 </div>
             </div>
@@ -1245,7 +1248,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
     public setToggleDetail = (scriptFieldKey = 'onClick') => this._docViewInternal?.setToggleDetail(scriptFieldKey);
     public onContextMenu = (e?: React.MouseEvent, pageX?: number, pageY?: number) => this._docViewInternal?.onContextMenu?.(e, pageX, pageY);
     public cleanupPointerEvents = () => this._docViewInternal?.cleanupPointerEvents();
-    public startDragging = (x: number, y: number, dropAction: dropActionType, hideSource = false) => this._docViewInternal?.startDragging(x, y, dropAction, hideSource);
+    public startDragging = (x: number, y: number, dropAction: dropActionType | undefined, hideSource = false) => this._docViewInternal?.startDragging(x, y, dropAction, hideSource);
     public showContextMenu = (pageX: number, pageY: number) => this._docViewInternal?.onContextMenu(undefined, pageX, pageY);
 
     public toggleNativeDimensions = () => this._docViewInternal && this.Document.type !== DocumentType.INK && Doc.toggleNativeDimensions(this.layoutDoc, this.NativeDimScaling() ?? 1, this._props.PanelWidth(), this._props.PanelHeight());
@@ -1288,7 +1291,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
                     this.dataDoc.audioAnnoState = AudioAnnoState.playing;
                     break;
                 case AudioAnnoState.playing:
-                    this.dataDoc[AudioPlay]?.stop();
+                    (this.dataDoc[AudioPlay] as Howl)?.stop();
                     this.dataDoc.audioAnnoState = AudioAnnoState.stopped;
                     break;
                 default:
diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx
index 1f5c9b84b..fefe25764 100644
--- a/src/client/views/nodes/EquationBox.tsx
+++ b/src/client/views/nodes/EquationBox.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
 import { action, makeObservable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -50,8 +49,8 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
             () => this._props.isSelected(),
             selected => {
                 if (this._ref.current) {
-                    if (selected) this._ref.current.element.current.children[0].addEventListener('keydown', this.keyPressed, true);
-                    else this._ref.current.element.current.children[0].removeEventListener('keydown', this.keyPressed);
+                    if (selected) (this._ref.current.element.current?.children[0] as HTMLElement).addEventListener('keydown', this.keyPressed, true);
+                    else (this._ref.current.element.current?.children[0] as HTMLElement).removeEventListener('keydown', this.keyPressed);
                 }
             },
             { fireImmediately: true }
@@ -60,8 +59,8 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
 
     @action
     keyPressed = (e: KeyboardEvent) => {
-        const _height = DivHeight(this._ref.current!.element.current);
-        const _width = DivWidth(this._ref.current!.element.current);
+        const _height = DivHeight(this._ref.current!.element?.current);
+        const _width = DivWidth(this._ref.current!.element?.current);
         if (e.key === 'Enter') {
             const nextEq = Docs.Create.EquationDocument(e.shiftKey ? StrCast(this.dataDoc.text) : 'x', {
                 title: '# math',
@@ -95,7 +94,7 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
     };
 
     updateSize = () => {
-        const style = this._ref.current && getComputedStyle(this._ref.current.element.current);
+        const style = this._ref.current?.element.current && getComputedStyle(this._ref.current.element.current);
         if (style?.width.endsWith('px') && style?.height.endsWith('px')) {
             if (this.layoutDoc._nativeWidth) {
                 // if equation has been scaled then editing the expression must also edit the native dimensions to keep the aspect ratio
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index fc59e9e26..dd71fd946 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -1,5 +1,6 @@
 /* eslint-disable react/no-unused-prop-types */
 /* eslint-disable react/require-default-props */
+import { Property } from 'csstype';
 import { computed } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -95,7 +96,7 @@ export interface FieldViewSharedProps {
     bringToFront?: (doc: Doc, sendToBack?: boolean) => void;
     waitForDoubleClickToClick?: () => 'never' | 'always' | undefined;
     defaultDoubleClick?: () => 'default' | 'ignore' | undefined;
-    pointerEvents?: () => Opt<'none' | 'all' | 'visiblePainted'>;
+    pointerEvents?: () => Opt<Property.PointerEvents>;
     suppressSetHeight?: boolean;
 }
 
diff --git a/src/client/views/nodes/FontIconBox/ButtonInterface.ts b/src/client/views/nodes/FontIconBox/ButtonInterface.ts
deleted file mode 100644
index 0d0d7b1c3..000000000
--- a/src/client/views/nodes/FontIconBox/ButtonInterface.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { IconProp } from '@fortawesome/fontawesome-svg-core';
-import { Doc } from '../../../../fields/Doc';
-import { ButtonType } from './FontIconBox';
-
-export interface IButtonProps {
-    type: string | ButtonType;
-    Document: Doc;
-    label: any;
-    icon: IconProp;
-    color: string;
-    backgroundColor: string;
-}
diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
index ffb668b03..f2f7f39bb 100644
--- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
@@ -73,12 +73,12 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
     Icon = (color: string, iconFalse?: boolean) => {
         let icon;
         if (iconFalse) {
-            icon = StrCast(this.dataDoc[this.fieldKey ?? 'iconFalse'] ?? this.dataDoc.icon, 'user') as any;
+            icon = StrCast(this.dataDoc[this.fieldKey ?? 'iconFalse'] ?? this.dataDoc.icon, 'user') as IconProp;
             if (icon) return <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />;
             return null;
         }
-        icon = StrCast(this.dataDoc[this.fieldKey ?? 'icon'] ?? this.dataDoc.icon, 'user') as any;
-        return !icon ? null : icon === 'pres-trail' ? TrailsIcon(color) : <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />;
+        icon = StrCast(this.dataDoc[this.fieldKey ?? 'icon'] ?? this.dataDoc.icon, 'user') as IconProp;
+        return !icon ? null : icon === ('pres-trail' as IconProp) ? TrailsIcon(color) : <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />;
     };
     @computed get dropdown() {
         return BoolCast(this.Document.dropDownOpen);
@@ -117,7 +117,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
                 break;
         } // prettier-ignore
         const numScript = (value?: number) => ScriptCast(this.Document.script).script.run({ this: this.Document, value, _readOnly_: value === undefined });
-        const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color);
+        const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string;
         // Script for checking the outcome of the toggle
         const checkResult = Number(Number(numScript().result ?? 0).toPrecision(NumCast(this.dataDoc.numPrecision, 3)));
 
@@ -142,7 +142,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
         setupMoveUpEvents(
             this,
             e,
-            () => ScriptCast(this.Document.onDragScript)?.script.run({ this: this.Document, value: { doc: value, e } }).result,
+            () => ScriptCast(this.Document.onDragScript)?.script.run({ this: this.Document, value: { doc: value, e } }).result as boolean,
             emptyFunction,
             emptyFunction
         ); // prettier-ignore
@@ -157,11 +157,11 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
 
         let noviceList: string[] = [];
         let text: string | undefined;
-        let getStyle: (val: string) => any = () => {};
+        let getStyle: (val: string) => { [key: string]: string } = () => ({});
         let icon: IconProp = 'caret-down';
         const isViewDropdown = script?.script.originalScript.startsWith('{ return setView');
         if (isViewDropdown) {
-            const selected = Array.from(script?.script.run({ _readOnly_: true }).result) as Doc[];
+            const selected = Array.from(script?.script.run({ _readOnly_: true }).result as Doc[]);
             // const selected = DocumentView.SelectedDocs();
             if (selected.lastElement()) {
                 if (StrCast(selected.lastElement().type) === DocumentType.COL) {
@@ -190,7 +190,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
             }
             noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Carousel3D, CollectionViewType.Stacking, CollectionViewType.NoteTaking];
         } else {
-            text = script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result;
+            text = script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result as string;
             // text = StrCast((RichTextMenu.Instance?.TextView?.EditorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
             getStyle = (val: string) => ({ fontFamily: val });
         }
@@ -231,8 +231,8 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
      * Color button
      */
     @computed get colorButton() {
-        const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color);
-        const curColor = this.colorScript?.script.run({ this: this.Document, value: undefined, _readOnly_: true }).result ?? 'transparent';
+        const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string;
+        const curColor = (this.colorScript?.script.run({ this: this.Document, value: undefined, _readOnly_: true }).result as string) ?? 'transparent';
         const tooltip: string = StrCast(this.Document.toolTip);
 
         return (
@@ -251,7 +251,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
                 type={Type.PRIM}
                 color={color}
                 background={SnappingManager.userBackgroundColor}
-                icon={this.Icon(color)!}
+                icon={this.Icon(color) ?? undefined}
                 tooltip={tooltip}
                 label={this.label}
             />
@@ -262,9 +262,9 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
         const tooltip: string = StrCast(this.Document.toolTip);
 
         const script = ScriptCast(this.Document.onClick)?.script;
-        const toggleStatus = script?.run({ this: this.Document, self: this.Document, value: undefined, _readOnly_: true }).result;
+        const toggleStatus = script?.run({ this: this.Document, self: this.Document, value: undefined, _readOnly_: true }).result as boolean;
         // Colors
-        const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color);
+        const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string;
         const items = DocListCast(this.dataDoc.data);
         const multiDoc = this.Document;
         return (
@@ -272,13 +272,13 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
                 tooltip={`Toggle ${tooltip}`}
                 type={Type.PRIM}
                 color={color}
-                onPointerDown={e => script && !toggleStatus && setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => script.run({ this: multiDoc, value: undefined, _readOnly_: false }))}
+                onPointerDown={e => script && !toggleStatus && setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => script.run({ this: multiDoc, value: undefined, _readOnly_: false }))}
                 isToggle={script ? true : false}
                 toggleStatus={toggleStatus}
                 //background={SnappingManager.userBackgroundColor}
                 label={this.label}
                 items={DocListCast(this.dataDoc.data).map(item => ({
-                    icon: <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={StrCast(item.icon) as any} color={color} />,
+                    icon: <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={StrCast(item.icon) as IconProp} color={color} />,
                     tooltip: StrCast(item.toolTip),
                     val: StrCast(item.toolType),
                 }))}
@@ -300,9 +300,9 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
 
         const script = ScriptCast(this.Document.onClick);
         const double = ScriptCast(this.Document.onDoubleClick);
-        const toggleStatus = script?.script.run({ this: this.Document, value: undefined, _readOnly_: true }).result ?? false;
+        const toggleStatus = (script?.script.run({ this: this.Document, value: undefined, _readOnly_: true }).result as boolean) ?? false;
         // Colors
-        const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color);
+        const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string;
         // const backgroundColor = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor);
 
         return (
@@ -337,30 +337,30 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
      * Default
      */
     @computed get defaultButton() {
-        const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color);
-        const tooltip: string = StrCast(this.Document.toolTip);
+        const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string;
+        const tooltip = StrCast(this.Document.toolTip);
 
-        return <IconButton tooltip={tooltip} icon={this.Icon(color)!} label={this.label} />;
+        return <IconButton tooltip={tooltip} icon={this.Icon(color) ?? undefined} label={this.label} />;
     }
 
     @computed get editableText() {
         const script = ScriptCast(this.Document.script);
         const checkResult = script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result;
 
-        const setValue = (value: string): boolean => script?.script.run({ this: this.Document, value, _readOnly_: false }).result;
+        const setValue = (value: string) => script?.script.run({ this: this.Document, value, _readOnly_: false }).result as boolean;
 
         return (
             <div className="menuButton editableText">
                 <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon="lock" />
                 <div style={{ width: 'calc(100% - .875em)', paddingLeft: '4px' }}>
-                    <EditableView GetValue={() => script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result} SetValue={setValue} oneLine contents={checkResult} />
+                    <EditableView GetValue={() => script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result as string} SetValue={setValue} oneLine contents={checkResult} />
                 </div>
             </div>
         );
     }
 
     renderButton = () => {
-        const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color);
+        const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string;
         const tooltip = StrCast(this.Document.toolTip);
         const scriptFunc = () => ScriptCast(this.Document.onClick)?.script.run({ this: this.Document, _readOnly_: false });
         const btnProps = { tooltip, icon: this.Icon(color)!, label: this.label };
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index ce7552047..51dd494da 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -35,6 +35,7 @@ import { FieldView, FieldViewProps } from './FieldView';
 import { FocusViewOptions } from './FocusViewOptions';
 import './ImageBox.scss';
 import { OpenWhere } from './OpenWhere';
+import { SnappingManager } from '../../util/SnappingManager';
 
 export class ImageEditorData {
     // eslint-disable-next-line no-use-before-define
@@ -73,7 +74,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     private _marqueeref = React.createRef<MarqueeAnnotator>();
     private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
     private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
-    @observable _savedAnnotations = new ObservableMap<number, (HTMLDivElement & { marqueeing?: boolean})[]>();
+    @observable _savedAnnotations = new ObservableMap<number, (HTMLDivElement & { marqueeing?: boolean })[]>();
     @observable _curSuffix = '';
     @observable _error = '';
     @observable _isHovering = false; // flag to switch between primary and alternate images on hover
@@ -328,7 +329,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                         })
                     }
                     style={{
-                        display: (this._props.isContentActive() !== false && DragManager.DocDragData?.canEmbed) || this.dataDoc[this.fieldKey + '_alternates'] ? 'block' : 'none',
+                        display: (this._props.isContentActive() !== false && SnappingManager.CanEmbed) || this.dataDoc[this.fieldKey + '_alternates'] ? 'block' : 'none',
                         width: 'min(10%, 25px)',
                         height: 'min(10%, 25px)',
                         background: usePath === undefined ? 'white' : usePath === 'alternate' ? 'black' : 'gray',
@@ -346,7 +347,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         const defaultUrl = new URL(ClientUtils.prepend('/assets/unknown-file-icon-hi.png'));
         const altpaths =
             alts
-                ?.map(doc => (doc instanceof Doc ? ImageCast(doc[Doc.LayoutFieldKey(doc)])?.url ?? defaultUrl : defaultUrl))
+                ?.map(doc => (doc instanceof Doc ? (ImageCast(doc[Doc.LayoutFieldKey(doc)])?.url ?? defaultUrl) : defaultUrl))
                 .filter(url => url)
                 .map(url => this.choosePath(url)) ?? []; // acc  ess the primary layout data of the alternate documents
         const paths = field ? [this.choosePath(field.url), ...altpaths] : altpaths;
@@ -356,7 +357,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     @computed get content() {
         TraceMobx();
 
-        const backColor = DashColor(this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string ?? Colors.WHITE);
+        const backColor = DashColor((this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string) ?? Colors.WHITE);
         const backAlpha = backColor.red() === 0 && backColor.green() === 0 && backColor.blue() === 0 ? backColor.alpha() : 1;
         const srcpath = this.layoutDoc.hideImage ? '' : this.paths[0];
         const fadepath = this.layoutDoc.hideImage ? '' : this.paths.lastElement();
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index 66e210c03..9e77e0973 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable jsx-a11y/control-has-associated-label */
 import { action, computed, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -35,7 +34,7 @@ export class KeyValueBox extends ViewBoxBaseComponent<FieldViewProps>() {
     public static LayoutString() {
         return FieldView.LayoutString(KeyValueBox, 'data');
     }
-    constructor(props: any) {
+    constructor(props: FieldViewProps) {
         super(props);
         makeObservable(this);
     }
@@ -88,7 +87,7 @@ export class KeyValueBox extends ViewBoxBaseComponent<FieldViewProps>() {
         const type: 'computed' | 'script' | false = rawvalue.startsWith(':=') ? 'computed' : rawvalue.startsWith('$=') ? 'script' : false;
         rawvalue = type ? rawvalue.substring(2) : rawvalue;
         rawvalue = rawvalue.replace(/.*\(\((.*)\)\)/, 'dashCallChat(_setCacheResult_, this, `$1`)');
-        const value = ["'", '"', '`'].includes(rawvalue.length ? rawvalue[0] : '') || !isNaN(rawvalue as any) ? rawvalue : '`' + rawvalue + '`';
+        const value = ["'", '"', '`'].includes(rawvalue.length ? rawvalue[0] : '') || !isNaN(+rawvalue) ? rawvalue : '`' + rawvalue + '`';
 
         let script = ScriptField.CompileScript(rawvalue, {}, true, undefined, DocumentIconContainer.getTransformer());
         if (!script.compiled) {
@@ -116,7 +115,7 @@ export class KeyValueBox extends ViewBoxBaseComponent<FieldViewProps>() {
                     if (key) target[key] = script.originalScript;
                     return false;
                 }
-                field === undefined && (field = res.result instanceof Array ? new List<any>(res.result) : res.result);
+                field === undefined && (field = res.result instanceof Array ? new List<FieldType>(res.result) : (res.result as FieldType));
             }
         }
         if (!key) return false;
@@ -165,7 +164,6 @@ export class KeyValueBox extends ViewBoxBaseComponent<FieldViewProps>() {
 
         const rows: JSX.Element[] = [];
         let i = 0;
-        const self = this;
         const keys = Object.keys(ids).slice();
         // for (const key of [...keys.filter(id => id !== 'layout' && !id.includes('_')).sort(), ...keys.filter(id => id === 'layout' || id.includes('_')).sort()]) {
         const sortedKeys = keys.sort((a: string, b: string) => {
@@ -184,12 +182,12 @@ export class KeyValueBox extends ViewBoxBaseComponent<FieldViewProps>() {
                     addDocTab={this._props.addDocTab}
                     PanelWidth={this._props.PanelWidth}
                     PanelHeight={this.rowHeight}
-                    ref={(function () {
+                    ref={(() => {
                         let oldEl: KeyValuePair | undefined;
                         return (el: KeyValuePair) => {
-                            if (oldEl) self.rows.splice(self.rows.indexOf(oldEl), 1);
+                            if (oldEl) this.rows.splice(this.rows.indexOf(oldEl), 1);
                             oldEl = el;
-                            if (el) self.rows.push(el);
+                            if (el) this.rows.push(el);
                         };
                     })()}
                     keyWidth={100 - this._splitPercentage}
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 0956be3e9..3023716b1 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable jsx-a11y/control-has-associated-label */
 import { Tooltip } from '@mui/material';
 import { action, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
@@ -9,7 +8,7 @@ import { Doc, Field } from '../../../fields/Doc';
 import { DocCast } from '../../../fields/Types';
 import { DocumentOptions, FInfo } from '../../documents/Documents';
 import { Transform } from '../../util/Transform';
-import { undoBatch } from '../../util/UndoManager';
+import { undoable } from '../../util/UndoManager';
 import { ContextMenu } from '../ContextMenu';
 import { EditableView } from '../EditableView';
 import { ObservableReactComponent } from '../ObservableReactComponent';
@@ -34,7 +33,7 @@ export class KeyValuePair extends ObservableReactComponent<KeyValuePairProps> {
     @observable private isPointerOver = false;
     @observable public isChecked = false;
     private checkbox = React.createRef<HTMLInputElement>();
-    constructor(props: any) {
+    constructor(props: KeyValuePairProps) {
         super(props);
         makeObservable(this);
     }
@@ -91,11 +90,11 @@ export class KeyValuePair extends ObservableReactComponent<KeyValuePairProps> {
                             type="button"
                             style={hover}
                             className="keyValuePair-td-key-delete"
-                            onClick={undoBatch(() => {
+                            onClick={undoable(() => {
                                 if (Object.keys(this._props.doc).indexOf(this._props.keyName) !== -1) {
                                     delete this._props.doc[this._props.keyName];
                                 } else delete DocCast(this._props.doc.proto)?.[this._props.keyName];
-                            })}>
+                            }, 'set key value')}>
                             X
                         </button>
                         <input className="keyValuePair-td-key-check" type="checkbox" style={hover} onChange={this.handleCheck} ref={this.checkbox} />
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 8d6ae9f73..4d9d2460e 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -27,6 +27,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
     public static LayoutString(fieldKey: string = 'link') {
         return FieldView.LayoutString(LinkBox, fieldKey);
     }
+    _hackToSeeIfDeleted: NodeJS.Timeout | undefined;
     _disposers: { [name: string]: IReactionDisposer } = {};
     @observable _forceAnimate: number = 0; // forces xArrow to animate when a transition animation is detected on something that affects an anchor
     @observable _hide = false; // don't render if anchor is not visible since that breaks xAnchor
@@ -43,7 +44,6 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
         const anchor = anch?.layout_unrendered ? DocCast(anch.annotationOn) : anch;
         return DocumentView.getDocumentView(anchor, this.DocumentView?.().containerViewPath?.().lastElement());
     };
-    _hackToSeeIfDeleted: any;
     componentWillUnmount() {
         this._hackToSeeIfDeleted && clearTimeout(this._hackToSeeIfDeleted);
         Object.keys(this._disposers).forEach(key => this._disposers[key]());
@@ -68,7 +68,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
                 let a1 = a && document.getElementById(a.ViewGuid);
                 let a2 = b && document.getElementById(b.ViewGuid);
                 // test whether the anchors themselves are hidden,...
-                if (!a1 || !a2 || (a?.ContentDiv as any)?.hidden || (b?.ContentDiv as any)?.hidden) this._hide = true;
+                if (!a1 || !a2 || a?.ContentDiv?.hidden || b?.ContentDiv?.hidden) this._hide = true;
                 else {
                     // .. or whether any of their DOM parents are hidden
                     for (; a1 && !a1.hidden; a1 = a1.parentElement);
@@ -151,11 +151,11 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
                         this._forceAnimate += 0.01;
                     })
                 ); // this forces an update during a transition animation
-            const highlight = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Highlighting);
+            const highlight = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Highlighting) as { highlightStyle: string; highlightColor: string; highlightIndex: number; highlightStroke: boolean };
             const highlightColor = highlight?.highlightIndex ? highlight?.highlightColor : undefined;
-            const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color);
-            const fontFamily = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontFamily);
-            const fontSize = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontSize);
+            const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string;
+            const fontFamily = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontFamily) as string;
+            const fontSize = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontSize) as number;
             const fontColor = (c => (c !== 'transparent' ? c : undefined))(StrCast(this.layoutDoc.link_fontColor));
             // eslint-disable-next-line camelcase
             const { stroke_markerScale: strokeMarkerScale, stroke_width: strokeRawWidth, stroke_startMarker: strokeStartMarker, stroke_endMarker: strokeEndMarker, stroke_dash: strokeDash } = this.Document;
@@ -248,7 +248,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
             2
         );
         return (
-            <div className={`linkBox-container${this._props.isContentActive() ? '-interactive' : ''}`} style={{ background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) }}>
+            <div className={`linkBox-container${this._props.isContentActive() ? '-interactive' : ''}`} style={{ background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string }}>
                 <ComparisonBox
                     // eslint-disable-next-line react/jsx-props-no-spreading
                     {...this.props} //
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 8f29600f6..10ff86a38 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -67,7 +67,7 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
     @observable _linkSrc: Opt<Doc> = undefined;
     @observable _toolTipText = '';
     @observable _hrefInd = 0;
-    constructor(props: any) {
+    constructor(props: LinkDocPreviewProps) {
         super(props);
         makeObservable(this);
     }
@@ -104,7 +104,7 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
     }
 
     onPointerDown = (e: PointerEvent) => {
-        !this._linkDocRef.current?.contains(e.target as any) && LinkInfo.Clear(); // close preview when not clicking anywhere other than the info bar of the preview
+        !this._linkDocRef.current?.contains(e.target as HTMLElement) && LinkInfo.Clear(); // close preview when not clicking anywhere other than the info bar of the preview
     };
 
     @action
@@ -144,7 +144,7 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
                                 this._linkSrc = anchor;
                                 const linkTarget = Doc.getOppositeAnchor(this._linkDoc, this._linkSrc);
                                 this._markerTargetDoc = linkTarget;
-                                this._targetDoc = /* linkTarget?.type === DocumentType.MARKER && */ linkTarget?.annotationOn ? Cast(linkTarget.annotationOn, Doc, null) ?? linkTarget : linkTarget;
+                                this._targetDoc = /* linkTarget?.type === DocumentType.MARKER && */ linkTarget?.annotationOn ? (Cast(linkTarget.annotationOn, Doc, null) ?? linkTarget) : linkTarget;
                             }
                             if (LinkInfo.Instance?.LinkInfo?.noPreview || this._linkSrc?.followLinkToggle || this._markerTargetDoc?.type === DocumentType.PRES) this.followLink();
                         }
diff --git a/src/client/views/nodes/LoadingBox.tsx b/src/client/views/nodes/LoadingBox.tsx
index 5f343bdfe..325ab18b4 100644
--- a/src/client/views/nodes/LoadingBox.tsx
+++ b/src/client/views/nodes/LoadingBox.tsx
@@ -39,7 +39,7 @@ export class LoadingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         return FieldView.LayoutString(LoadingBox, fieldKey);
     }
 
-    _timer: any;
+    _timer: NodeJS.Timeout | undefined;
     @observable progress = '';
     componentDidMount() {
         if (!Doc.CurrentlyLoading?.includes(this.Document)) {
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index d7687e03e..c66f7c726 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 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';
@@ -481,8 +479,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         console.log('deleting');
         if (this._selectedPinOrRoute) {
             // Removes filter
-            Doc.setDocFilter(this.Document, 'latitude', this._selectedPinOrRoute.latitude, 'remove');
-            Doc.setDocFilter(this.Document, 'longitude', this._selectedPinOrRoute.longitude, 'remove');
+            Doc.setDocFilter(this.Document, 'latitude', NumCast(this._selectedPinOrRoute.latitude), 'remove');
+            Doc.setDocFilter(this.Document, 'longitude', NumCast(this._selectedPinOrRoute.longitude), 'remove');
             Doc.setDocFilter(this.Document, LinkedTo, `mapPin=${Field.toScriptString(DocCast(this._selectedPinOrRoute))}`, 'remove');
 
             this.removePushpinOrRoute(this._selectedPinOrRoute);
@@ -1152,7 +1150,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     _textRef = React.createRef<any>();
     render() {
         const scale = this._props.NativeDimScaling?.() || 1;
-        const parscale = scale === 1 ? 1 : this.ScreenToLocalBoxXf().Scale ?? 1;
+        const parscale = scale === 1 ? 1 : (this.ScreenToLocalBoxXf().Scale ?? 1);
 
         return (
             <div className="mapBox" ref={this._ref}>
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 8db68ddfe..c03694dd9 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/control-has-associated-label */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
@@ -76,7 +74,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                 });
             else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href))
                 PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then(
-                    action((pdf: any) => {
+                    action(pdf => {
                         this._pdf = pdf;
                     })
                 );
@@ -108,7 +106,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     };
 
     crop = (region: Doc | undefined, addCrop?: boolean) => {
-        if (!region) return undefined;
+        const docViewContent = this.DocumentView?.().ContentDiv;
+        if (!region || !docViewContent) return undefined;
         const cropping = Doc.MakeCopy(region, true);
         cropping.layout_unrendered = false; // text selection have this
         cropping.text_inlineAnnotations = undefined; // text selections have this -- it causes them not to be rendered.
@@ -120,7 +119,6 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         regionData.followLinkToggle = true;
         this.addDocument(region);
 
-        const docViewContent = this.DocumentView?.().ContentDiv!;
         const newDiv = docViewContent.cloneNode(true) as HTMLDivElement;
         newDiv.style.width = NumCast(this.layoutDoc._width).toString();
         newDiv.style.height = NumCast(this.layoutDoc._height).toString();
@@ -162,7 +160,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             (NumCast(region.x) * this._props.PanelWidth()) / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']),
             4
         )
-            .then((dataUrl: any) => {
+            .then(dataUrl => {
                 ClientUtils.convertDataUri(dataUrl, region[Id]).then(returnedfilename =>
                     setTimeout(
                         action(() => {
@@ -172,7 +170,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                     )
                 );
             })
-            .catch((error: any) => {
+            .catch(error => {
                 console.error('oops, something went wrong!', error);
             });
 
@@ -181,9 +179,10 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
 
     updateIcon = () => {
         // currently we render pdf icons as text labels
-        const docViewContent = this.DocumentView?.().ContentDiv!;
+        const docViewContent = this.DocumentView?.().ContentDiv;
         const filename = this.layoutDoc[Id] + '-icon' + new Date().getTime();
         this._pdfViewer?._mainCont.current &&
+            docViewContent &&
             UpdateIcon(
                 filename,
                 docViewContent,
@@ -475,6 +474,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         const cm = ContextMenu.Instance;
         const options = cm.findByDescription('Options...');
         const optionItems: ContextMenuProps[] = options && 'subitems' in options ? options.subitems : [];
+
         !Doc.noviceMode && optionItems.push({ description: 'Toggle Sidebar Type', event: this.toggleSidebarType, icon: 'expand-arrows-alt' });
         !Doc.noviceMode && optionItems.push({ description: 'update icon', event: () => this.pdfUrl && this.updateIcon(), icon: 'expand-arrows-alt' });
         // optionItems.push({ description: "Toggle Sidebar ", event: () => this.toggleSidebar(), icon: "expand-arrows-alt" });
@@ -656,7 +656,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             else {
                 if (!PDFBox.pdfpromise.get(href)) PDFBox.pdfpromise.set(href, Pdfjs.getDocument(href).promise);
                 PDFBox.pdfpromise.get(href)?.then(
-                    action((pdf: any) => {
+                    action(pdf => {
                         PDFBox.pdfcache.set(href, (this._pdf = pdf));
                     })
                 );
diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx
index f88eb3bca..31a1a398b 100644
--- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx
+++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx
@@ -1,8 +1,5 @@
 /* eslint-disable camelcase */
-/* eslint-disable jsx-a11y/control-has-associated-label */
 /* eslint-disable @typescript-eslint/no-unused-vars */
-/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 /* eslint-disable react/no-array-index-key */
 /* eslint-disable react/jsx-props-no-spreading */
 /* eslint-disable no-return-assign */
@@ -1009,7 +1006,7 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
                                 <Dialog maxWidth="sm" fullWidth open={BoolCast(this.dataDoc.hintDialogueOpen)} onClose={() => (this.dataDoc.hintDialogueOpen = false)}>
                                     <DialogTitle>Hints</DialogTitle>
                                     <DialogContent>
-                                        {this.selectedQuestion.hints?.map((hint: any, index: number) => (
+                                        {this.selectedQuestion.hints?.map((hint: { description: string; content: string }, index: number) => (
                                             <div key={index}>
                                                 <DialogContentText>
                                                     <details>
@@ -1985,7 +1982,13 @@ export class PhysicsSimulationBox extends ViewBoxAnnotatableComponent<FieldViewP
 }
 
 Docs.Prototypes.TemplateMap.set(DocumentType.SIMULATION, {
-    data: '',
     layout: { view: PhysicsSimulationBox, dataField: 'data' },
-    options: { acl: '', _width: 1000, _height: 800, mass1: '', mass2: '', layout_nativeDimEditable: true, position: '', acceleration: '', pendulum: '', spring: '', wedge: '', simulation: '', review: '', systemIcon: 'BsShareFill' },
+    options: {
+        acl: '',
+        _width: 1000,
+        _height: 800,
+        _layout_nativeDimEditable: true,
+        systemIcon: 'BsShareFill',
+        // mass1: '', mass2: '', position: '', acceleration: '', pendulum: '', spring: '', wedge: '', simulation: '', review: ''
+    },
 });
diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx
index 07381c7d0..7ba313e92 100644
--- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx
@@ -55,8 +55,7 @@ export class RecordingBox extends ViewBoxBaseComponent<FieldViewProps>() {
         this.dataDoc[this._props.fieldKey] = new VideoField(this.result.accessPaths.client);
         // stringify the presentation and store it
         if (presentation?.movements) {
-            const presCopy = { ...presentation };
-            presCopy.movements = presentation.movements.map(movement => ({ ...movement, doc: movement.doc[Id] })) as any;
+            const presCopy = { ...presentation, movements: presentation.movements.map(movement => ({ ...movement, doc: (movement.doc as Doc)[Id] })) };
             this.dataDoc[this.fieldKey + '_presentation'] = JSON.stringify(presCopy);
         }
     };
@@ -210,7 +209,7 @@ ScriptingGlobals.add(function getCurrentRecording() {
 });
 // eslint-disable-next-line prefer-arrow-callback
 ScriptingGlobals.add(function getWorkspaceRecordings() {
-    return new List<any>(['Record Workspace', `Record Webcam`, ...DocListCast(Doc.UserDoc().workspaceRecordings)]);
+    return new List<string | Doc>(['Record Workspace', `Record Webcam`, ...DocListCast(Doc.UserDoc().workspaceRecordings)]);
 });
 // eslint-disable-next-line prefer-arrow-callback
 ScriptingGlobals.add(function isWorkspaceRecording() {
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index 9ef1071f7..6289470b6 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -20,7 +20,7 @@ import { DocumentType } from '../../documents/DocumentTypes';
 import { Docs } from '../../documents/Documents';
 import { CaptureManager } from '../../util/CaptureManager';
 import { SettingsManager } from '../../util/SettingsManager';
-import { TrackMovements } from '../../util/TrackMovements';
+import { Movement, TrackMovements } from '../../util/TrackMovements';
 import { ContextMenu } from '../ContextMenu';
 import { ViewBoxAnnotatableComponent } from '../DocComponent';
 import { DocViewUtils } from '../DocViewUtils';
@@ -31,10 +31,11 @@ import { FieldView, FieldViewProps } from './FieldView';
 import './ScreenshotBox.scss';
 import { VideoBox } from './VideoBox';
 import { FormattedTextBox } from './formattedText/FormattedTextBox';
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
 
-declare class MediaRecorder {
-    constructor(e: any, options?: any); // whatever MediaRecorder has
-}
+// declare class MediaRecorder {
+//     constructor(e: any, options?: any); // whatever MediaRecorder has
+// }
 
 // interface VideoTileProps {
 //     raised: { coord: Vector2, off: Vector3 }[];
@@ -117,8 +118,8 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     public static LayoutString(fieldKey: string) {
         return FieldView.LayoutString(ScreenshotBox, fieldKey);
     }
-    private _audioRec: any;
-    private _videoRec: any;
+    private _audioRec: MediaRecorder | undefined;
+    private _videoRec: MediaRecorder | undefined;
     @observable private _videoRef: HTMLVideoElement | null = null;
     @observable _screenCapture = false;
     @computed get recordingStart() {
@@ -136,7 +137,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     };
 
     videoLoad = () => {
-        const aspect = this._videoRef!.videoWidth / this._videoRef!.videoHeight;
+        const aspect = (this._videoRef?.videoWidth || 0) / (this._videoRef?.videoHeight || 1);
         const nativeWidth = Doc.NativeWidth(this.layoutDoc);
         const nativeHeight = Doc.NativeHeight(this.layoutDoc);
         if (!nativeWidth || !nativeHeight) {
@@ -166,7 +167,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     }
 
     specificContextMenu = (): void => {
-        const subitems = [{ description: 'Screen Capture', event: this.toggleRecording, icon: 'expand-arrows-alt' as any }];
+        const subitems = [{ description: 'Screen Capture', event: this.toggleRecording, icon: 'expand-arrows-alt' as IconProp }];
         ContextMenu.Instance.addItem({ description: 'Options...', subitems, icon: 'video' });
     };
 
@@ -221,29 +222,29 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     Pause = () => this._screenCapture && this.toggleRecording();
 
     toggleRecording = async () => {
-        if (!this._screenCapture) {
+        if (!this._screenCapture && this._videoRef) {
             this._audioRec = new MediaRecorder(await navigator.mediaDevices.getUserMedia({ audio: true }));
-            const audChunks: any = [];
-            this._audioRec.ondataavailable = (e: any) => audChunks.push(e.data);
+            const audChunks: Blob[] = [];
+            this._audioRec.ondataavailable = e => audChunks.push(e.data);
             this._audioRec.onstop = async () => {
-                const [{ result }] = await Networking.UploadFilesToServer(audChunks.map((file: any) => ({ file })));
+                const [{ result }] = await Networking.UploadFilesToServer(audChunks.map(file => ({ file })));
                 if (!(result instanceof Error)) {
                     this.dataDoc[this._props.fieldKey + '_audio'] = new AudioField(result.accessPaths.agnostic.client);
                 }
             };
-            this._videoRef!.srcObject = await (navigator.mediaDevices as any).getDisplayMedia({ video: true });
-            this._videoRec = new MediaRecorder(this._videoRef!.srcObject);
-            const vidChunks: any = [];
+            this._videoRef.srcObject = await navigator.mediaDevices.getDisplayMedia({ video: true });
+            this._videoRec = new MediaRecorder(this._videoRef.srcObject);
+            const vidChunks: Blob[] = [];
             this._videoRec.onstart = () => {
                 if (this.dataDoc[this._props.fieldKey + '_trackScreen']) TrackMovements.Instance.start();
                 this.dataDoc[this._props.fieldKey + '_recordingStart'] = new DateField(new Date());
             };
-            this._videoRec.ondataavailable = (e: any) => vidChunks.push(e.data);
+            this._videoRec.ondataavailable = e => vidChunks.push(e.data);
             this._videoRec.onstop = async () => {
                 const presentation = TrackMovements.Instance.yieldPresentation();
                 if (presentation?.movements) {
                     const presCopy = { ...presentation };
-                    presCopy.movements = presentation.movements.map(movement => ({ ...movement, doc: movement.doc[Id] })) as any;
+                    presCopy.movements = presentation.movements.map(movement => ({ ...movement, doc: (movement.doc as Doc)[Id] }) as Movement);
                     this.dataDoc[this.fieldKey + '_presentation'] = JSON.stringify(presCopy);
                 }
                 TrackMovements.Instance.finish();
diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx
index bc19d7ad1..8da422039 100644
--- a/src/client/views/nodes/ScriptingBox.tsx
+++ b/src/client/views/nodes/ScriptingBox.tsx
@@ -1,8 +1,8 @@
 /* eslint-disable react/button-has-type */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
 import { action, computed, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
+import ResizeObserver from 'resize-observer-polyfill';
 import { returnAlways, returnEmptyString } from '../../../ClientUtils';
 import { Doc } from '../../../fields/Doc';
 import { List } from '../../../fields/List';
@@ -10,21 +10,26 @@ 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 { DocumentType } from '../../documents/DocumentTypes';
+import { Docs } from '../../documents/Documents';
 import { DragManager } from '../../util/DragManager';
 import { ScriptManager } from '../../util/ScriptManager';
-import { CompileScript, ScriptParam } from '../../util/Scripting';
+import { CompileError, CompileScript, ScriptParam } from '../../util/Scripting';
 import { ScriptingGlobals } from '../../util/ScriptingGlobals';
 import { ContextMenu } from '../ContextMenu';
 import { ViewBoxAnnotatableComponent } from '../DocComponent';
 import { EditableView } from '../EditableView';
 import { OverlayView } from '../OverlayView';
-import { FieldView, FieldViewProps } from './FieldView';
 import { DocumentIconContainer } from './DocumentIcon';
+import { FieldView, FieldViewProps } from './FieldView';
 import './ScriptingBox.scss';
-import { Docs } from '../../documents/Documents';
-import { DocumentType } from '../../documents/DocumentTypes';
+import * as ts from 'typescript';
+import { FieldType } from '../../../fields/ObjectField';
+
+// eslint-disable-next-line @typescript-eslint/no-var-requires
+const getCaretCoordinates = require('textarea-caret');
 
-const _global = (window /* browser */ || global) /* node */ as any;
+// eslint-disable-next-line @typescript-eslint/no-var-requires
 const ReactTextareaAutocomplete = require('@webscopeio/react-textarea-autocomplete').default;
 
 @observer
@@ -41,9 +46,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     @observable private _function: boolean = false;
     @observable private _spaced: boolean = false;
 
-    @observable private _scriptKeys: any = ScriptingGlobals.getGlobals();
-    @observable private _scriptingDescriptions: any = ScriptingGlobals.getDescriptions();
-    @observable private _scriptingParams: any = ScriptingGlobals.getParameters();
+    @observable private _scriptKeys = ScriptingGlobals.getGlobals();
+    @observable private _scriptingDescriptions = ScriptingGlobals.getDescriptions();
+    @observable private _scriptingParams = ScriptingGlobals.getParameters();
 
     @observable private _currWord: string = '';
     @observable private _suggestions: string[] = [];
@@ -52,20 +57,20 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     @observable private _suggestionBoxY: number = 0;
     @observable private _lastChar: string = '';
 
-    @observable private _suggestionRef: any = React.createRef();
-    @observable private _scriptTextRef: any = React.createRef();
+    @observable private _suggestionRef = React.createRef<HTMLDivElement>();
+    @observable private _scriptTextRef = React.createRef<HTMLDivElement>();
 
-    @observable private _selection: any = 0;
+    @observable private _selection = 0;
 
     @observable private _paramSuggestion: boolean = false;
-    @observable private _scriptSuggestedParams: any = '';
-    @observable private _scriptParamsText: any = '';
+    @observable private _scriptSuggestedParams: JSX.Element | string = '';
+    @observable private _scriptParamsText = '';
 
     constructor(props: FieldViewProps) {
         super(props);
         makeObservable(this);
         if (!this.compileParams.length) {
-            const params = ScriptCast(this.dataDoc[this._props.fieldKey])?.script.options.params as { [key: string]: any };
+            const params = ScriptCast(this.dataDoc[this._props.fieldKey])?.script.options.params as { [key: string]: string };
             if (params) {
                 this.compileParams = Array.from(Object.keys(params))
                     .filter(p => !p.startsWith('_'))
@@ -106,26 +111,16 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         this.dataDoc[this.fieldKey + '-params'] = new List<string>(value);
     }
 
-    getValue(result: any, descrip: boolean) {
-        if (typeof result === 'object') {
-            const text = descrip ? result[1] : result[2];
-            return text !== undefined ? text : '';
-        }
-        return '';
-    }
-
     onClickScriptDisable = returnAlways;
 
     @action
     componentDidMount() {
         this._props.setContentViewBox?.(this);
         this.rawText = this.rawScript;
-        const resizeObserver = new _global.ResizeObserver(
+        const resizeObserver = new ResizeObserver(
             action(() => {
                 const area = document.querySelector('textarea');
                 if (area) {
-                    // eslint-disable-next-line global-require
-                    const getCaretCoordinates = require('textarea-caret');
                     const caret = getCaretCoordinates(area, this._selection);
                     this.resetSuggestionPos(caret);
                 }
@@ -135,12 +130,12 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     }
 
     @action
-    resetSuggestionPos(caret: any) {
+    resetSuggestionPos(caret: { top: number; left: number; height: number }) {
         if (!this._suggestionRef.current || !this._scriptTextRef.current) return;
         const suggestionWidth = this._suggestionRef.current.offsetWidth;
         const scriptWidth = this._scriptTextRef.current.offsetWidth;
         const { top } = caret;
-        const { x } = this.dataDoc;
+        const x = NumCast(this.layoutDoc.x);
         let { left } = caret;
         if (left + suggestionWidth > x + scriptWidth) {
             const diff = left + suggestionWidth - (x + scriptWidth);
@@ -171,8 +166,8 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
 
     // displays error message
     @action
-    onError = (error: any) => {
-        this._errorMessage = error?.message ? error.message : error?.map((entry: any) => entry.messageText).join('  ') || '';
+    onError = (errors: ts.Diagnostic[] | string) => {
+        this._errorMessage = typeof errors === 'string' ? errors : errors.map(entry => entry.toString()).join('  ') || '';
     };
 
     // checks if the script compiles using CompileScript method and inputting params
@@ -184,7 +179,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         });
 
         const result = !this.rawText.trim()
-            ? ({ compiled: false, errors: undefined } as any)
+            ? ({ compiled: false, errors: [] } as CompileError)
             : CompileScript(this.rawText, {
                   editable: true,
                   transformer: DocumentIconContainer.getTransformer(),
@@ -192,7 +187,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                   typecheck: false,
               });
         this.dataDoc[this.fieldKey] = result.compiled ? new ScriptField(result, undefined, this.rawText) : undefined;
-        this.onError(result.compiled ? undefined : result.errors);
+        this.onError(result.compiled ? [] : result.errors);
         return result.compiled;
     };
 
@@ -200,7 +195,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     @action
     onRun = () => {
         if (this.onCompile()) {
-            const bindings: { [name: string]: any } = {};
+            const bindings: { [name: string]: unknown } = {};
             this.paramsNames.forEach(key => {
                 bindings[key] = this.dataDoc[key];
             });
@@ -294,8 +289,8 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
 
     // sets field of the param name to the selected value in drop down box
     @action
-    viewChanged = (e: React.ChangeEvent, name: string) => {
-        const val = (e.target as any).selectedOptions[0].value;
+    viewChanged = (e: React.ChangeEvent<HTMLSelectElement>, name: string) => {
+        const val = e.target.selectedOptions[0].value;
         this.dataDoc[name] = val[0] === 'S' ? val.substring(1) : val[0] === 'N' ? parseInt(val.substring(1)) : val.substring(1) === 'true';
     };
 
@@ -309,7 +304,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     // adds option to create a copy to the context menu
     specificContextMenu = (): void => {
         const existingOptions = ContextMenu.Instance.findByDescription('Options...');
-        const options = existingOptions && 'subitems' in existingOptions ? existingOptions.subitems : [];
+        const options = existingOptions?.subitems ?? [];
         options.push({ description: 'Create a Copy', event: this.onCopy, icon: 'copy' });
         !existingOptions && ContextMenu.Instance.addItem({ description: 'Options...', subitems: options, icon: 'hand-point-right' });
     };
@@ -381,7 +376,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                         const results = script.compiled && script.run();
                         if (results && results.success) {
                             this._errorMessage = '';
-                            this.dataDoc[parameter] = results.result;
+                            this.dataDoc[parameter] = results.result as FieldType;
                             return true;
                         }
                         this._errorMessage = 'invalid document';
@@ -524,18 +519,17 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
 
     @action
     suggestionPos = () => {
-        // eslint-disable-next-line global-require
-        const getCaretCoordinates = require('textarea-caret');
+        // eslint-disable-next-line @typescript-eslint/no-this-alias
         const This = this;
         document.querySelector('textarea')?.addEventListener('input', function () {
-            const caret = getCaretCoordinates(this, this.selectionEnd);
-            This._selection = this;
+            const caret = getCaretCoordinates(this, this.selectionEnd) as { top: number; left: number; height: number };
+            // This._selection = this;
             This.resetSuggestionPos(caret);
         });
     };
 
     @action
-    keyHandler(e: any, pos: number) {
+    keyHandler(e: React.KeyboardEvent, pos: number) {
         e.stopPropagation();
         if (this._lastChar === 'Enter') {
             this.rawText += ' ';
@@ -602,7 +596,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     }
 
     @action
-    handlePosChange(number: any) {
+    handlePosChange(number: number) {
         this._caretPos = number;
         if (this._caretPos === 0) {
             this.rawText = ' ' + this.rawText;
@@ -625,7 +619,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                     placeholder="write your script here"
                     onFocus={this.onFocus}
                     onBlur={() => this._overlayDisposer?.()}
-                    onChange={action((e: any) => {
+                    onChange={action((e: React.ChangeEvent<HTMLSelectElement>) => {
                         this.rawText = e.target.value;
                     })}
                     value={this.rawText}
@@ -633,24 +627,24 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                     loadingComponent={() => <span>Loading</span>}
                     trigger={{
                         ' ': {
-                            dataProvider: (token: any) => this.handleToken(token),
-                            component: (blob: any) => this.renderFuncListElement(blob.entity),
-                            output: (item: any, trigger: any) => {
+                            dataProvider: this.handleToken,
+                            component: (blob: { entity: string }) => this.renderFuncListElement(blob.entity),
+                            output: (item: string, trigger: string) => {
                                 this._spaced = true;
                                 return trigger + item.trim();
                             },
                         },
                         '.': {
-                            dataProvider: (token: any) => this.handleToken(token),
-                            component: (blob: any) => this.renderFuncListElement(blob.entity),
-                            output: (item: any, trigger: any) => {
+                            dataProvider: this.handleToken,
+                            component: (blob: { entity: string }) => this.renderFuncListElement(blob.entity),
+                            output: (item: string, trigger: string) => {
                                 this._spaced = true;
                                 return trigger + item.trim();
                             },
                         },
                     }}
                     onKeyDown={(e: React.KeyboardEvent) => this.keyHandler(e, this._caretPos)}
-                    onCaretPositionChange={(number: any) => this.handlePosChange(number)}
+                    onCaretPositionChange={this.handlePosChange}
                 />
             </div>
         );
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 1f285b300..4933869a7 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -125,8 +125,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     }
 
     override PlayerTime = () => this.player?.currentTime;
-    override Pause = (update: boolean = true) => {
-        this.pause(update);
+    override Pause = () => {
+        this.pause(true);
         !this._keepCurrentlyPlaying && this.removeCurrentlyPlaying();
     };
 
@@ -157,7 +157,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     };
 
     // plays video
-    @action public Play = (update: boolean = true) => {
+    @action public Play = () => {
         if (this._playRegionTimer) return;
 
         this._playing = true;
@@ -172,8 +172,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             }
             try {
                 this._audioPlayer && this.player && (this._audioPlayer.currentTime = this.player?.currentTime);
-                update && this.player && this.playFrom(start, undefined, true);
-                update && this._audioPlayer?.play();
+                this.player && this.playFrom(start, undefined, true);
+                this._audioPlayer?.play();
             } catch (e) {
                 console.log('Video Play Exception:', e);
             }
@@ -384,7 +384,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     getVideoThumbnails = () => {
         if (this.dataDoc[this.fieldKey + '_thumbnails'] !== undefined) return;
         this.dataDoc[this.fieldKey + '_thumbnails'] = new List<string>();
-        const thumbnailPromises: Promise<any>[] = [];
+        const thumbnailPromises: Promise<string>[] = [];
         const video = document.createElement('video');
 
         video.onloadedmetadata = () => {
@@ -467,7 +467,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                         runInAction(() => {
                             this._screenCapture = !this._screenCapture;
                         });
-                        this._videoRef!.srcObject = !this._screenCapture ? null : await (navigator.mediaDevices).getDisplayMedia({ video: true });
+                        this._videoRef!.srcObject = !this._screenCapture ? null : await navigator.mediaDevices.getDisplayMedia({ video: true });
                     },
                     icon: 'expand-arrows-alt',
                 });
@@ -557,9 +557,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                         style={this._fullScreen ? this.fullScreenSize() : this.isCropped ? { width: 'max-content', height: 'max-content', transform: `scale(${1 / NumCast(this.layoutDoc._freeform_scale)})`, transformOrigin: 'top left' } : {}}
                         onCanPlay={this.videoLoad}
                         controls={false}
-                        onPlay={() => this.Play()}
+                        onPlay={this.Play}
                         onSeeked={this.updateTimecode}
-                        onPause={() => this.Pause()}
+                        onPause={this.Pause}
                         onClick={this._fullScreen ? () => (this.playing() ? this.Pause() : this.Play()) : e => e.preventDefault()}>
                         <source src={field.url.href} type="video/mp4" />
                         Not supported.
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index be7e0f483..1fd73c226 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1,4 +1,5 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Property } from 'csstype';
 import { htmlToText } from 'html-to-text';
 import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
@@ -21,7 +22,7 @@ import { DocumentType } from '../../documents/DocumentTypes';
 import { DocUtils } from '../../documents/DocUtils';
 import { ScriptingGlobals } from '../../util/ScriptingGlobals';
 import { SnappingManager } from '../../util/SnappingManager';
-import { undoBatch, UndoManager } from '../../util/UndoManager';
+import { undoable, UndoManager } from '../../util/UndoManager';
 import { MarqueeOptionsMenu } from '../collections/collectionFreeForm';
 import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
 import { ContextMenu } from '../ContextMenu';
@@ -83,7 +84,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         this._marqueeing = val;
     }
     @observable private _iframe: HTMLIFrameElement | null = null;
-    @observable private _savedAnnotations = new ObservableMap<number, (HTMLDivElement& { marqueeing?: boolean})[]>();
+    @observable private _savedAnnotations = new ObservableMap<number, (HTMLDivElement & { marqueeing?: boolean })[]>();
     @observable private _scrollHeight = NumCast(this.layoutDoc.scrollHeight);
     @computed get _url() {
         return this.webField?.toString() || '';
@@ -121,11 +122,12 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             });
         }
         try {
+            const contentWindow = this._iframe?.contentWindow;
             if (clear) {
-                this._iframe?.contentWindow?.getSelection()?.empty();
+                contentWindow?.getSelection()?.empty();
             }
-            if (searchString) {
-                (this._iframe?.contentWindow as any)?.find(searchString, false, bwd, true);
+            if (searchString && contentWindow && 'find' in contentWindow) {
+                (contentWindow.find as (str: string, caseSens?: boolean, backward?: boolean, wrapAround?: boolean) => void)(searchString, false, bwd, true);
             }
         } catch (e) {
             console.log('WebBox search error', e);
@@ -142,7 +144,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         }
     };
 
-    updateThumb = async () => {
+    updateIcon = async () => {
         if (!this._iframe) return;
         const scrollTop = NumCast(this.layoutDoc._layout_scrollTop);
         const nativeWidth = NumCast(this.layoutDoc.nativeWidth);
@@ -154,7 +156,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         this.layoutDoc.thumb = undefined;
         this.Document.thumbLockout = true; // lock to prevent multiple thumb updates.
         CreateImage(this._webUrl.endsWith('/') ? this._webUrl.substring(0, this._webUrl.length - 1) : this._webUrl, this._iframe.contentDocument?.styleSheets ?? [], htmlString, nativeWidth, nativeHeight, scrollTop)
-            .then((dataUrl: any) => {
+            .then((dataUrl: string) => {
                 if (dataUrl.includes('<!DOCTYPE')) {
                     console.log('BAD DATA IN THUMB CREATION');
                     return;
@@ -172,7 +174,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                     )
                 );
             })
-            .catch((error: any) => {
+            .catch((error: object) => {
                 console.error('oops, something went wrong!', error);
             });
     };
@@ -359,8 +361,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         return anchor;
     };
 
-    _textAnnotationCreator: (() => ObservableMap<number, (HTMLDivElement & { marqueeing?: boolean})[]>) | undefined;
-    savedAnnotationsCreator: () => ObservableMap<number, (HTMLDivElement & { marqueeing?: boolean})[]> = () => this._textAnnotationCreator?.() || this._savedAnnotations;
+    _textAnnotationCreator: (() => ObservableMap<number, (HTMLDivElement & { marqueeing?: boolean })[]>) | undefined;
+    savedAnnotationsCreator: () => ObservableMap<number, (HTMLDivElement & { marqueeing?: boolean })[]> = () => this._textAnnotationCreator?.() || this._savedAnnotations;
 
     @action
     iframeMove = (e: PointerEvent) => {
@@ -424,11 +426,11 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             sel.empty(); // Chrome
         else if (sel?.removeAllRanges) sel.removeAllRanges(); // Firefox
         // bcz: NEED TO unrotate e.clientX and e.clientY
-        const word = getWordAtPoint(e.target, e.clientX, e.clientY);
+        const target = e.target as HTMLElement;
+        const word = target && getWordAtPoint(target, e.clientX, e.clientY);
         this._setPreviewCursor?.(e.clientX, e.clientY, false, true, this.Document);
         MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
 
-        const target = e.target as HTMLElement;
         if (!word && !target?.className?.includes('rangeslider') && !target?.onclick && !target?.parentElement?.onclick) {
             if (e.button !== 2) this.marqueeing = [e.clientX, e.clientY];
             e.preventDefault();
@@ -468,8 +470,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             .inverse()
             .transformPoint(e.clientX, e.clientY - NumCast(this.layoutDoc.layout_scrollTop));
         MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
-        const word = getWordAtPoint(e.target, e.clientX, e.clientY);
         const target = e.target as HTMLElement;
+        const word = target && getWordAtPoint(target, e.clientX, e.clientY);
         if (!word && !target?.className?.includes('rangeslider') && !target?.onclick && !target?.parentElement?.onclick) {
             this.marqueeing = theclick;
             this._marqueeref.current?.onInitiateSelection(this.marqueeing);
@@ -488,7 +490,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         }
         return undefined;
     }
-    addWebStyleSheetRule(sheet: CSSStyleSheet | null | undefined, selector: string, css: {[key:string]: string}, selectorPrefix = '.') {
+    addWebStyleSheetRule(sheet: CSSStyleSheet | null | undefined, selector: string, css: { [key: string]: string }, selectorPrefix = '.') {
         const propText =
             typeof css === 'string'
                 ? css
@@ -498,7 +500,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         return sheet?.insertRule(selectorPrefix + selector + '{' + propText + '}', sheet.cssRules.length);
     }
 
-    _iframetimeout: NodeJS.Timeout|undefined = undefined;
+    _iframetimeout: NodeJS.Timeout | undefined = undefined;
     @observable _warning = 0;
     @action
     iframeLoaded = () => {
@@ -520,7 +522,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         if (requrlraw !== this._url.toString()) {
             if (requrlraw.match(/q=.*&/)?.length && this._url.toString().match(/q=.*&/)?.length) {
                 const matches = requrlraw.match(/[^a-zA-z]q=[^&]*/g);
-                const newsearch = matches?.lastElement() || "";
+                const newsearch = matches?.lastElement() || '';
                 if (matches) {
                     requrlraw = requrlraw.substring(0, requrlraw.indexOf(newsearch));
                     for (let i = 1; i < Array.from(matches)?.length; i++) {
@@ -567,12 +569,12 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
             );
             iframeContent.addEventListener(
                 'click',
-                undoBatch(
+                undoable(
                     action((e: MouseEvent) => {
                         let eleHref = '';
                         for (let ele = e.target as HTMLElement | Element | null; ele; ele = ele.parentElement) {
                             if (ele instanceof HTMLAnchorElement) {
-                                eleHref = (typeof ele.href === 'string' ? ele.href : eleHref) || (ele.parentElement && ("href" in ele.parentElement) ? ele.parentElement.href as string: eleHref);
+                                eleHref = (typeof ele.href === 'string' ? ele.href : eleHref) || (ele.parentElement && 'href' in ele.parentElement ? (ele.parentElement.href as string) : eleHref);
                             }
                         }
                         const origin = this.webField?.origin;
@@ -588,7 +590,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                                 this._outerRef.current.scrollLeft = 0;
                             }
                         }
-                    })
+                    }),
+                    'follow web link'
                 )
             );
             iframe.contentDocument.addEventListener('wheel', this.iframeWheel, { passive: false });
@@ -792,7 +795,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                 },
                 icon: 'snowflake',
             });
-            funcs.push({ description: 'Create Thumbnail', event: () => this.updateThumb(), icon: 'portrait' });
+            !Doc.noviceMode && funcs.push({ description: 'Update Icon', event: () => this.updateIcon(), icon: 'portrait' });
             cm.addItem({ description: 'Options...', subitems: funcs, icon: 'asterisk' });
         }
     };
@@ -1085,7 +1088,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     @computed get webpage() {
         TraceMobx();
         const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1;
-        const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this._props.pointerEvents?.() as "none" | "all" | "visiblePainted" | undefined)
+        const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this._props.pointerEvents?.() as Property.PointerEvents | undefined);
         const scale = previewScale * (this._props.NativeDimScaling?.() || 1);
         return (
             <div
@@ -1170,7 +1173,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     render() {
         TraceMobx();
         const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1;
-        const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this._props.pointerEvents?.() as 'none' | 'all' | 'visiblePainted' | undefined);
+        const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this._props.pointerEvents?.() as Property.PointerEvents);
         const scale = previewScale * (this._props.NativeDimScaling?.() || 1);
         return (
             <div
diff --git a/src/client/views/nodes/WebBoxRenderer.js b/src/client/views/nodes/WebBoxRenderer.js
index 6fb8f4957..b727107a9 100644
--- a/src/client/views/nodes/WebBoxRenderer.js
+++ b/src/client/views/nodes/WebBoxRenderer.js
@@ -4,8 +4,6 @@
  * @param {StyleSheetList} styleSheets
  */
 const ForeignHtmlRenderer = function (styleSheets) {
-    const self = this;
-
     /**
      *
      * @param {String} binStr
@@ -252,15 +250,14 @@ const ForeignHtmlRenderer = function (styleSheets) {
      */
     this.renderToImage = (webUrl, html, width, height, scroll, xoff) =>
         new Promise(resolve => {
-            const img = new Image();
-            img.onload = function () {
-                console.log(`IMAGE SVG created: ${webUrl}`);
-                resolve(img);
-            };
             console.log(`BUILDING SVG for: ${webUrl}`);
             buildSvgDataUri(webUrl, html, width, height, scroll, xoff).then(uri => {
+                const img = new Image();
                 img.src = uri;
-                return img;
+                img.onload = () => {
+                    console.log(`IMAGE SVG created: ${webUrl}`);
+                    resolve(img);
+                };
             });
         });
 
@@ -272,7 +269,7 @@ const ForeignHtmlRenderer = function (styleSheets) {
      * @return {Promise<Image>}
      */
     this.renderToCanvas = (webUrl, html, width, height, scroll, xoff, oversample) =>
-        self.renderToImage(webUrl, html, width, height, scroll, xoff).then(img => {
+        this.renderToImage(webUrl, html, width, height, scroll, xoff).then(img => {
             const canvas = document.createElement('canvas');
             canvas.width = img.width * oversample;
             canvas.height = img.height * oversample;
@@ -290,8 +287,7 @@ const ForeignHtmlRenderer = function (styleSheets) {
      * @return {Promise<String>}
      */
     this.renderToBase64Png = (webUrl, html, width, height, scroll, xoff, oversample) =>
-        self
-            .renderToCanvas(webUrl, html, width, height, scroll, xoff, oversample) //
+        this.renderToCanvas(webUrl, html, width, height, scroll, xoff, oversample) //
             .then(canvas => canvas.toDataURL('image/png'));
 };
 
diff --git a/src/client/views/nodes/audio/AudioWaveform.tsx b/src/client/views/nodes/audio/AudioWaveform.tsx
index 2d1d3d7db..297deb575 100644
--- a/src/client/views/nodes/audio/AudioWaveform.tsx
+++ b/src/client/views/nodes/audio/AudioWaveform.tsx
@@ -39,7 +39,7 @@ export class AudioWaveform extends ObservableReactComponent<AudioWaveformProps>
     public static NUMBER_OF_BUCKETS = 100; // number of buckets data is divided into to draw waveform lines
     _disposer: IReactionDisposer | undefined;
 
-    constructor(props: any) {
+    constructor(props: AudioWaveformProps) {
         super(props);
         makeObservable(this);
     }
diff --git a/src/client/views/nodes/formattedText/DashDocCommentView.tsx b/src/client/views/nodes/formattedText/DashDocCommentView.tsx
index 3ec49fa27..0304ddc86 100644
--- a/src/client/views/nodes/formattedText/DashDocCommentView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocCommentView.tsx
@@ -5,18 +5,20 @@ import { IReactionDisposer, computed, reaction } from 'mobx';
 import { Doc } from '../../../../fields/Doc';
 import { DocServer } from '../../../DocServer';
 import { NumCast } from '../../../../fields/Types';
+import { Node } from 'prosemirror-model';
+import { EditorView } from 'prosemirror-view';
 
 interface IDashDocCommentViewInternal {
     docId: string;
-    view: any;
-    getPos: any;
+    view: EditorView;
+    getPos: () => number;
     setHeight: (height: number) => void;
 }
 
 export class DashDocCommentViewInternal extends React.Component<IDashDocCommentViewInternal> {
     _reactionDisposer: IReactionDisposer | undefined;
 
-    constructor(props: any) {
+    constructor(props: IDashDocCommentViewInternal) {
         super(props);
         this.onPointerLeaveCollapsed = this.onPointerLeaveCollapsed.bind(this);
         this.onPointerEnterCollapsed = this.onPointerEnterCollapsed.bind(this);
@@ -43,19 +45,19 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV
         return DocServer.GetRefField(this.props.docId);
     }
 
-    onPointerLeaveCollapsed = (e: any) => {
+    onPointerLeaveCollapsed = (e: React.PointerEvent) => {
         this._dashDoc.then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowUnhighlight());
         e.preventDefault();
         e.stopPropagation();
     };
 
-    onPointerEnterCollapsed = (e: any) => {
+    onPointerEnterCollapsed = (e: React.PointerEvent) => {
         this._dashDoc.then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc, false));
         e.preventDefault();
         e.stopPropagation();
     };
 
-    onPointerUpCollapsed = (e: any) => {
+    onPointerUpCollapsed = (e: React.PointerEvent) => {
         const target = this.targetNode();
 
         if (target) {
@@ -65,7 +67,7 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV
             setTimeout(() => {
                 expand && this._dashDoc.then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc));
                 try {
-                    this.props.view.dispatch(this.props.view.state.tr.setSelection(TextSelection.create(this.props.view.state.tr.doc, this.props.getPos() + (expand ? 2 : 1))));
+                    this.props.view.dispatch(this.props.view.state.tr.setSelection(TextSelection.create(this.props.view.state.tr.doc, (this.props.getPos() ?? 0) + (expand ? 2 : 1))));
                 } catch (err) {
                     /* empty */
                 }
@@ -74,7 +76,7 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV
         e.stopPropagation();
     };
 
-    onPointerDownCollapsed = (e: any) => {
+    onPointerDownCollapsed = (e: React.PointerEvent) => {
         e.stopPropagation();
     };
 
@@ -84,7 +86,7 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV
         for (let i = this.props.getPos() + 1; i < state.doc.content.size; i++) {
             const m = state.doc.nodeAt(i);
             if (m && m.type === state.schema.nodes.dashDoc && m.attrs.docId === this.props.docId) {
-                return { node: m, pos: i, hidden: m.attrs.hidden } as { node: any; pos: number; hidden: boolean };
+                return { node: m, pos: i, hidden: m.attrs.hidden } as { node: Node; pos: number; hidden: boolean };
             }
         }
 
@@ -119,10 +121,10 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV
 // the comment can be toggled on/off with the '<-' text anchor.
 export class DashDocCommentView {
     dom: HTMLDivElement; // container for label and value
-    root: any;
-    node: any;
+    root: ReactDOM.Root;
+    node: Node;
 
-    constructor(node: any, view: any, getPos: any) {
+    constructor(node: Node, view: EditorView, getPos: () => number | undefined) {
         this.node = node;
         this.dom = document.createElement('div');
         this.dom.style.width = node.attrs.width;
@@ -130,22 +132,22 @@ export class DashDocCommentView {
         this.dom.style.fontWeight = 'bold';
         this.dom.style.position = 'relative';
         this.dom.style.display = 'inline-block';
-        this.dom.onkeypress = function (e: any) {
+        this.dom.onkeypress = function (e) {
             e.stopPropagation();
         };
-        this.dom.onkeydown = function (e: any) {
+        this.dom.onkeydown = function (e) {
             e.stopPropagation();
         };
-        this.dom.onkeyup = function (e: any) {
+        this.dom.onkeyup = function (e) {
             e.stopPropagation();
         };
-        this.dom.onmousedown = function (e: any) {
+        this.dom.onmousedown = function (e) {
             e.stopPropagation();
         };
 
+        const getPosition = () => getPos() ?? 0;
         this.root = ReactDOM.createRoot(this.dom);
-        this.root.render(<DashDocCommentViewInternal view={view} getPos={getPos} setHeight={this.setHeight} docId={node.attrs.docId} />);
-        (this as any).dom = this.dom;
+        this.root.render(<DashDocCommentViewInternal view={view} getPos={getPosition} setHeight={this.setHeight} docId={node.attrs.docId} />);
     }
 
     setHeight = (hgt: number) => {
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 93371685d..e7f2cdba8 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
 import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import { NodeSelection } from 'prosemirror-state';
@@ -16,6 +15,8 @@ import { ObservableReactComponent } from '../../ObservableReactComponent';
 import { DocumentView } from '../DocumentView';
 import { FocusViewOptions } from '../FocusViewOptions';
 import { FormattedTextBox } from './FormattedTextBox';
+import { EditorView } from 'prosemirror-view';
+import { Node } from 'prosemirror-model';
 
 const horizPadding = 3; // horizontal padding to container to allow cursor to show up on either side.
 interface IDashDocViewInternal {
@@ -26,9 +27,9 @@ interface IDashDocViewInternal {
     height: string;
     hidden: boolean;
     fieldKey: string;
-    view: any;
-    node: any;
-    getPos: any;
+    view: EditorView;
+    node: Node;
+    getPos: () => number;
 }
 
 @observer
@@ -109,7 +110,7 @@ export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewIn
     };
     outerFocus = (target: Doc, options: FocusViewOptions) => this._textBox.focus(target, options); // ideally, this would scroll to show the focus target
 
-    onKeyDown = (e: any) => {
+    onKeyDown = (e: React.KeyboardEvent) => {
         e.stopPropagation();
         if (e.key === 'Tab' || e.key === 'Enter') {
             e.preventDefault();
@@ -176,29 +177,31 @@ export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewIn
 
 export class DashDocView {
     dom: HTMLSpanElement; // container for label and value
-    root: any;
+    root: ReactDOM.Root;
 
-    constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) {
+    constructor(node: Node, view: EditorView, getPos: () => number | undefined, tbox: FormattedTextBox) {
         this.dom = document.createElement('span');
         this.dom.style.position = 'relative';
         this.dom.style.textIndent = '0';
         this.dom.style.width = (+node.attrs.width.toString().replace('px', '') + horizPadding).toString();
         this.dom.style.height = node.attrs.height;
         this.dom.style.display = node.attrs.hidden ? 'none' : 'inline-block';
-        (this.dom.style as any).float = node.attrs.float;
-        this.dom.onkeypress = function (e: any) {
+        this.dom.style.float = node.attrs.float;
+        this.dom.onkeypress = function (e: KeyboardEvent) {
             e.stopPropagation();
         };
-        this.dom.onkeydown = function (e: any) {
+        this.dom.onkeydown = function (e: KeyboardEvent) {
             e.stopPropagation();
         };
-        this.dom.onkeyup = function (e: any) {
+        this.dom.onkeyup = function (e: KeyboardEvent) {
             e.stopPropagation();
         };
-        this.dom.onmousedown = function (e: any) {
+        this.dom.onmousedown = function (e: MouseEvent) {
             e.stopPropagation();
         };
 
+        const getPosition = () => getPos() ?? 0;
+
         this.root = ReactDOM.createRoot(this.dom);
         this.root.render(
             <DashDocViewInternal
@@ -211,7 +214,7 @@ export class DashDocView {
                 tbox={tbox}
                 view={view}
                 node={node}
-                getPos={getPos}
+                getPos={getPosition}
             />
         );
     }
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index 9903d0e8a..f0313fba4 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -1,6 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
-/* eslint-disable jsx-a11y/control-has-associated-label */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@mui/material';
 import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
@@ -26,6 +23,8 @@ import { ObservableReactComponent } from '../../ObservableReactComponent';
 import { OpenWhere } from '../OpenWhere';
 import './DashFieldView.scss';
 import { FormattedTextBox } from './FormattedTextBox';
+import { Node } from 'prosemirror-model';
+import { EditorView } from 'prosemirror-view';
 
 @observer
 export class DashFieldViewMenu extends AntimodeMenu<AntimodeMenuProps> {
@@ -34,7 +33,7 @@ export class DashFieldViewMenu extends AntimodeMenu<AntimodeMenuProps> {
     static createFieldView: (e: React.MouseEvent) => void = emptyFunction;
     static toggleFieldHide: () => void = emptyFunction;
     static toggleValueHide: () => void = emptyFunction;
-    constructor(props: any) {
+    constructor(props: AntimodeMenuProps) {
         super(props);
         DashFieldViewMenu.Instance = this;
     }
@@ -100,8 +99,8 @@ interface IDashFieldViewInternal {
     height: number;
     editable: boolean;
     nodeSelected: () => boolean;
-    node: any;
-    getPos: any;
+    node: Node;
+    getPos: () => number;
     unclickable: () => boolean;
 }
 
@@ -274,7 +273,9 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi
                     <select className="dashFieldView-select" tabIndex={-1} defaultValue={this._dashDoc && Field.toKeyValueString(this._dashDoc, this._fieldKey)} onChange={this.selectVal}>
                         <option value="-unset-">-unset-</option>
                         {this.values.map(val => (
-                            <option value={val.value}>{val.label}</option>
+                            <option key={val.value} value={val.value}>
+                                {val.label}
+                            </option>
                         ))}
                     </select>
                 )}
@@ -284,16 +285,17 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi
 }
 export class DashFieldView {
     dom: HTMLDivElement; // container for label and value
-    root: any;
-    node: any;
+    root: ReactDOM.Root;
+    node: Node;
     tbox: FormattedTextBox;
-    getpos: any;
+    getpos: () => number | undefined;
     @observable _nodeSelected = false;
     NodeSelected = () => this._nodeSelected;
 
-    unclickable = () => !this.tbox._props.rootSelected?.() && this.node.marks.some((m: any) => m.type === this.tbox.EditorView?.state.schema.marks.linkAnchor && m.attrs.noPreview);
-    constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) {
+    unclickable = () => !this.tbox._props.rootSelected?.() && this.node.marks.some(m => m.type === this.tbox.EditorView?.state.schema.marks.linkAnchor && m.attrs.noPreview);
+    constructor(node: Node, view: EditorView, getPos: () => number | undefined, tbox: FormattedTextBox) {
         makeObservable(this);
+        const getPosition = () => getPos() ?? 0;
         this.node = node;
         this.tbox = tbox;
         this.getpos = getPos;
@@ -312,7 +314,7 @@ export class DashFieldView {
                 const editor = tbox.EditorView;
                 if (editor) {
                     const { state } = editor;
-                    for (let i = this.getpos() + 1; i < state.doc.content.size; i++) {
+                    for (let i = getPosition() + 1; i < state.doc.content.size; i++) {
                         if (state.doc.nodeAt(i)?.type.name === state.schema.nodes.dashField.name) {
                             editor.dispatch(state.tr.setSelection(new NodeSelection(state.doc.resolve(i))));
                             return;
@@ -321,10 +323,10 @@ export class DashFieldView {
                 }
             }
         };
-        this.dom.onkeyup = function (e: any) {
+        this.dom.onkeyup = function (e: KeyboardEvent) {
             e.stopPropagation();
         };
-        this.dom.onmousedown = function (e: any) {
+        this.dom.onmousedown = function (e: MouseEvent) {
             e.stopPropagation();
         };
 
@@ -333,7 +335,7 @@ export class DashFieldView {
             <DashFieldViewInternal
                 node={node}
                 unclickable={this.unclickable}
-                getPos={getPos}
+                getPos={getPosition}
                 fieldKey={node.attrs.fieldKey}
                 docId={node.attrs.docId}
                 width={node.attrs.width}
diff --git a/src/client/views/nodes/formattedText/EquationEditor.tsx b/src/client/views/nodes/formattedText/EquationEditor.tsx
index d9b1a2cf8..8bb4a0a26 100644
--- a/src/client/views/nodes/formattedText/EquationEditor.tsx
+++ b/src/client/views/nodes/formattedText/EquationEditor.tsx
@@ -3,15 +3,12 @@ import React, { Component, createRef } from 'react';
 
 // Import JQuery, required for the functioning of the equation editor
 import $ from 'jquery';
-
 import './EquationEditor.scss';
 
-// @ts-ignore
-window.jQuery = $;
-
-// @ts-ignore
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+(window as any).jQuery = $;
 require('mathquill/build/mathquill');
-
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
 (window as any).MathQuill = (window as any).MathQuill.getInterface(1);
 
 type EquationEditorProps = {
@@ -36,17 +33,18 @@ type EquationEditorProps = {
  * @extends {Component<EquationEditorProps>}
  */
 class EquationEditor extends Component<EquationEditorProps> {
-    element: any;
+    element: React.RefObject<HTMLSpanElement>;
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     mathField: any;
     ignoreEditEvents: number;
 
     // Element needs to be in the class format and thus requires a constructor. The steps that are run
     // in the constructor is to make sure that React can succesfully communicate with the equation
     // editor.
-    constructor(props: any) {
+    constructor(props: EquationEditorProps) {
         super(props);
 
-        this.element = createRef();
+        this.element = createRef<HTMLSpanElement>();
         this.mathField = null;
 
         // MathJax apparently fire 2 edit events on startup.
@@ -74,6 +72,7 @@ class EquationEditor extends Component<EquationEditorProps> {
             autoOperatorNames,
         };
 
+        // eslint-disable-next-line @typescript-eslint/no-explicit-any
         this.mathField = (window as any).MathQuill.MathField(this.element.current, config);
         this.mathField.latex(value || '');
     }
diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx
index 5167c8f2a..4d0e9efee 100644
--- a/src/client/views/nodes/formattedText/EquationView.tsx
+++ b/src/client/views/nodes/formattedText/EquationView.tsx
@@ -1,15 +1,16 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
 import { IReactionDisposer } from 'mobx';
 import { observer } from 'mobx-react';
+import { Node } from 'prosemirror-model';
 import { TextSelection } from 'prosemirror-state';
+import { EditorView } from 'prosemirror-view';
 import * as React from 'react';
 import * as ReactDOM from 'react-dom/client';
 import { Doc } from '../../../../fields/Doc';
+import { DocData } from '../../../../fields/DocSymbols';
 import { StrCast } from '../../../../fields/Types';
 import './DashFieldView.scss';
 import EquationEditor from './EquationEditor';
 import { FormattedTextBox } from './FormattedTextBox';
-import { DocData } from '../../../../fields/DocSymbols';
 
 interface IEquationViewInternal {
     fieldKey: string;
@@ -27,7 +28,7 @@ export class EquationViewInternal extends React.Component<IEquationViewInternal>
     _fieldKey: string;
     _ref: React.RefObject<EquationEditor> = React.createRef();
 
-    constructor(props: any) {
+    constructor(props: IEquationViewInternal) {
         super(props);
         this._fieldKey = props.fieldKey;
         this._textBoxDoc = props.tbox.Document;
@@ -63,7 +64,7 @@ export class EquationViewInternal extends React.Component<IEquationViewInternal>
                 <EquationEditor
                     ref={this._ref}
                     value={StrCast(this._textBoxDoc[DocData][this._fieldKey])}
-                    onChange={(str: any) => {
+                    onChange={str => {
                         this._textBoxDoc[DocData][this._fieldKey] = str;
                     }}
                     autoCommands="pi theta sqrt sum prod alpha beta gamma rho"
@@ -77,25 +78,27 @@ export class EquationViewInternal extends React.Component<IEquationViewInternal>
 
 export class EquationView {
     dom: HTMLDivElement; // container for label and value
-    root: any;
+    root: ReactDOM.Root;
     tbox: FormattedTextBox;
-    view: any;
-    constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) {
+    view: EditorView;
+    _editor: EquationEditor | undefined;
+    getPos: () => number;
+    constructor(node: Node, view: EditorView, getPos: () => number, tbox: FormattedTextBox) {
         this.tbox = tbox;
         this.view = view;
+        this.getPos = getPos;
         this.dom = document.createElement('div');
         this.dom.style.width = node.attrs.width;
         this.dom.style.height = node.attrs.height;
         this.dom.style.position = 'relative';
         this.dom.style.display = 'inline-block';
-        this.dom.onmousedown = function (e: any) {
+        this.dom.onmousedown = (e: MouseEvent) => {
             e.stopPropagation();
         };
 
         this.root = ReactDOM.createRoot(this.dom);
         this.root.render(<EquationViewInternal fieldKey={node.attrs.fieldKey} width={node.attrs.width} height={node.attrs.height} getPos={getPos} setEditor={this.setEditor} tbox={tbox} />);
     }
-    _editor: EquationEditor | undefined;
     setEditor = (editor?: EquationEditor) => {
         this._editor = editor;
     };
@@ -106,6 +109,7 @@ export class EquationView {
         this._editor?.mathField.focus();
     }
     selectNode() {
+        this.view.dispatch(this.view.state.tr.setSelection(new TextSelection(this.view.state.doc.resolve(this.getPos()))));
         this.tbox._applyingChange = this.tbox.fieldKey; // setting focus will make prosemirror lose focus, which will cause it to change its selection to a text selection, which causes this view to get rebuilt but it's no longer node selected, so the equationview won't have focus
         setTimeout(() => {
             this._editor?.mathField.focus();
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 39e237986..c8b25e184 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -96,7 +96,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
     private _sidebarTagRef = React.createRef<React.Component>();
     private _ref: React.RefObject<HTMLDivElement> = React.createRef();
     private _scrollRef: HTMLDivElement | null = null;
-    private _editorView: Opt<EditorView & { TextView?: FormattedTextBox|undefined}>;
+    private _editorView: Opt<EditorView & { TextView?: FormattedTextBox | undefined }>;
     public _applyingChange: string = '';
     private _inDrop = false;
     private _finishingLink = false;
@@ -113,7 +113,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
     private _forceUncollapse = true; // if the cursor doesn't move between clicks, then the selection will disappear for some reason.  This flags the 2nd click as happening on a selection which allows bullet points to toggle
     private _break = true;
     public ProseRef?: HTMLDivElement;
-    set _recordingDictation(value) { !this.dataDoc[`${this.fieldKey}_recordingSource`] && (this.dataDoc.mediaState = value ? mediaState.Recording : undefined); }
+    set _recordingDictation(value) {
+        !this.dataDoc[`${this.fieldKey}_recordingSource`] && (this.dataDoc.mediaState = value ? mediaState.Recording : undefined);
+    }
     @computed get _recordingDictation()        { return this.dataDoc?.mediaState === mediaState.Recording; } // prettier-ignore
     @computed get allSidebarDocs()             { return DocListCast(this.dataDoc[this.SidebarKey]); } // prettier-ignore
     @computed get noSidebar()                  { return this.DocumentView?.()._props.hideDecorationTitle || this._props.noSidebar || this.Document._layout_noSidebar; } // prettier-ignore
@@ -128,20 +130,26 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
     @computed get config() {
         this._keymap = buildKeymap(schema, this._props);
         this._rules = new RichTextRules(this.Document, this);
-        return { schema,
-                 plugins: [
-                    inputRules(this._rules.inpRules),
-                    this.richTextMenuPlugin(),
-                    history(),
-                    keymap(this._keymap),
-                    keymap(baseKeymap),
-                    new Plugin({ props: { attributes: { class: 'ProseMirror-example-setup-style' } } }),
-                    new Plugin({ view: () => new FormattedTextBoxComment() }),
-                ] };
+        return {
+            schema,
+            plugins: [
+                inputRules(this._rules.inpRules),
+                this.richTextMenuPlugin(),
+                history(),
+                keymap(this._keymap),
+                keymap(baseKeymap),
+                new Plugin({ props: { attributes: { class: 'ProseMirror-example-setup-style' } } }),
+                new Plugin({ view: () => new FormattedTextBoxComment() }),
+            ],
+        };
     }
 
-    public get EditorView() { return this._editorView; }
-    public get SidebarKey() { return this.fieldKey + '_sidebar'; }
+    public get EditorView() {
+        return this._editorView;
+    }
+    public get SidebarKey() {
+        return this.fieldKey + '_sidebar';
+    }
     public makeAIFlashcards: () => void = unimplementedFunction;
     public addToCollection: ((doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) | undefined;
 
@@ -777,7 +785,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
     specificContextMenu = (e: React.MouseEvent): void => {
         const cm = ContextMenu.Instance;
 
-        let target:Element|HTMLElement|null = e.target as HTMLElement; // hrefs are stored on the database of the <a> node that wraps the hyerlink <span>
+        let target: Element | HTMLElement | null = e.target as HTMLElement; // hrefs are stored on the database of the <a> node that wraps the hyerlink <span>
         while (target && (!(target instanceof HTMLElement) || !target.dataset?.targethrefs)) target = target.parentElement;
         const editor = this._editorView;
         if (editor && target && !(e.nativeEvent instanceof simMouseEvent ? e.nativeEvent.dash : false)) {
@@ -789,10 +797,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
                 .lastElement()
                 .replace(Doc.localServerPath(), '')
                 .split('?')[0];
-            const deleteMarkups = undoBatch(() => {
+            const deleteMarkups = undoable(() => {
                 const { selection } = editor.state;
                 editor.dispatch(editor.state.tr.removeMark(selection.from, selection.to, editor.state.schema.marks.linkAnchor));
-            });
+            }, 'delete markups');
             e.persist();
             anchorDoc &&
                 DocServer.GetRefField(anchorDoc).then(
@@ -816,21 +824,21 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
         const changeItems: ContextMenuProps[] = [];
         changeItems.push({
             description: 'plain',
-            event: undoBatch(() => {
+            event: undoable(() => {
                 Doc.setNativeView(this.Document);
                 this.layoutDoc.layout_autoHeightMargins = undefined;
-            }),
+            }, 'set plain view'),
             icon: 'eye',
         });
         changeItems.push({
             description: 'metadata',
-            event: undoBatch(() => {
+            event: undoable(() => {
                 this.dataDoc.layout_meta = Cast(Doc.UserDoc().emptyHeader, Doc, null)?.layout;
                 this.Document.layout_fieldKey = 'layout_meta';
                 setTimeout(() => {
                     this.layoutDoc._header_height = this.layoutDoc._layout_autoHeightMargins = 50;
                 }, 50);
-            }),
+            }, 'set metadata view'),
             icon: 'eye',
         });
         const noteTypesDoc = Cast(Doc.UserDoc().template_notes, Doc, null);
@@ -838,11 +846,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
             const icon: IconProp = StrCast(note.icon) as IconProp;
             changeItems.push({
                 description: StrCast(note.title),
-                event: undoBatch(() => {
-                    this.layoutDoc.layout_autoHeightMargins = undefined;
-                    Doc.setNativeView(this.Document);
-                    DocUtils.makeCustomViewClicked(this.Document, Docs.Create.TreeDocument, StrCast(note.title), note);
-                }),
+                event: undoable(
+                    () => {
+                        this.layoutDoc.layout_autoHeightMargins = undefined;
+                        Doc.setNativeView(this.Document);
+                        DocUtils.makeCustomViewClicked(this.Document, Docs.Create.TreeDocument, StrCast(note.title), note);
+                    },
+                    `set ${StrCast(note.title)} view}`
+                ),
                 icon: icon,
             });
         });
@@ -1229,9 +1240,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
                 const protoData = DocCast(this.dataDoc.proto)?.[this.fieldKey];
                 const dataData = this.dataDoc[this.fieldKey];
                 const layoutData = Doc.AreProtosEqual(this.layoutDoc, this.dataDoc) ? undefined : this.layoutDoc[this.fieldKey];
-                const dataTime = dataData ? DateCast(this.dataDoc[this.fieldKey + '_modificationDate'])?.date.getTime() ?? 0 : 0;
-                const layoutTime = layoutData && this.dataDoc[this.fieldKey + '_autoUpdate'] ? DateCast(DocCast(this.layoutDoc)[this.fieldKey + '_modificationDate'])?.date.getTime() ?? 0 : 0;
-                const protoTime = protoData && this.dataDoc[this.fieldKey + '_autoUpdate'] ? DateCast(DocCast(this.dataDoc.proto)[this.fieldKey + '_modificationDate'])?.date.getTime() ?? 0 : 0;
+                const dataTime = dataData ? (DateCast(this.dataDoc[this.fieldKey + '_modificationDate'])?.date.getTime() ?? 0) : 0;
+                const layoutTime = layoutData && this.dataDoc[this.fieldKey + '_autoUpdate'] ? (DateCast(DocCast(this.layoutDoc)[this.fieldKey + '_modificationDate'])?.date.getTime() ?? 0) : 0;
+                const protoTime = protoData && this.dataDoc[this.fieldKey + '_autoUpdate'] ? (DateCast(DocCast(this.dataDoc.proto)[this.fieldKey + '_modificationDate'])?.date.getTime() ?? 0) : 0;
                 const recentData = dataTime >= layoutTime ? (protoTime >= dataTime ? protoData : dataData) : layoutTime >= protoTime ? layoutData : protoData;
                 const whichData = recentData ?? (this.layoutDoc.isTemplateDoc ? layoutData : protoData) ?? protoData;
                 return !whichData ? undefined : { data: RTFCast(whichData), str: Field.toString(DocCast(whichData) ?? StrCast(whichData)) };
@@ -1370,11 +1381,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
     }
 
     richTextMenuPlugin() {
-        return new Plugin({view : action((newView: EditorView) => {
+        return new Plugin({
+            view: action((newView: EditorView) => {
                 this._props.rootSelected?.() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView);
                 return new RichTextMenuPlugin({ editorProps: this._props });
-            })});
-    };
+            }),
+        });
+    }
     _didScroll = false;
     _scrollStopper: undefined | (() => void);
     // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -1509,7 +1522,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
             e.preventDefault();
             e.stopPropagation();
             const timecode = Number(target.dataset?.timecode);
-            DocServer.GetRefField(target.dataset?.audioid || "").then(anchor => {
+            DocServer.GetRefField(target.dataset?.audioid || '').then(anchor => {
                 if (anchor instanceof Doc) {
                     // const timecode = NumCast(anchor.timecodeToShow, 0);
                     const audiodoc = anchor.annotationOn as Doc;
@@ -1549,8 +1562,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
         const state = this.EditorView?.state;
         if (state && this.ProseRef?.children[0].className.includes('-focused') && this._props.isContentActive() && !e.button) {
             if (!state.selection.empty && !(state.selection instanceof NodeSelection)) this.setupAnchorMenu();
-            let clickTarget:HTMLElement|Element|null = e.target as HTMLElement; // hrefs are stored on the dataset of the <a> node that wraps the hyerlink <span>
-            for (let target:HTMLElement|Element|null = clickTarget as HTMLElement; target instanceof HTMLElement && !target.dataset?.targethrefs; target = target.parentElement);
+            let clickTarget: HTMLElement | Element | null = e.target as HTMLElement; // hrefs are stored on the dataset of the <a> node that wraps the hyerlink <span>
+            for (let target: HTMLElement | Element | null = clickTarget as HTMLElement; target instanceof HTMLElement && !target.dataset?.targethrefs; target = target.parentElement);
             while (clickTarget instanceof HTMLElement && !clickTarget.dataset?.targethrefs) clickTarget = clickTarget.parentElement;
             const dataset = clickTarget instanceof HTMLElement ? clickTarget?.dataset : undefined;
             FormattedTextBoxComment.update(this, this.EditorView!, undefined, dataset?.targethrefs, dataset?.linkdoc, dataset?.nopreview === 'true');
@@ -1588,7 +1601,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
     onClick = (e: React.MouseEvent): void => {
         if (!this._props.isContentActive()) return;
         const editorView = this._editorView;
-        const editorRoot = editorView?.root instanceof Document ?editorView.root : undefined;
+        const editorRoot = editorView?.root instanceof Document ? editorView.root : undefined;
         if (editorView && (!this._forceUncollapse || editorRoot?.getSelection()?.isCollapsed)) {
             // this is a hack to allow the cursor to be placed at the end of a document when the document ends in an inline dash comment.  Apparently Chrome on Windows has a bug/feature which breaks this when clicking after the end of the text.
             const pcords = editorView.posAtCoords({ left: e.clientX, top: e.clientY });
@@ -1834,7 +1847,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
         TraceMobx();
         const annotated = DocListCast(this.dataDoc[this.SidebarKey]).filter(d => d?.author).length;
         const color = !annotated ? Colors.WHITE : Colors.BLACK;
-        const backgroundColor = !annotated ? (this.sidebarWidth() ? Colors.MEDIUM_BLUE : Colors.BLACK) : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.WidgetColor + (annotated ? ':annotated' : '')) as string;
+        const backgroundColor = !annotated ? (this.sidebarWidth() ? Colors.MEDIUM_BLUE : Colors.BLACK) : (this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.WidgetColor + (annotated ? ':annotated' : '')) as string);
 
         return !annotated && (!this._props.isContentActive() || SnappingManager.IsDragging || Doc.ActiveTool !== InkTool.None) ? null : (
             <div
@@ -1981,7 +1994,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
     @computed get fontColor() {  return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontColor) as string; } // prettier-ignore
     @computed get fontSize()  {  return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontSize) as string; } // prettier-ignore
     @computed get fontFamily() { return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontFamily) as string; } // prettier-ignore
-    @computed get fontWeight() { return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontWeight) as string;  }// prettier-ignore
+    @computed get fontWeight() { return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontWeight) as string;  } // prettier-ignore
     render() {
         TraceMobx();
         const scale = this._props.NativeDimScaling?.() || 1;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 37a96fc37..6c0eac103 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -61,8 +61,8 @@ export class FormattedTextBoxComment {
             tooltip.style.display = 'none';
             tooltip.appendChild(tooltipText);
             tooltip.onpointerdown = (e: PointerEvent) => {
-                const { textBox, startUserMarkRegion, endUserMarkRegion, userMark } = FormattedTextBoxComment;
-                false && startUserMarkRegion !== undefined && textBox?.adoptAnnotation(startUserMarkRegion, endUserMarkRegion, userMark);
+                // const { textBox, startUserMarkRegion, endUserMarkRegion, userMark } = FormattedTextBoxComment;
+                // startUserMarkRegion !== undefined && textBox?.adoptAnnotation(startUserMarkRegion, endUserMarkRegion, userMark);
                 e.stopPropagation();
                 e.preventDefault();
             };
diff --git a/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts b/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts
index 8799964b3..d41938698 100644
--- a/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts
+++ b/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts
@@ -1,18 +1,18 @@
-import { Node, DOMOutputSpec } from 'prosemirror-model';
+import { Node, DOMOutputSpec, AttributeSpec, TagParseRule } from 'prosemirror-model';
 import clamp from '../../../util/clamp';
 import convertToCSSPTValue from '../../../util/convertToCSSPTValue';
 import toCSSLineSpacing from '../../../util/toCSSLineSpacing';
 
 // import type { NodeSpec } from './Types';
 type NodeSpec = {
-    attrs?: { [key: string]: any };
+    attrs?: { [key: string]: AttributeSpec };
     content?: string;
     draggable?: boolean;
     group?: string;
     inline?: boolean;
     name?: string;
-    parseDOM?: Array<any>;
-    toDOM?: (node: any) => DOMOutputSpec;
+    parseDOM?: Array<TagParseRule>;
+    toDOM?: (node: Node) => DOMOutputSpec;
 };
 
 // This assumes that every 36pt maps to one indent level.
@@ -30,7 +30,7 @@ function convertMarginLeftToIndentValue(marginLeft: string): number {
     return clamp(MIN_INDENT_LEVEL, Math.floor(ptValue / INDENT_MARGIN_PT_SIZE), MAX_INDENT_LEVEL);
 }
 
-function getAttrs(dom: HTMLElement): Object {
+export function getAttrs(dom: HTMLElement): object {
     const { lineHeight, textAlign, marginLeft, paddingTop, paddingBottom } = dom.style;
 
     let align = dom.getAttribute('align') || textAlign || '';
@@ -50,9 +50,31 @@ function getAttrs(dom: HTMLElement): Object {
     return { align, indent, lineSpacing, paddingTop, paddingBottom, id };
 }
 
-function toDOM(node: Node): DOMOutputSpec {
+export function getHeadingAttrs(dom: HTMLElement): { align?: string; indent?: number; lineSpacing?: string; paddingTop?: string; paddingBottom?: string; id: string; level?: number } {
+    const { lineHeight, textAlign, marginLeft, paddingTop, paddingBottom } = dom.style;
+
+    let align = dom.getAttribute('align') || textAlign || '';
+    align = ALIGN_PATTERN.test(align) ? align : '';
+
+    let indent = parseInt(dom.getAttribute(ATTRIBUTE_INDENT) || '', 10);
+
+    if (!indent && marginLeft) {
+        indent = convertMarginLeftToIndentValue(marginLeft);
+    }
+
+    indent = indent || MIN_INDENT_LEVEL;
+
+    const lineSpacing = lineHeight ? toCSSLineSpacing(lineHeight) : undefined;
+
+    const level = Number(dom.nodeName.substring(1)) || 1;
+
+    const id = dom.getAttribute('id') || '';
+    return { align, indent, lineSpacing, paddingTop, paddingBottom, id, level };
+}
+
+export function toDOM(node: Node): DOMOutputSpec {
     const { align, indent, inset, lineSpacing, paddingTop, paddingBottom, id } = node.attrs;
-    const attrs: { [key: string]: any } | null = {};
+    const attrs: { [key: string]: unknown } | null = {};
 
     let style = '';
     if (align && align !== 'left') {
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 247b7c097..738f6d699 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -1,8 +1,8 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@mui/material';
-import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
-import { lift, wrapIn } from 'prosemirror-commands';
+import { lift, toggleMark, wrapIn } from 'prosemirror-commands';
 import { Mark, MarkType } from 'prosemirror-model';
 import { wrapInList } from 'prosemirror-schema-list';
 import { EditorState, NodeSelection, TextSelection, Transaction } from 'prosemirror-state';
@@ -22,8 +22,6 @@ import { updateBullets } from './ProsemirrorExampleTransfer';
 import './RichTextMenu.scss';
 import { schema } from './schema_rts';
 
-const { toggleMark } = require('prosemirror-commands');
-
 @observer
 export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
     // eslint-disable-next-line no-use-before-define
@@ -35,8 +33,8 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
     private _linkToRef = React.createRef<HTMLInputElement>();
 
     layoutDoc: Doc | undefined;
-    @observable public view?: EditorView & { TextView ?: FormattedTextBox } = undefined;
-    public editorProps: FieldViewProps | AntimodeMenuProps |undefined;
+    @observable public view?: EditorView & { TextView?: FormattedTextBox } = undefined;
+    public editorProps: FieldViewProps | AntimodeMenuProps | undefined;
 
     public _brushMap: Map<string, Set<Mark>> = new Map();
 
@@ -124,7 +122,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
     }
 
     @action
-    public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: FormattedTextBoxProps|AntimodeMenuProps|undefined, layoutDoc: Doc | undefined) {
+    public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: FormattedTextBoxProps | AntimodeMenuProps | undefined, layoutDoc: Doc | undefined) {
         if (this._linkToRef.current?.getBoundingClientRect().width) {
             return;
         }
@@ -158,7 +156,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
         this.getTextLinkTargetTitle().then(targetTitle => this.setCurrentLink(targetTitle));
     }
 
-    setMark = (mark: Mark, state: EditorState, dispatch: (tr:Transaction) => void, dontToggle: boolean = false) => {
+    setMark = (mark: Mark, state: EditorState, dispatch: (tr: Transaction) => void, dontToggle: boolean = false) => {
         if (mark) {
             const newPos = state.selection.$anchor.node()?.type === schema.nodes.ordered_list ? state.selection.from : state.selection.from;
             const node = (state.selection as NodeSelection).node ?? (newPos >= 0 ? state.doc.nodeAt(newPos) : undefined);
@@ -177,7 +175,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
                     toggleMark(mark.type, mark.attrs)(state, dispatch);
                 }
             }
-        //    this.updateMenu(this.view, undefined, undefined, this.layoutDoc);
+            //    this.updateMenu(this.view, undefined, undefined, this.layoutDoc);
         }
     };
 
@@ -193,7 +191,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
             }
         }
         return 'left';
-    }
+    };
 
     // finds font sizes and families in selection
     getActiveListStyle = () => {
@@ -208,7 +206,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
             }
         }
         return '';
-    }
+    };
 
     // finds font sizes and families in selection
     getActiveFontStylesOnSelection() {
@@ -365,7 +363,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
             this.view.focus();
         } else {
             Doc.UserDoc()[fontField] = value;
-           // this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
+            // this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
         }
     };
 
@@ -391,10 +389,10 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
                 this.view!.dispatch(tx3);
             });
         this.view.focus();
-       // this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
+        // this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
     };
 
-    insertSummarizer(state: EditorState, dispatch: (tr:Transaction) => void) {
+    insertSummarizer(state: EditorState, dispatch: (tr: Transaction) => void) {
         if (state.selection.empty) return false;
         const mark = state.schema.marks.summarize.create();
         const { tr } = state;
@@ -408,7 +406,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
     vcenterToggle = () => {
         this.layoutDoc && (this.layoutDoc._layout_centered = !this.layoutDoc._layout_centered);
     };
-    align = (view: EditorView, dispatch: (tr:Transaction) => void, alignment: 'left' | 'right' | 'center') => {
+    align = (view: EditorView, dispatch: (tr: Transaction) => void, alignment: 'left' | 'right' | 'center') => {
         if (this.TextView?._props.rootSelected?.()) {
             let { tr } = view.state;
             view.state.doc.nodesBetween(view.state.selection.from, view.state.selection.to, (node, pos) => {
@@ -424,7 +422,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
         }
     };
 
-    paragraphSetup(state: EditorState, dispatch: (tr:Transaction) => void, field: 'inset' | 'indent', value?: 0 | 10 | -10) {
+    paragraphSetup(state: EditorState, dispatch: (tr: Transaction) => void, field: 'inset' | 'indent', value?: 0 | 10 | -10) {
         let { tr } = state;
         state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos) => {
             if (node.type === schema.nodes.paragraph || node.type === schema.nodes.heading) {
@@ -440,8 +438,8 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
         return true;
     }
 
-    insertBlockquote(state: EditorState, dispatch: (tr:Transaction) => void) {
-        const node = state.selection.$from.depth ? state.selection.$from.node(state.selection.$from.depth-1): undefined;
+    insertBlockquote(state: EditorState, dispatch: (tr: Transaction) => void) {
+        const node = state.selection.$from.depth ? state.selection.$from.node(state.selection.$from.depth - 1) : undefined;
         if (node?.type === schema.nodes.blockquote) {
             lift(state, dispatch);
         } else {
@@ -450,7 +448,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
         return true;
     }
 
-    insertHorizontalRule(state: EditorState, dispatch: (tr:Transaction) => void) {
+    insertHorizontalRule(state: EditorState, dispatch: (tr: Transaction) => void) {
         dispatch(state.tr.replaceSelectionWith(state.schema.nodes.horizontal_rule.create()).scrollIntoView());
         return true;
     }
@@ -516,7 +514,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
         const onLinkChange = (e: React.ChangeEvent<HTMLInputElement>) => {
             this.TextView?.endUndoTypingBatch();
             UndoManager.RunInBatch(() => this.setCurrentLink(e.target.value), 'link change');
-        }
+        };
 
         const link = this.currentLink ? this.currentLink : '';
 
@@ -595,7 +593,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
         if (this.view) {
             const linkAnchor = this.view.state.selection.$from.nodeAfter?.marks.find(m => m.type === this.view!.state.schema.marks.linkAnchor);
             if (linkAnchor) {
-                const allAnchors = (linkAnchor.attrs.allAnchors as { href: string; title: string; linkId: string; targetId: string; }[]).slice();
+                const allAnchors = (linkAnchor.attrs.allAnchors as { href: string; title: string; linkId: string; targetId: string }[]).slice();
                 this.TextView?.RemoveAnchorFromSelection(allAnchors);
                 // bcz: Argh ... this will remove the link from the document even it's anchored somewhere else in the text which happens if only part of the anchor text was selected.
                 allAnchors
@@ -698,7 +696,7 @@ interface RichTextMenuPluginProps {
 }
 export class RichTextMenuPlugin extends React.Component<RichTextMenuPluginProps> {
     // eslint-disable-next-line react/no-unused-class-component-methods
-    update(view: EditorView & {TextView ?: FormattedTextBox}, lastState: EditorState | undefined) {
+    update(view: EditorView & { TextView?: FormattedTextBox }, lastState: EditorState | undefined) {
         RichTextMenu.Instance?.updateMenu(view, lastState, this.props.editorProps, view.TextView?.layoutDoc);
     }
     render() {
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts
index bf11dfe62..39f589b1e 100644
--- a/src/client/views/nodes/formattedText/RichTextRules.ts
+++ b/src/client/views/nodes/formattedText/RichTextRules.ts
@@ -1,4 +1,5 @@
 import { ellipsis, emDash, InputRule, smartQuotes, textblockTypeInputRule } from 'prosemirror-inputrules';
+import { NodeType } from 'prosemirror-model';
 import { NodeSelection, TextSelection } from 'prosemirror-state';
 import { ClientUtils } from '../../../../ClientUtils';
 import { Doc, DocListCast, FieldResult, StrListCast } from '../../../../fields/Doc';
@@ -6,7 +7,7 @@ import { DocData } from '../../../../fields/DocSymbols';
 import { Id } from '../../../../fields/FieldSymbols';
 import { List } from '../../../../fields/List';
 import { NumCast, StrCast } from '../../../../fields/Types';
-import { Utils } from '../../../../Utils';
+import { emptyFunction, Utils } from '../../../../Utils';
 import { Docs } from '../../../documents/Documents';
 import { CollectionViewType } from '../../../documents/DocumentTypes';
 import { DocUtils } from '../../../documents/DocUtils';
@@ -35,13 +36,7 @@ export class RichTextRules {
             wrappingInputRule(/%>$/, schema.nodes.blockquote),
 
             // 1. create numerical ordered list
-            wrappingInputRule(
-                /^1\.\s$/,
-                schema.nodes.ordered_list,
-                () => ({ mapStyle: 'decimal', bulletStyle: 1 }),
-                (match: any, node: any) => node.childCount + node.attrs.order === +match[1],
-                ((type: any) => ({ type: type, attrs: { mapStyle: 'decimal', bulletStyle: 1 } })) as any
-            ),
+            wrappingInputRule(/^1\.\s$/, schema.nodes.ordered_list, () => ({ mapStyle: 'decimal', bulletStyle: 1 }), emptyFunction, ((type: unknown) => ({ type, attrs: { mapStyle: 'decimal', bulletStyle: 1 } })) as unknown as null),
 
             // A. create alphabetical ordered list
             wrappingInputRule(
@@ -49,9 +44,8 @@ export class RichTextRules {
                 schema.nodes.ordered_list,
                 // match => {
                 () => ({ mapStyle: 'multi', bulletStyle: 1 }),
-                // return ({ order: +match[1] })
-                (match: any, node: any) => node.childCount + node.attrs.order === +match[1],
-                ((type: any) => ({ type: type, attrs: { mapStyle: 'multi', bulletStyle: 1 } })) as any
+                emptyFunction,
+                ((type: NodeType) => ({ type, attrs: { mapStyle: 'multi', bulletStyle: 1 } })) as unknown as null
             ),
 
             // * + - create bullet list
@@ -60,8 +54,8 @@ export class RichTextRules {
                 schema.nodes.ordered_list,
                 // match => {
                 () => ({ mapStyle: 'bullet' }), //  ({ order: +match[1] })
-                (match: any, node: any) => node.childCount + node.attrs.order === +match[1],
-                ((type: any) => ({ type: type, attrs: { mapStyle: 'bullet' } })) as any
+                emptyFunction,
+                ((type: NodeType) => ({ type: type, attrs: { mapStyle: 'bullet' } })) as unknown as null
             ),
 
             // ``` create code block
@@ -93,7 +87,7 @@ export class RichTextRules {
                     const textDoc = this.Document[DocData];
                     const numInlines = NumCast(textDoc.inlineTextCount);
                     textDoc.inlineTextCount = numInlines + 1;
-                    const node = (state.doc.resolve(start) as any).nodeAfter;
+                    const node = state.doc.resolve(start).nodeAfter;
                     const newNode = schema.nodes.dashComment.create({ docId: doc[Id], reflow: false });
                     const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: 'dashDoc', docId: doc[Id], float: 'right' });
                     const sm = state.storedMarks || undefined;
@@ -137,7 +131,7 @@ export class RichTextRules {
                 textDocInline.proto = textDoc; // make the annotation inherit from the outer text doc so that it can resolve any nested field references, e.g., [[field]]
                 textDoc[inlineLayoutKey] = FormattedTextBox.LayoutString(inlineFieldKey); // create a layout string for the layout key that will render the annotation text
                 textDoc[inlineFieldKey] = ''; // set a default value for the annotation
-                const node = (state.doc.resolve(start) as any).nodeAfter;
+                const node = state.doc.resolve(start).nodeAfter;
                 const newNode = schema.nodes.dashComment.create({ docId: textDocInline[Id], reflow: true });
                 const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: 'dashDoc', docId: textDocInline[Id], float: 'right' });
                 const sm = state.storedMarks || undefined;
@@ -154,8 +148,8 @@ export class RichTextRules {
             // set the First-line indent node type for the selection's paragraph (assumes % was used to initiate an EnteringStyle mode)
             new InputRule(/(%d|d)$/, (state, match, start, end) => {
                 if (!match[0].startsWith('%') && !this.EnteringStyle) return null;
-                const pos = state.doc.resolve(start) as any;
-                for (let depth = pos.path.length / 3 - 1; depth >= 0; depth--) {
+                const pos = state.doc.resolve(start);
+                for (let depth = pos.depth; depth >= 0; depth--) {
                     const node = pos.node(depth);
                     if (node.type === schema.nodes.paragraph) {
                         const replaced = state.tr.setNodeMarkup(pos.pos - pos.parentOffset - 1, node.type, { ...node.attrs, indent: node.attrs.indent === 25 ? undefined : 25 });
@@ -169,8 +163,8 @@ export class RichTextRules {
             // set the Hanging indent node type for the current selection's paragraph (assumes % was used to initiate an EnteringStyle mode)
             new InputRule(/(%h|h)$/, (state, match, start, end) => {
                 if (!match[0].startsWith('%') && !this.EnteringStyle) return null;
-                const pos = state.doc.resolve(start) as any;
-                for (let depth = pos.path.length / 3 - 1; depth >= 0; depth--) {
+                const pos = state.doc.resolve(start);
+                for (let depth = pos.depth; depth >= 0; depth--) {
                     const node = pos.node(depth);
                     if (node.type === schema.nodes.paragraph) {
                         const replaced = state.tr.setNodeMarkup(pos.pos - pos.parentOffset - 1, node.type, { ...node.attrs, indent: node.attrs.indent === -25 ? undefined : -25 });
@@ -184,12 +178,12 @@ export class RichTextRules {
             // set the Quoted indent node type for the current selection's paragraph (assumes % was used to initiate an EnteringStyle mode)
             new InputRule(/(%q|q)$/, (state, match, start, end) => {
                 if (!match[0].startsWith('%') && !this.EnteringStyle) return null;
-                const pos = state.doc.resolve(start) as any;
+                const pos = state.doc.resolve(start);
                 if (state.selection instanceof NodeSelection && state.selection.node.type === schema.nodes.ordered_list) {
                     const { node } = state.selection;
                     return state.tr.setNodeMarkup(pos.pos, node.type, { ...node.attrs, indent: node.attrs.indent === 30 ? undefined : 30 });
                 }
-                for (let depth = pos.path.length / 3 - 1; depth >= 0; depth--) {
+                for (let depth = pos.depth; depth >= 0; depth--) {
                     const node = pos.node(depth);
                     if (node.type === schema.nodes.paragraph) {
                         const replaced = state.tr.setNodeMarkup(pos.pos - pos.parentOffset - 1, node.type, { ...node.attrs, inset: node.attrs.inset === 30 ? undefined : 30 });
@@ -202,9 +196,9 @@ export class RichTextRules {
 
             // center justify text
             new InputRule(/%\^/, (state, match, start, end) => {
-                const resolved = state.doc.resolve(start) as any;
+                const resolved = state.doc.resolve(start);
                 if (resolved?.parent.type.name === 'paragraph') {
-                    return state.tr.deleteRange(start, end).setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'center' }, resolved.parent.marks);
+                    return state.tr.deleteRange(start, end).setNodeMarkup(resolved.start() - 1, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'center' }, resolved.parent.marks);
                 }
                 const node = resolved.nodeAfter;
                 const sm = state.storedMarks || undefined;
@@ -214,9 +208,9 @@ export class RichTextRules {
 
             // left justify text
             new InputRule(/%\[/, (state, match, start, end) => {
-                const resolved = state.doc.resolve(start) as any;
+                const resolved = state.doc.resolve(start);
                 if (resolved?.parent.type.name === 'paragraph') {
-                    return state.tr.deleteRange(start, end).setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'left' }, resolved.parent.marks);
+                    return state.tr.deleteRange(start, end).setNodeMarkup(resolved.start() - 1, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'left' }, resolved.parent.marks);
                 }
                 const node = resolved.nodeAfter;
                 const sm = state.storedMarks || undefined;
@@ -226,9 +220,9 @@ export class RichTextRules {
 
             // right justify text
             new InputRule(/%\]/, (state, match, start, end) => {
-                const resolved = state.doc.resolve(start) as any;
+                const resolved = state.doc.resolve(start);
                 if (resolved?.parent.type.name === 'paragraph') {
-                    return state.tr.deleteRange(start, end).setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'right' }, resolved.parent.marks);
+                    return state.tr.deleteRange(start, end).setNodeMarkup(resolved.start() - 1, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'right' }, resolved.parent.marks);
                 }
                 const node = resolved.nodeAfter;
                 const sm = state.storedMarks || undefined;
@@ -426,9 +420,9 @@ export class RichTextRules {
                 if (state.selection.to === state.selection.from || !this.EnteringStyle) return null;
 
                 const tag = match[0] === 't' ? 'todo' : match[0] === 'i' ? 'ignore' : match[0] === 'x' ? 'disagree' : match[0] === '!' ? 'important' : '??';
-                const node = (state.doc.resolve(start) as any).nodeAfter;
+                const node = state.doc.resolve(start).nodeAfter;
 
-                if (node?.marks.findIndex((m: any) => m.type === schema.marks.user_tag) !== -1) return state.tr.removeMark(start, end, schema.marks.user_tag);
+                if (node?.marks.findIndex(m => m.type === schema.marks.user_tag) !== -1) return state.tr.removeMark(start, end, schema.marks.user_tag);
                 return node
                     ? state.tr
                           .removeMark(start, end, schema.marks.user_mark)
@@ -438,7 +432,7 @@ export class RichTextRules {
             }),
 
             new InputRule(/%\(/, (state, match, start, end) => {
-                const node = (state.doc.resolve(start) as any).nodeAfter;
+                const node = state.doc.resolve(start).nodeAfter;
                 const sm = state.storedMarks?.slice() || [];
                 const mark = state.schema.marks.summarizeInclusive.create();
 
@@ -447,7 +441,7 @@ export class RichTextRules {
                 const content = selected.selection.content();
                 const replaced = node ? selected.replaceRangeWith(start, end, schema.nodes.summary.create({ visibility: true, text: content, textslice: content.toJSON() })) : state.tr;
 
-                return replaced.setSelection(new TextSelection(replaced.doc.resolve(end))).setStoredMarks([...node.marks, ...sm]);
+                return replaced.setSelection(new TextSelection(replaced.doc.resolve(end))).setStoredMarks([...(node?.marks ?? []), ...sm]);
             }),
 
             new InputRule(/%\)/, (state, match, start, end) => state.tr.deleteRange(start, end).removeStoredMark(state.schema.marks.summarizeInclusive.create())),
diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts
index 6e1f325cf..ba8e4faed 100644
--- a/src/client/views/nodes/formattedText/marks_rts.ts
+++ b/src/client/views/nodes/formattedText/marks_rts.ts
@@ -34,14 +34,14 @@ export const marks: { [index: string]: MarkSpec } = {
         parseDOM: [
             {
                 tag: 'a[href]',
-                getAttrs(dom: any) {
+                getAttrs: dom => {
                     return {
                         title: dom.getAttribute('title'),
                     };
                 },
             },
         ],
-        toDOM(node: any) {
+        toDOM: node => {
             const targethrefs = node.attrs.allAnchors.reduce((p: string, item: { href: string; title: string; anchorId: string }) => (p ? p + ' ' + item.href : item.href), '');
             const anchorids = node.attrs.allAnchors.reduce((p: string, item: { href: string; title: string; anchorId: string }) => (p ? p + ' ' + item.anchorId : item.anchorId), '');
             return ['a', { id: Utils.GenerateGuid(), class: anchorids, 'data-targethrefs': targethrefs, /* 'data-noPreview': 'true', */ 'data-linkdoc': node.attrs.linkDoc, title: node.attrs.title, style: `background: lightBlue` }, 0];
@@ -53,7 +53,7 @@ export const marks: { [index: string]: MarkSpec } = {
         parseDOM: [
             {
                 tag: 'div',
-                getAttrs(dom: any) {
+                getAttrs: dom => {
                     return {
                         noAutoLink: dom.getAttribute('data-noAutoLink'),
                     };
@@ -80,7 +80,7 @@ export const marks: { [index: string]: MarkSpec } = {
         parseDOM: [
             {
                 tag: 'a[href]',
-                getAttrs(dom: any) {
+                getAttrs: dom => {
                     return {
                         title: dom.getAttribute('title'),
                         noPreview: dom.getAttribute('noPreview'),
@@ -88,7 +88,7 @@ export const marks: { [index: string]: MarkSpec } = {
                 },
             },
         ],
-        toDOM(node: any) {
+        toDOM: node => {
             const targethrefs = node.attrs.allAnchors.reduce((p: string, item: { href: string; title: string; anchorId: string }) => (p ? p + ' ' + item.href : item.href), '');
             const anchorids = node.attrs.allAnchors.reduce((p: string, item: { href: string; title: string; anchorId: string }) => (p ? p + ' ' + item.anchorId : item.anchorId), '');
             return node.attrs.docref && node.attrs.title
@@ -117,7 +117,7 @@ export const marks: { [index: string]: MarkSpec } = {
         parseDOM: [
             {
                 tag: 'span',
-                getAttrs(dom: any) {
+                getAttrs: dom => {
                     return { fontSize: dom.style.fontSize ? dom.style.fontSize.toString() : '' };
                 },
             },
@@ -131,7 +131,7 @@ export const marks: { [index: string]: MarkSpec } = {
         parseDOM: [
             {
                 tag: 'span',
-                getAttrs(dom: any) {
+                getAttrs: dom => {
                     const cstyle = getComputedStyle(dom);
                     if (cstyle.font) {
                         if (cstyle.font.indexOf('Times New Roman') !== -1) return { fontFamily: 'Times New Roman' };
@@ -154,7 +154,7 @@ export const marks: { [index: string]: MarkSpec } = {
         parseDOM: [
             {
                 tag: 'span',
-                getAttrs(dom: any) {
+                getAttrs: dom => {
                     return { color: dom.getAttribute('color') };
                 },
             },
@@ -170,12 +170,12 @@ export const marks: { [index: string]: MarkSpec } = {
         parseDOM: [
             {
                 tag: 'span',
-                getAttrs(dom: any) {
+                getAttrs: dom => {
                     return { fontHighlight: dom.getAttribute('background-color') };
                 },
             },
         ],
-        toDOM(node: any) {
+        toDOM: node => {
             return node.attrs.fontHighlight ? ['span', { style: 'background-color:' + node.attrs.fontHighlight }] : ['span', { style: 'background-color: transparent' }];
         },
     },
@@ -224,7 +224,7 @@ export const marks: { [index: string]: MarkSpec } = {
         attrs: {
             bulletType: { default: 'decimal' },
         },
-        toDOM(node: any) {
+        toDOM: node => {
             return [
                 'span',
                 {
@@ -238,11 +238,11 @@ export const marks: { [index: string]: MarkSpec } = {
         parseDOM: [
             {
                 tag: 'span',
-                getAttrs: (p: any) => {
+                getAttrs: p => {
                     if (typeof p !== 'string') {
                         const style = getComputedStyle(p);
                         if (style.textDecoration === 'underline') return null;
-                        if (p.parentElement.outerHTML.indexOf('text-decoration: underline') !== -1 && p.parentElement.outerHTML.indexOf('text-decoration-style: solid') !== -1) {
+                        if (p.parentElement?.outerHTML.indexOf('text-decoration: underline') !== -1 && p.parentElement?.outerHTML.indexOf('text-decoration-style: solid') !== -1) {
                             return null;
                         }
                     }
@@ -266,11 +266,11 @@ export const marks: { [index: string]: MarkSpec } = {
         parseDOM: [
             {
                 tag: 'span',
-                getAttrs: (p: any) => {
+                getAttrs: p => {
                     if (typeof p !== 'string') {
                         const style = getComputedStyle(p);
                         if (style.textDecoration === 'underline') return null;
-                        if (p.parentElement.outerHTML.indexOf('text-decoration: underline') !== -1 && p.parentElement.outerHTML.indexOf('text-decoration-style: dotted') !== -1) {
+                        if (p.parentElement?.outerHTML.indexOf('text-decoration: underline') !== -1 && p.parentElement?.outerHTML.indexOf('text-decoration-style: dotted') !== -1) {
                             return null;
                         }
                     }
@@ -292,10 +292,10 @@ export const marks: { [index: string]: MarkSpec } = {
         parseDOM: [
             {
                 tag: 'span',
-                getAttrs: (p: any) => {
+                getAttrs: p => {
                     if (typeof p !== 'string') {
                         const style = getComputedStyle(p);
-                        if (style.textDecoration === 'underline' || p.parentElement.outerHTML.indexOf('text-decoration-style:line') !== -1) {
+                        if (style.textDecoration === 'underline' || p.parentElement?.outerHTML.indexOf('text-decoration-style:line') !== -1) {
                             return null;
                         }
                     }
@@ -317,7 +317,7 @@ export const marks: { [index: string]: MarkSpec } = {
             selected: { default: false },
         },
         parseDOM: [{ style: 'background: yellow' }],
-        toDOM(node: any) {
+        toDOM: node => {
             return ['span', { style: `background: ${node.attrs.selected ? 'orange' : 'yellow'}` }];
         },
     },
@@ -330,7 +330,7 @@ export const marks: { [index: string]: MarkSpec } = {
         },
         excludes: 'user_mark',
         group: 'inline',
-        toDOM(node: any) {
+        toDOM: node => {
             const uid = node.attrs.userid.replace(/\./g, '').replace(/@/g, '');
             const min = Math.round(node.attrs.modified / 60);
             const hr = Math.round(min / 60);
@@ -348,7 +348,7 @@ export const marks: { [index: string]: MarkSpec } = {
         },
         group: 'inline',
         inclusive: false,
-        toDOM(node: any) {
+        toDOM: node => {
             const uid = node.attrs.userid.replace('.', '').replace('@', '');
             return ['span', { class: 'UT-' + uid + ' UT-' + node.attrs.tag }, 0];
         },
diff --git a/src/client/views/nodes/formattedText/nodes_rts.ts b/src/client/views/nodes/formattedText/nodes_rts.ts
index 5bf942218..02ded3103 100644
--- a/src/client/views/nodes/formattedText/nodes_rts.ts
+++ b/src/client/views/nodes/formattedText/nodes_rts.ts
@@ -1,6 +1,6 @@
 import { DOMOutputSpec, Node, NodeSpec } from 'prosemirror-model';
 import { listItem, orderedList } from 'prosemirror-schema-list';
-import { ParagraphNodeSpec, toParagraphDOM, getParagraphNodeAttrs } from './ParagraphNodeSpec';
+import { ParagraphNodeSpec, toParagraphDOM, getHeadingAttrs } from './ParagraphNodeSpec';
 import { DocServer } from '../../../DocServer';
 import { Doc, Field, FieldType } from '../../../../fields/Doc';
 import { schema } from './schema_rts';
@@ -53,7 +53,7 @@ export const nodes: { [index: string]: NodeSpec } = {
         parseDOM: [
             {
                 tag: 'audiotag',
-                getAttrs(dom: any) {
+                getAttrs: dom => {
                     return {
                         timeCode: dom.getAttribute('data-timecode'),
                         audioId: dom.getAttribute('data-audioid'),
@@ -123,24 +123,57 @@ export const nodes: { [index: string]: NodeSpec } = {
             level: { default: 1 },
         },
         parseDOM: [
-            { tag: 'h1', attrs: { level: 1 } },
-            { tag: 'h2', attrs: { level: 2 } },
-            { tag: 'h3', attrs: { level: 3 } },
-            { tag: 'h4', attrs: { level: 4 } },
-            { tag: 'h5', attrs: { level: 5 } },
-            { tag: 'h6', attrs: { level: 6 } },
+            {
+                tag: 'h1',
+                attrs: { level: 1 },
+                getAttrs(dom) {
+                    return getHeadingAttrs(dom);
+                },
+            },
+            {
+                tag: 'h2',
+                attrs: { level: 2 },
+                getAttrs(dom) {
+                    return getHeadingAttrs(dom);
+                },
+            },
+            {
+                tag: 'h3',
+                attrs: { level: 3 },
+                getAttrs(dom) {
+                    return getHeadingAttrs(dom);
+                },
+            },
+            {
+                tag: 'h4',
+                attrs: { level: 4 },
+                getAttrs(dom) {
+                    return getHeadingAttrs(dom);
+                },
+            },
+            {
+                tag: 'h5',
+                attrs: { level: 5 },
+                getAttrs(dom) {
+                    return getHeadingAttrs(dom);
+                },
+            },
+            {
+                tag: 'h6',
+                attrs: { level: 6 },
+                getAttrs(dom) {
+                    return getHeadingAttrs(dom);
+                },
+            },
         ],
         toDOM(node) {
-            const dom = toParagraphDOM(node) as any;
-            dom[0] = `h${node.attrs.level || 1}`;
+            const dom = toParagraphDOM(node);
+            if (dom instanceof Array) {
+                // eslint-disable-next-line @typescript-eslint/no-explicit-any
+                (dom as any)[0] = `h${node.attrs.level || 1}`; // [0] is readonly so cast away to any
+            }
             return dom;
         },
-        getAttrs(dom: any) {
-            const attrs = getParagraphNodeAttrs(dom) as any;
-            const level = Number(dom.nodeName.substring(1)) || 1;
-            attrs.level = level;
-            return attrs;
-        },
     },
 
     // :: NodeSpec A code listing. Disallows marks or non-text inline
@@ -221,7 +254,7 @@ export const nodes: { [index: string]: NodeSpec } = {
         parseDOM: [
             {
                 tag: 'img[src]',
-                getAttrs(dom: any) {
+                getAttrs: dom => {
                     return {
                         src: dom.getAttribute('src'),
                         title: dom.getAttribute('title'),
@@ -300,7 +333,7 @@ export const nodes: { [index: string]: NodeSpec } = {
         parseDOM: [
             {
                 tag: 'video[src]',
-                getAttrs(dom: any) {
+                getAttrs: dom => {
                     return {
                         src: dom.getAttribute('src'),
                         title: dom.getAttribute('title'),
@@ -341,33 +374,31 @@ export const nodes: { [index: string]: NodeSpec } = {
         parseDOM: [
             {
                 tag: 'ul',
-                getAttrs(dom: any) {
+                getAttrs: dom => {
                     return {
                         bulletStyle: dom.getAttribute('data-bulletStyle'),
                         mapStyle: dom.getAttribute('data-mapStyle'),
                         fontColor: dom.style.color,
-                        fontSize: dom.style['font-size'],
-                        fontFamily: dom.style['font-family'],
-                        indent: dom.style['margin-left'],
+                        fontSize: dom.style.fontSize,
+                        fontFamily: dom.style.fontFamily,
+                        indent: dom.style.marginLeft,
                     };
                 },
             },
             {
                 style: 'list-style-type=disc',
-                getAttrs() {
-                    return { mapStyle: 'bullet' };
-                },
+                getAttrs: () => ({ mapStyle: 'bullet' }),
             },
             {
                 tag: 'ol',
-                getAttrs(dom: any) {
+                getAttrs: dom => {
                     return {
                         bulletStyle: dom.getAttribute('data-bulletStyle'),
                         mapStyle: dom.getAttribute('data-mapStyle'),
                         fontColor: dom.style.color,
-                        fontSize: dom.style['font-size'],
-                        fontFamily: dom.style['font-family'],
-                        indent: dom.style['margin-left'],
+                        fontSize: dom.style.fontSize,
+                        fontFamily: dom.style.fontFamily,
+                        indent: dom.style.marginLeft,
                     };
                 },
             },
@@ -416,7 +447,7 @@ export const nodes: { [index: string]: NodeSpec } = {
         parseDOM: [
             {
                 tag: 'li',
-                getAttrs(dom: any) {
+                getAttrs: dom => {
                     return { mapStyle: dom.getAttribute('data-mapStyle'), bulletStyle: dom.getAttribute('data-bulletStyle') };
                 },
             },
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
index cb5aad32d..0920b1bd3 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable jsx-a11y/label-has-associated-control */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Button, IconButton, Type } from 'browndash-components';
 import { action, makeObservable, observable } from 'mobx';
@@ -150,7 +149,7 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
     }
 
     public addDoc: (doc: Doc | Doc[], sidebarKey?: string | undefined) => boolean = () => false;
-    public createFilteredDoc: (axes?: any) => boolean = () => false;
+    public createFilteredDoc: (axes?: string[]) => boolean = () => false;
     public addToCollection: ((doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) | undefined;
 
     /**
@@ -371,8 +370,8 @@ export class GPTPopup extends ObservableReactComponent<GPTPopupProps> {
         <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
             {this.heading('GENERATED IMAGE')}
             <div className="image-content-wrapper">
-                {this.imgUrls.map(rawSrc => (
-                    <div className="img-wrapper">
+                {this.imgUrls.map((rawSrc, i) => (
+                    <div key={rawSrc[0] + i} className="img-wrapper">
                         <div className="img-container">
                             <img key={rawSrc[0]} src={rawSrc[0]} width={150} height={150} alt="dalle generation" />
                         </div>
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 1279563ef..dee0edfae 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -1,8 +1,8 @@
 import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as Pdfjs from 'pdfjs-dist';
-import 'pdfjs-dist/web/pdf_viewer.css';
 import * as PDFJSViewer from 'pdfjs-dist/web/pdf_viewer.mjs';
+import 'pdfjs-dist/webpack.mjs'; // sets the PDF workerSrc
 import * as React from 'react';
 import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, returnAll, returnFalse, returnNone, returnZero, smoothScroll } from '../../../ClientUtils';
 import { CreateLinkToActiveAudio, Doc, DocListCast, Opt } from '../../../fields/Doc';
@@ -28,10 +28,8 @@ import { AnchorMenu } from './AnchorMenu';
 import { Annotation } from './Annotation';
 import { GPTPopup } from './GPTPopup/GPTPopup';
 import './PDFViewer.scss';
-
-// pdfjsLib.GlobalWorkerOptions.workerSrc = `/assets/pdf.worker.js`;
 // The workerSrc property shall be specified.
-Pdfjs.GlobalWorkerOptions.workerSrc = 'https://unpkg.com/pdfjs-dist@4.4.168/build/pdf.worker.mjs';
+// Pdfjs.GlobalWorkerOptions.workerSrc = 'https://unpkg.com/pdfjs-dist@4.4.168/build/pdf.worker.mjs';
 
 interface IViewerProps extends FieldViewProps {
     pdfBox: PDFBox;
@@ -62,7 +60,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
     }
 
     @observable _pageSizes: { width: number; height: number }[] = [];
-    @observable _savedAnnotations = new ObservableMap<number, (HTMLDivElement & { marqueeing?: boolean})[]>();
+    @observable _savedAnnotations = new ObservableMap<number, (HTMLDivElement & { marqueeing?: boolean })[]>();
     @observable _textSelecting = true;
     @observable _showWaiting = true;
     @observable Index: number = -1;
@@ -214,7 +212,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
         this._disposers.scale = reaction(
             () => NumCast(this._props.layoutDoc._freeform_scale, 1),
             scale => {
-                this._pdfViewer.currentScaleValue = scale+"";
+                this._pdfViewer.currentScaleValue = scale + '';
             },
             { fireImmediately: true }
         );
@@ -483,7 +481,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
             e.stopPropagation();
             if (e.ctrlKey) {
                 const curScale = Number(this._pdfViewer.currentScaleValue);
-                this._pdfViewer.currentScaleValue = Math.max(1, Math.min(10, curScale - (curScale * e.deltaY) / 1000)) + "";
+                this._pdfViewer.currentScaleValue = Math.max(1, Math.min(10, curScale - (curScale * e.deltaY) / 1000)) + '';
                 this._props.layoutDoc._freeform_scale = Number(this._pdfViewer.currentScaleValue);
             }
         }
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 2792f3aba..e6a95fd30 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1,4 +1,3 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
 /* eslint-disable @typescript-eslint/no-namespace */
 /* eslint-disable default-param-last */
 /* eslint-disable no-use-before-define */
@@ -19,7 +18,7 @@ import {
 import { Copy, FieldChanged, HandleUpdate, Id, Parent, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols';
 import { InkTool } from './InkField';
 import { List } from './List';
-import { ObjectField } from './ObjectField';
+import { ObjectField, serverOpType } from './ObjectField';
 import { PrefetchProxy, ProxyField } from './Proxy';
 import { FieldId, RefField } from './RefField';
 import { RichTextField } from './RichTextField';
@@ -28,6 +27,15 @@ import { ComputedField, ScriptField } from './ScriptField';
 import { BoolCast, Cast, DocCast, FieldValue, NumCast, StrCast, ToConstructor, toList } from './Types';
 import { containedFieldChangedHandler, deleteProperty, GetEffectiveAcl, getField, getter, makeEditable, makeReadOnly, setter, SharingPermissions } from './util';
 
+export let ObjGetRefField: (id: string, force?: boolean) => Promise<Doc | undefined>;
+export let ObjGetRefFields: (ids: string[]) => Promise<Map<string, Doc | undefined>>;
+
+export function SetObjGetRefField(func: (id: string, force?: boolean) => Promise<Doc | undefined>) {
+    ObjGetRefField = func;
+}
+export function SetObjGetRefFields(func: (ids: string[]) => Promise<Map<string, Doc | undefined>>) {
+    ObjGetRefFields = func;
+}
 export const LinkedTo = '-linkedTo';
 export namespace Field {
     /**
@@ -91,18 +99,19 @@ export namespace Field {
         });
         return script;
     }
-    export function toString(field: FieldType) {
+    export function toString(fieldIn: unknown) {
+        const field = fieldIn as FieldType;
         if (typeof field === 'string' || typeof field === 'number' || typeof field === 'boolean') return String(field);
         return field?.[ToString]?.() || '';
     }
-    export function IsField(field: any): field is FieldType;
-    export function IsField(field: any, includeUndefined: true): field is FieldType | undefined;
-    export function IsField(field: any, includeUndefined: boolean = false): field is FieldType | undefined {
+    export function IsField(field: unknown): field is FieldType;
+    export function IsField(field: unknown, includeUndefined: true): field is FieldType | undefined;
+    export function IsField(field: unknown, includeUndefined: boolean = false): field is FieldType | undefined {
         return ['string', 'number', 'boolean'].includes(typeof field) || field instanceof ObjectField || field instanceof RefField || (includeUndefined && field === undefined);
     }
     // eslint-disable-next-line @typescript-eslint/no-shadow
-    export function Copy(field: any) {
-        return field instanceof ObjectField ? ObjectField.MakeCopy(field) : field;
+    export function Copy(field: unknown) {
+        return field instanceof ObjectField ? ObjectField.MakeCopy(field) : (field as FieldType);
     }
     UndoManager.SetFieldPrinter(toString);
 }
@@ -157,7 +166,7 @@ export const ReverseHierarchyMap: Map<string, { level: aclLevel; acl: symbol; im
 // this recursively updates all protos as well.
 export function updateCachedAcls(doc: Doc) {
     if (doc) {
-        const target = (doc as any)?.__fieldTuples ?? doc;
+        const target = doc[FieldTuples] ?? doc;
         const permissions: { [key: string]: symbol } = !target.author || target.author === ClientUtils.CurrentUserEmail() ? { acl_Me: AclAdmin } : {};
         Object.keys(target).forEach(key => {
             key.startsWith('acl_') && (permissions[key] = ReverseHierarchyMap.get(StrCast(target[key]))!.acl);
@@ -177,7 +186,7 @@ export function updateCachedAcls(doc: Doc) {
 }
 
 @scriptingGlobal
-@Deserializable('Doc', updateCachedAcls, ['id'])
+@Deserializable('Doc', (obj: unknown) => updateCachedAcls(obj as Doc), ['id'])
 export class Doc extends RefField {
     @observable public static RecordingEvent = 0;
     @observable public static GuestDashboard: Doc | undefined = undefined;
@@ -328,12 +337,15 @@ export class Doc extends RefField {
     }
 
     [key: string]: FieldResult;
+    [key2: symbol]: unknown;
 
     @serializable(alias('fields', map(autoObject(), { afterDeserialize: afterDocDeserialize })))
-    private get __fieldTuples() {
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    get __fieldTuples(): any {
+        // __fieldTuples does not follow the index signature pattern which requires a FieldResult return value -- so this hack suppresses the error
         return this[FieldTuples];
     }
-    private set __fieldTuples(value) {
+    set __fieldTuples(value) {
         // called by deserializer to set all fields in one shot
         this[FieldTuples] = value;
         Object.keys(value).forEach(key => {
@@ -348,33 +360,33 @@ export class Doc extends RefField {
         });
     }
 
-    @observable private [FieldTuples]: any = {};
-    @observable private [FieldKeys]: any = {};
+    @observable private [FieldTuples]: { [key: string]: FieldResult } = {};
+    @observable private [FieldKeys]: { [key: string]: boolean } = {};
     /// all of the raw acl's that have been set on this document.  Use GetEffectiveAcl to determine the actual ACL of the doc for editing
     @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 = undefined; // meant to store sound object from Howl
+    @observable public [AudioPlay]: unknown = 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<any /* DocumentView */>();
+    @observable public [DocViews] = new ObservableSet<unknown /* DocumentView */>();
 
     private [Self] = this;
-    private [SelfProxy]: any;
+    private [SelfProxy]: Doc;
     private [UpdatingFromServer]: boolean = false;
     private [ForceServerWrite]: boolean = false;
-    private [CachedUpdates]: { [key: string]: () => void | Promise<any> } = {};
+    private [CachedUpdates]: { [key: string]: () => void | Promise<void> } = {};
 
     public [Initializing]: boolean = false;
-    public [FieldChanged] = (diff: undefined | { op: '$addToSet' | '$remFromSet' | '$set'; items: FieldType[] | undefined; length: number | undefined; hint?: any }, serverOp: any) => {
+    public [FieldChanged] = (diff: { op: '$addToSet' | '$remFromSet' | '$set'; items: FieldType[] | undefined; length: number | undefined; hint?: unknown } | undefined, serverOp: serverOpType) => {
         if (!this[UpdatingFromServer] || this[ForceServerWrite]) {
             DocServer.UpdateField(this[Id], serverOp);
         }
     };
     public [Width] = () => NumCast(this[SelfProxy]._width);
     public [Height] = () => NumCast(this[SelfProxy]._height);
-    public [TransitionTimer]: any = undefined;
+    public [TransitionTimer]: NodeJS.Timeout | undefined = undefined;
     public [ToJavascriptString] = () => `idToDoc("${this[Self][Id]}")`; // what should go here?
     public [ToScriptString] = () => `idToDoc("${this[Self][Id]}")`;
     public [ToString] = () => `Doc(${GetEffectiveAcl(this[SelfProxy]) === AclPrivate ? '-inaccessible-' : this[SelfProxy].title})`;
@@ -387,7 +399,7 @@ export class Doc extends RefField {
         const self = this[SelfProxy];
         const templateLayoutDoc = Cast(Doc.LayoutField(self), Doc, null);
         if (templateLayoutDoc) {
-            let renderFieldKey: any;
+            let renderFieldKey: string = '';
             const layoutField = templateLayoutDoc[StrCast(templateLayoutDoc.layout_fieldKey, 'layout')];
             if (typeof layoutField === 'string') {
                 [renderFieldKey] = layoutField.split("fieldKey={'")[1].split("'"); // layoutField.split("'")[1];
@@ -399,16 +411,17 @@ export class Doc extends RefField {
         return undefined;
     }
 
-    public async [HandleUpdate](diff: any) {
-        const set = diff.$set;
+    public async [HandleUpdate](diff: { $set: { [key: string]: FieldType } } | { $unset?: unknown }) {
+        const $set = '$set' in diff ? diff.$set : undefined;
+        const $unset = '$unset' in diff ? diff.$unset : undefined;
         const sameAuthor = this.author === ClientUtils.CurrentUserEmail();
         const fprefix = 'fields.';
-        Object.keys(set ?? {})
+        Object.keys($set ?? {})
             .filter(key => key.startsWith(fprefix))
             .forEach(async key => {
                 const fKey = key.substring(fprefix.length);
                 const fn = async () => {
-                    const value = await SerializationHelper.Deserialize(set[key]);
+                    const value = (await SerializationHelper.Deserialize($set?.[key])) as FieldType;
                     const prev = GetEffectiveAcl(this);
                     this[UpdatingFromServer] = true;
                     this[fKey] = value;
@@ -429,8 +442,7 @@ export class Doc extends RefField {
                     this[CachedUpdates][fKey] = fn;
                 }
             });
-        const unset = diff.$unset;
-        Object.keys(unset ?? {})
+        Object.keys($unset ?? {})
             .filter(key => key.startsWith(fprefix))
             .forEach(async key => {
                 const fKey = key.substring(7);
@@ -451,12 +463,10 @@ export class Doc extends RefField {
 
 // eslint-disable-next-line no-redeclare
 export namespace Doc {
-    // eslint-disable-next-line import/no-mutable-exports
     export let SelectOnLoad: Doc | undefined;
     export function SetSelectOnLoad(doc: Doc | undefined) {
         SelectOnLoad = doc;
     }
-    // eslint-disable-next-line import/no-mutable-exports
     export let DocDragDataName: string = '';
     export function SetDocDragDataName(name: string) {
         DocDragDataName = name;
@@ -474,7 +484,7 @@ export namespace Doc {
             delete doc[CachedUpdates][field];
         }
     }
-    export function AddCachedUpdate(doc: Doc, field: string, oldValue: any) {
+    export function AddCachedUpdate(doc: Doc, field: string, oldValue: FieldType) {
         const val = oldValue;
         doc[CachedUpdates][field] = () => {
             doc[UpdatingFromServer] = true;
@@ -493,7 +503,7 @@ export namespace Doc {
 
     export function Get(doc: Doc, key: string, ignoreProto: boolean = false): FieldResult {
         try {
-            return getField(doc[Self], key, ignoreProto);
+            return getField(doc[Self], key, ignoreProto) as FieldResult;
         } catch {
             return doc;
         }
@@ -558,9 +568,12 @@ export namespace Doc {
     export function assign<K extends string>(doc: Doc, fields: Partial<Record<K, Opt<FieldType>>>, skipUndefineds: boolean = false, isInitializing = false) {
         isInitializing && (doc[Initializing] = true);
         Object.keys(fields).forEach(key => {
-            const value = (fields as any)[key];
+            const value = (fields as { [key: string]: Opt<FieldType> })[key];
             if (!skipUndefineds || value !== undefined) {
                 // Do we want to filter out undefineds?
+                if (typeof value === 'object' && 'values' in value) {
+                    console.log(value);
+                }
                 doc[key] = value;
             }
         });
@@ -712,7 +725,7 @@ export namespace Doc {
         await Promise.all(
             Object.keys(doc).map(async key => {
                 if (filter.includes(key)) return;
-                const assignKey = (val: any) => {
+                const assignKey = (val: Opt<FieldType>) => {
                     copy[key] = val;
                 };
                 const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
@@ -735,7 +748,7 @@ export namespace Doc {
                                         .trim()
                                 );
                                 const results = docids && (await DocServer.GetRefFields(docids));
-                                const rdocs = results && Array.from(Object.keys(results)).map(rkey => DocCast(results[rkey]));
+                                const rdocs = results && Array.from(Object.keys(results)).map(rkey => DocCast(results.get(rkey)));
                                 rdocs?.map(d => d && Doc.makeClone(d, cloneMap, linkMap, rtfs, exclusions, pruneDocs, cloneLinks, cloneTemplates));
                                 rtfs.push({ copy, key, field: objField });
                             }
@@ -818,11 +831,11 @@ export namespace Doc {
         const linkedDocs = Array.from(linkMap.values());
         linkedDocs.forEach(link => Doc.AddLink?.(link, true));
         rtfMap.forEach(({ copy, key, field }) => {
-            const replacer = (match: any, attr: string, id: string /* , offset: any, string: any */) => {
+            const replacer = (match: string, attr: string, id: string /* , offset: any, string: any */) => {
                 const mapped = cloneMap.get(id);
                 return attr + '"' + (mapped ? mapped[Id] : id) + '"';
             };
-            const replacer2 = (match: any, href: string, id: string /* , offset: any, string: any */) => {
+            const replacer2 = (match: string, href: string, id: string /* , offset: any, string: any */) => {
                 const mapped = cloneMap.get(id);
                 return href + (mapped ? mapped[Id] : id);
             };
@@ -874,7 +887,7 @@ export namespace Doc {
                             newLayoutDoc.embedContainer = targetDoc;
                             newLayoutDoc.resolvedDataDoc = dataDoc;
                             newLayoutDoc.acl_Guest = SharingPermissions.Edit;
-                            if (dataDoc[templateField] === undefined && (templateLayoutDoc[templateField] as any)?.length) {
+                            if (dataDoc[templateField] === undefined && (templateLayoutDoc[templateField] as List<Doc>)?.length) {
                                 dataDoc[templateField] = ObjectField.MakeCopy(templateLayoutDoc[templateField] as List<Doc>);
                                 // ComputedField.MakeFunction(`ObjectField.MakeCopy(templateLayoutDoc["${templateField}"])`, { templateLayoutDoc: Doc.name }, { templateLayoutDoc });
                             }
@@ -901,7 +914,7 @@ export namespace Doc {
         return { layout: Doc.expandTemplateLayout(childDoc, templateRoot), data: resolvedDataDoc };
     }
 
-    export function FindReferences(infield: Doc | List<any>, references: Set<Doc>, system: boolean | undefined) {
+    export function FindReferences(infield: Doc | List<Doc>, references: Set<Doc>, system: boolean | undefined) {
         if (infield instanceof Promise) return;
         if (!(infield instanceof Doc)) {
             infield?.forEach(val => (val instanceof Doc || val instanceof List) && FindReferences(val, references, system));
@@ -976,9 +989,10 @@ export namespace Doc {
                     } else if (cfield instanceof ComputedField) {
                         copy[key] = cfield[Copy](); // ComputedField.MakeFunction(cfield.script.originalScript);
                     } else if (field instanceof ObjectField) {
+                        const docAtKey = doc[key];
                         copy[key] =
-                            doc[key] instanceof Doc && key.includes('layout[')
-                                ? new ProxyField(Doc.MakeCopy(doc[key] as any)) // copy the expanded render template
+                            docAtKey instanceof Doc && key.includes('layout[')
+                                ? new ProxyField(Doc.MakeCopy(docAtKey)) // copy the expanded render template
                                 : ObjectField.MakeCopy(field);
                     } else if (field instanceof Promise) {
                         // eslint-disable-next-line no-debugger
@@ -1235,7 +1249,7 @@ export namespace Doc {
     }
 
     const UnhighlightWatchers: (() => void)[] = [];
-    let UnhighlightTimer: any;
+    let UnhighlightTimer: NodeJS.Timeout | undefined;
     export function IsUnhighlightTimerSet() { return UnhighlightTimer; } // prettier-ignore
     export function AddUnHighlightWatcher(watcher: () => void) {
         if (UnhighlightTimer) {
@@ -1244,7 +1258,7 @@ export namespace Doc {
     }
     export function linkFollowUnhighlight() {
         clearTimeout(UnhighlightTimer);
-        UnhighlightTimer = 0;
+        UnhighlightTimer = undefined;
         UnhighlightWatchers.forEach(watcher => watcher());
         UnhighlightWatchers.length = 0;
         highlightedDocs.forEach(doc => Doc.UnHighlightDoc(doc));
@@ -1258,10 +1272,7 @@ export namespace Doc {
         if (UnhighlightTimer) clearTimeout(UnhighlightTimer);
         const presTransition = Number(presentationEffect?.presentation_transition);
         const duration = isNaN(presTransition) ? 5000 : presTransition;
-        UnhighlightTimer = window.setTimeout(() => {
-            linkFollowUnhighlight();
-            UnhighlightTimer = 0;
-        }, duration);
+        UnhighlightTimer = setTimeout(linkFollowUnhighlight, duration);
     }
 
     export const highlightedDocs = new ObservableSet<Doc>();
@@ -1319,7 +1330,7 @@ export namespace Doc {
         StrCast(doc.layout_fieldKey).split('_')[1] === 'icon' && setNativeView(doc);
     }
 
-    export function setNativeView(doc: any) {
+    export function setNativeView(doc: Doc) {
         const prevLayout = StrCast(doc.layout_fieldKey).split('_')[1];
         const deiconify = prevLayout === 'icon' && StrCast(doc.deiconifyLayout) ? 'layout_' + StrCast(doc.deiconifyLayout) : '';
         prevLayout === 'icon' && (doc.deiconifyLayout = undefined);
@@ -1356,15 +1367,15 @@ export namespace Doc {
     // filters document in a container collection:
     // all documents with the specified value for the specified key are included/excluded
     // based on the modifiers :"check", "x", undefined
-    export function setDocFilter(container: Opt<Doc>, key: string, value: any, modifiers: 'remove' | 'match' | 'check' | 'x' | 'exists' | 'unset', toggle?: boolean, fieldPrefix?: string, append: boolean = true) {
+    export function setDocFilter(container: Opt<Doc>, key: string, value: FieldType | undefined, modifiers: 'remove' | 'match' | 'check' | 'x' | 'exists' | 'unset', toggle?: boolean, fieldPrefix?: string, append: boolean = true) {
         if (!container) return;
         const filterField = '_' + (fieldPrefix ? fieldPrefix + '_' : '') + 'childFilters';
         const childFilters = StrListCast(container[filterField]);
         runInAction(() => {
             for (let i = 0; i < childFilters.length; i++) {
                 const fields = childFilters[i].split(FilterSep); // split key:value:modifier
-                if (fields[0] === key && (fields[1] === value.toString() || modifiers === 'match' || (fields[2] === 'match' && modifiers === 'remove'))) {
-                    if (fields[2] === modifiers && modifiers && fields[1] === value.toString()) {
+                if (fields[0] === key && (fields[1] === value?.toString() || modifiers === 'match' || (fields[2] === 'match' && modifiers === 'remove'))) {
+                    if (fields[2] === modifiers && modifiers && fields[1] === value?.toString()) {
                         // eslint-disable-next-line no-param-reassign
                         if (toggle) modifiers = 'remove';
                         else return;
@@ -1393,7 +1404,7 @@ export namespace Doc {
         return undefined;
     }
     export function assignDocToField(doc: Doc, field: string, id: string) {
-        DocServer.GetRefField(id).then(layout => {
+        DocServer.GetRefField(id)?.then(layout => {
             layout instanceof Doc && (doc[field] = layout);
         });
         return id;
@@ -1460,7 +1471,6 @@ export namespace Doc {
             case DocumentType.BUTTON: return 'bolt';
             case DocumentType.PRES: return 'route';
             case DocumentType.SCRIPTING: return 'terminal';
-            case DocumentType.IMPORT: return 'cloud-upload-alt';
             case DocumentType.VID: return 'video';
             case DocumentType.INK: return 'pen-nib';
             case DocumentType.PDF: return 'file-pdf';
@@ -1494,7 +1504,7 @@ export namespace Doc {
                 const doc = DocCast(await DocServer.GetRefField(json.id));
                 const links = await DocServer.GetRefFields(json.linkids as string[]);
                 Array.from(Object.keys(links))
-                    .map(key => links[key])
+                    .map(key => links.get(key))
                     .forEach(link => link instanceof Doc && Doc.AddLink?.(link));
                 return doc;
             }
@@ -1506,7 +1516,7 @@ export namespace Doc {
         const primitives = ['string', 'number', 'boolean'];
 
         export interface JsonConversionOpts {
-            data: any;
+            data: unknown;
             title?: string;
             appendToExisting?: { targetDoc: Doc; fieldKey?: string };
             excludeEmptyObjects?: boolean;
@@ -1561,7 +1571,7 @@ export namespace Doc {
             if (data === undefined || data === null || ![...primitives, 'object'].includes(typeof data)) {
                 return undefined;
             }
-            let resolved: any;
+            let resolved: unknown;
             try {
                 resolved = JSON.parse(typeof data === 'string' ? data : JSON.stringify(data));
             } catch (e) {
@@ -1569,7 +1579,7 @@ export namespace Doc {
             }
             let output: Opt<Doc>;
             if (typeof resolved === 'object' && !(resolved instanceof Array)) {
-                output = convertObject(resolved, excludeEmptyObjects, title, appendToExisting?.targetDoc);
+                output = convertObject(resolved as { [key: string]: FieldType }, excludeEmptyObjects, title, appendToExisting?.targetDoc);
             } else {
                 // give the proper types to the data extracted from the JSON
                 const result = toField(resolved, excludeEmptyObjects);
@@ -1590,7 +1600,7 @@ export namespace Doc {
          * @returns the object mapped from JSON to field values, where each mapping
          * might involve arbitrary recursion (since toField might itself call convertObject)
          */
-        const convertObject = (object: any, excludeEmptyObjects: boolean, title?: string, target?: Doc): Opt<Doc> => {
+        const convertObject = (object: { [key: string]: FieldType }, excludeEmptyObjects: boolean, title?: string, target?: Doc): Opt<Doc> => {
             const hasEntries = Object.keys(object).length;
             if (hasEntries || !excludeEmptyObjects) {
                 const resolved = target ?? new Doc();
@@ -1618,7 +1628,7 @@ export namespace Doc {
          * @returns the list mapped from JSON to field values, where each mapping
          * might involve arbitrary recursion (since toField might itself call convertList)
          */
-        const convertList = (list: Array<any>, excludeEmptyObjects: boolean): Opt<List<FieldType>> => {
+        const convertList = (list: Array<unknown>, excludeEmptyObjects: boolean): Opt<List<FieldType>> => {
             const target = new List();
             let result: Opt<FieldType>;
             // if excludeEmptyObjects is true, any qualifying conversions from toField will
@@ -1633,15 +1643,15 @@ export namespace Doc {
             return undefined;
         };
 
-        const toField = (data: any, excludeEmptyObjects: boolean, title?: string): Opt<FieldType> => {
+        const toField = (data: unknown, excludeEmptyObjects: boolean, title?: string): Opt<FieldType> => {
             if (data === null || data === undefined) {
                 return undefined;
             }
             if (primitives.includes(typeof data)) {
-                return data;
+                return data as FieldType;
             }
             if (typeof data === 'object') {
-                return data instanceof Array ? convertList(data, excludeEmptyObjects) : convertObject(data, excludeEmptyObjects, title, undefined);
+                return data instanceof Array ? convertList(data, excludeEmptyObjects) : convertObject(data as { [key: string]: FieldType }, excludeEmptyObjects, title, undefined);
             }
             throw new Error(`How did ${data} of type ${typeof data} end up in JSON?`);
         };
@@ -1654,8 +1664,8 @@ export function RTFIsFragment(html: string) {
 export function GetHrefFromHTML(html: string): string {
     const parser = new DOMParser();
     const parsedHtml = parser.parseFromString(html, 'text/html');
-    if (parsedHtml.body.childNodes.length === 1 && parsedHtml.body.childNodes[0].childNodes.length === 1 && (parsedHtml.body.childNodes[0].childNodes[0] as any).href) {
-        return (parsedHtml.body.childNodes[0].childNodes[0] as any).href;
+    if (parsedHtml.body.childNodes.length === 1 && parsedHtml.body.childNodes[0].childNodes.length === 1 && (parsedHtml.body.childNodes[0].childNodes[0] as HTMLAnchorElement).href) {
+        return (parsedHtml.body.childNodes[0].childNodes[0] as HTMLAnchorElement).href;
     }
     return '';
 }
@@ -1675,35 +1685,35 @@ export function IdToDoc(id: string) {
     return DocCast(DocServer.GetCachedRefField(id));
 }
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function idToDoc(id: string): any {
+ScriptingGlobals.add(function idToDoc(id: string): Doc {
     return IdToDoc(id);
 });
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function renameEmbedding(doc: any) {
+ScriptingGlobals.add(function renameEmbedding(doc: Doc) {
     return StrCast(doc[DocData].title).replace(/\([0-9]*\)/, '') + `(${doc.proto_embeddingId})`;
 });
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function getProto(doc: any) {
+ScriptingGlobals.add(function getProto(doc: Doc) {
     return Doc.GetProto(doc);
 });
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function getDocTemplate(doc?: any) {
+ScriptingGlobals.add(function getDocTemplate(doc?: Doc) {
     return Doc.getDocTemplate(doc);
 });
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function getEmbedding(doc: any) {
+ScriptingGlobals.add(function getEmbedding(doc: Doc) {
     return Doc.MakeEmbedding(doc);
 });
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function getCopy(doc: any, copyProto: any) {
+ScriptingGlobals.add(function getCopy(doc: Doc, copyProto: boolean) {
     return doc.isTemplateDoc ? Doc.MakeDelegateWithProto(doc) : Doc.MakeCopy(doc, copyProto);
 });
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function copyField(field: any) {
+ScriptingGlobals.add(function copyField(field: FieldResult) {
     return Field.Copy(field);
 });
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function docList(field: any) {
+ScriptingGlobals.add(function docList(field: FieldResult) {
     return DocListCast(field);
 });
 // eslint-disable-next-line prefer-arrow-callback
@@ -1711,11 +1721,11 @@ ScriptingGlobals.add(function addDocToList(doc: Doc, field: string, added: Doc)
     return Doc.AddDocToList(doc, field, added);
 });
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function setInPlace(doc: any, field: any, value: any) {
+ScriptingGlobals.add(function setInPlace(doc: Doc, field: string, value: string) {
     return Doc.SetInPlace(doc, field, value, false);
 });
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function sameDocs(doc1: any, doc2: any) {
+ScriptingGlobals.add(function sameDocs(doc1: Doc, doc2: Doc) {
     return Doc.AreProtosEqual(doc1, doc2);
 });
 // eslint-disable-next-line prefer-arrow-callback
@@ -1723,7 +1733,7 @@ ScriptingGlobals.add(function assignDoc(doc: Doc, field: string, id: string) {
     return Doc.assignDocToField(doc, field, id);
 });
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function docCastAsync(doc: FieldResult): any {
+ScriptingGlobals.add(function docCastAsync(doc: FieldResult): FieldResult<Doc> {
     return Cast(doc, Doc);
 });
 // eslint-disable-next-line prefer-arrow-callback
@@ -1732,7 +1742,7 @@ ScriptingGlobals.add(function activePresentationItem() {
     return curPres && DocListCast(curPres[Doc.LayoutFieldKey(curPres)])[NumCast(curPres._itemIndex)];
 });
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function setDocFilter(container: Doc, key: string, value: any, modifiers: 'match' | 'check' | 'x' | 'remove') {
+ScriptingGlobals.add(function setDocFilter(container: Doc, key: string, value: string, modifiers: 'match' | 'check' | 'x' | 'remove') {
     Doc.setDocFilter(container, key, value, modifiers);
 });
 // eslint-disable-next-line prefer-arrow-callback
diff --git a/src/fields/List.ts b/src/fields/List.ts
index 38c47d546..22bbcb9ab 100644
--- a/src/fields/List.ts
+++ b/src/fields/List.ts
@@ -2,33 +2,33 @@ import { action, computed, makeObservable, observable } from 'mobx';
 import { alias, list as serializrList, serializable } from 'serializr';
 import { ScriptingGlobals } from '../client/util/ScriptingGlobals';
 import { Deserializable, afterDocDeserialize, autoObject } from '../client/util/SerializationHelper';
-import { Field, FieldType, StrListCast } from './Doc';
+import { Doc, Field, FieldType, ObjGetRefFields, StrListCast } from './Doc';
 import { FieldTuples, Self, SelfProxy } from './DocSymbols';
 import { Copy, FieldChanged, Parent, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols';
-import { ObjGetRefFields, ObjectField } from './ObjectField';
+import { ObjectField } from './ObjectField';
 import { ProxyField } from './Proxy';
 import { RefField } from './RefField';
 import { containedFieldChangedHandler, deleteProperty, getter, setter } from './util';
 
 function toObjectField(field: FieldType) {
-    return field instanceof RefField ? new ProxyField(field) : field;
+    return field instanceof Doc ? new ProxyField(field) : field;
 }
 
-function toRealField(field: FieldType) {
+function toRealField(field: FieldType | undefined) {
     return field instanceof ProxyField ? field.value : field;
 }
 
-type StoredType<T extends FieldType> = T extends RefField ? ProxyField<T> : T;
+type StoredType<T extends FieldType> = T extends Doc ? ProxyField<T> : T;
 
 export const ListFieldName = 'fields';
 @Deserializable('list')
-class ListImpl<T extends FieldType> extends ObjectField {
-    static listHandlers: any = {
+export class ListImpl<T extends FieldType> extends ObjectField {
+    static listHandlers = {
         /// Mutator methods
-        copyWithin() {
+        copyWithin: function (this: ListImpl<FieldType>) {
             throw new Error('copyWithin not supported yet');
         },
-        fill(value: any, start?: number, end?: number) {
+        fill: function (this: ListImpl<FieldType>, value: FieldType, start?: number, end?: number) {
             if (value instanceof RefField) {
                 throw new Error('fill with RefFields not supported yet');
             }
@@ -36,12 +36,12 @@ class ListImpl<T extends FieldType> extends ObjectField {
             this[SelfProxy][FieldChanged]?.();
             return res;
         },
-        pop(): any {
+        pop: function (this: ListImpl<FieldType>): FieldType {
             const field = toRealField(this[Self].__fieldTuples.pop());
             this[SelfProxy][FieldChanged]?.();
             return field;
         },
-        push: action(function (this: ListImpl<any>, ...itemsIn: any[]) {
+        push: action(function (this: ListImpl<FieldType>, ...itemsIn: FieldType[]) {
             const items = itemsIn.map(toObjectField);
 
             const list = this[Self];
@@ -58,27 +58,27 @@ class ListImpl<T extends FieldType> extends ObjectField {
             this[SelfProxy][FieldChanged]?.({ op: '$addToSet', items, length: length + items.length });
             return res;
         }),
-        reverse() {
+        reverse: function (this: ListImpl<FieldType>) {
             const res = this[Self].__fieldTuples.reverse();
             this[SelfProxy][FieldChanged]?.();
             return res;
         },
-        shift() {
+        shift: function (this: ListImpl<FieldType>) {
             const res = toRealField(this[Self].__fieldTuples.shift());
             this[SelfProxy][FieldChanged]?.();
             return res;
         },
-        sort(cmpFunc: any) {
+        sort: function (this: ListImpl<FieldType>, cmpFunc: (first: FieldType | undefined, second: FieldType | undefined) => number) {
             this[Self].__realFields; // coerce retrieving entire array
-            const res = this[Self].__fieldTuples.sort(cmpFunc ? (first: any, second: any) => cmpFunc(toRealField(first), toRealField(second)) : undefined);
+            const res = this[Self].__fieldTuples.sort(cmpFunc ? (first: FieldType, second: FieldType) => cmpFunc(toRealField(first), toRealField(second)) : undefined);
             this[SelfProxy][FieldChanged]?.();
             return res;
         },
-        splice: action(function (this: any, start: number, deleteCount: number, ...itemsIn: any[]) {
+        splice: action(function (this: ListImpl<FieldType>, start: number, deleteCount: number, ...itemsIn: FieldType[]) {
             this[Self].__realFields; // coerce retrieving entire array
             const items = itemsIn.map(toObjectField);
             const list = this[Self];
-            const removed = list.__fieldTuples.filter((item: any, i: number) => i >= start && i < start + deleteCount);
+            const removed = list.__fieldTuples.filter((item: FieldType, i: number) => i >= start && i < start + deleteCount);
             for (let i = 0; i < items.length; i++) {
                 const item = items[i];
                 // TODO Error checking to make sure parent doesn't already exist
@@ -88,7 +88,7 @@ class ListImpl<T extends FieldType> extends ObjectField {
                     item[FieldChanged] = containedFieldChangedHandler(this, i + start, item);
                 }
             }
-            const hintArray: { val: any; index: number }[] = [];
+            const hintArray: { val: FieldType; index: number }[] = [];
             for (let i = start; i < start + deleteCount; i++) {
                 hintArray.push({ val: list.__fieldTuples[i], index: i });
             }
@@ -104,7 +104,7 @@ class ListImpl<T extends FieldType> extends ObjectField {
             );
             return res.map(toRealField);
         }),
-        unshift(...itemsIn: any[]) {
+        unshift: function (this: ListImpl<FieldType>, ...itemsIn: FieldType[]) {
             const items = itemsIn.map(toObjectField);
             const list = this[Self];
             for (let i = 0; i < items.length; i++) {
@@ -121,108 +121,108 @@ class ListImpl<T extends FieldType> extends ObjectField {
             return res;
         },
         /// Accessor methods
-        concat: action(function (this: any, ...items: any[]) {
+        concat: action(function (this: ListImpl<FieldType>, ...items: FieldType[]) {
             this[Self].__realFields;
             return this[Self].__fieldTuples.map(toRealField).concat(...items);
         }),
-        includes(valueToFind: any, fromIndex: number) {
+        includes: function (this: ListImpl<FieldType>, valueToFind: FieldType, fromIndex: number) {
             if (valueToFind instanceof RefField) {
                 return this[Self].__realFields.includes(valueToFind, fromIndex);
             }
             return this[Self].__fieldTuples.includes(valueToFind, fromIndex);
         },
-        indexOf(valueToFind: any, fromIndex: number) {
+        indexOf: function (this: ListImpl<FieldType>, valueToFind: FieldType, fromIndex: number) {
             if (valueToFind instanceof RefField) {
                 return this[Self].__realFields.indexOf(valueToFind, fromIndex);
             }
             return this[Self].__fieldTuples.indexOf(valueToFind, fromIndex);
         },
-        join(separator: any) {
+        join: function (this: ListImpl<FieldType>, separator: string) {
             this[Self].__realFields;
             return this[Self].__fieldTuples.map(toRealField).join(separator);
         },
-        lastElement() {
+        lastElement: function (this: ListImpl<FieldType>) {
             return this[Self].__realFields.lastElement();
         },
-        lastIndexOf(valueToFind: any, fromIndex: number) {
+        lastIndexOf: function (this: ListImpl<FieldType>, valueToFind: FieldType, fromIndex: number) {
             if (valueToFind instanceof RefField) {
                 return this[Self].__realFields.lastIndexOf(valueToFind, fromIndex);
             }
             return this[Self].__fieldTuples.lastIndexOf(valueToFind, fromIndex);
         },
-        slice(begin: number, end: number) {
+        slice: function (this: ListImpl<FieldType>, begin: number, end: number) {
             this[Self].__realFields;
             return this[Self].__fieldTuples.slice(begin, end).map(toRealField);
         },
 
         /// Iteration methods
-        entries() {
+        entries: function (this: ListImpl<FieldType>) {
             return this[Self].__realFields.entries();
         },
-        every(callback: any, thisArg: any) {
+        every: function (this: ListImpl<FieldType>, callback: (value: FieldType, index: number, array: FieldType[]) => unknown, thisArg: unknown) {
             return this[Self].__realFields.every(callback, thisArg);
             // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
             // If we don't want to support the array parameter, we should use this version instead
             // return this[Self].__fieldTuples.every((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
         },
-        filter(callback: any, thisArg: any) {
+        filter: function (this: ListImpl<FieldType>, callback: (value: FieldType, index: number, array: FieldType[]) => FieldType[], thisArg: unknown) {
             return this[Self].__realFields.filter(callback, thisArg);
             // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
             // If we don't want to support the array parameter, we should use this version instead
             // return this[Self].__fieldTuples.filter((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
         },
-        find(callback: any, thisArg: any) {
+        find: function (this: ListImpl<FieldType>, callback: (value: FieldType, index: number, obj: FieldType[]) => FieldType, thisArg: unknown) {
             return this[Self].__realFields.find(callback, thisArg);
             // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
             // If we don't want to support the array parameter, we should use this version instead
             // return this[Self].__fieldTuples.find((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
         },
-        findIndex(callback: any, thisArg: any) {
+        findIndex: function (this: ListImpl<FieldType>, callback: (value: FieldType, index: number, obj: FieldType[]) => number, thisArg: unknown) {
             return this[Self].__realFields.findIndex(callback, thisArg);
             // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
             // If we don't want to support the array parameter, we should use this version instead
             // return this[Self].__fieldTuples.findIndex((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
         },
-        forEach(callback: any, thisArg: any) {
+        forEach: function (this: ListImpl<FieldType>, callback: (value: FieldType, index: number, array: FieldType[]) => void, thisArg: unknown) {
             return this[Self].__realFields.forEach(callback, thisArg);
             // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
             // If we don't want to support the array parameter, we should use this version instead
             // return this[Self].__fieldTuples.forEach((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
         },
-        map(callback: any, thisArg: any) {
+        map: function (this: ListImpl<FieldType>, callback: (value: FieldType, index: number, array: FieldType[]) => unknown, thisArg: unknown) {
             return this[Self].__realFields.map(callback, thisArg);
             // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
             // If we don't want to support the array parameter, we should use this version instead
             // return this[Self].__fieldTuples.map((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
         },
-        reduce(callback: any, initialValue: any) {
+        reduce: function (this: ListImpl<FieldType>, callback: (previousValue: unknown, currentValue: FieldType, currentIndex: number, array: FieldType[]) => unknown, initialValue: unknown) {
             return this[Self].__realFields.reduce(callback, initialValue);
             // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
             // If we don't want to support the array parameter, we should use this version instead
             // return this[Self].__fieldTuples.reduce((acc:any, element:any, index:number, array:any) => callback(acc, toRealField(element), index, array), initialValue);
         },
-        reduceRight(callback: any, initialValue: any) {
+        reduceRight: function (this: ListImpl<FieldType>, callback: (previousValue: unknown, currentValue: FieldType, currentIndex: number, array: FieldType[]) => unknown, initialValue: unknown) {
             return this[Self].__realFields.reduceRight(callback, initialValue);
             // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
             // If we don't want to support the array parameter, we should use this version instead
             // return this[Self].__fieldTuples.reduceRight((acc:any, element:any, index:number, array:any) => callback(acc, toRealField(element), index, array), initialValue);
         },
-        some(callback: any, thisArg: any) {
+        some: function (this: ListImpl<FieldType>, callback: (value: FieldType, index: number, array: FieldType[]) => boolean, thisArg: unknown) {
             return this[Self].__realFields.some(callback, thisArg);
             // TODO This is probably more efficient, but technically the callback can take the array, which would mean we would have to map the actual array anyway.
             // If we don't want to support the array parameter, we should use this version instead
             // return this[Self].__fieldTuples.some((element:any, index:number, array:any) => callback(toRealField(element), index, array), thisArg);
         },
-        values() {
+        values: function (this: ListImpl<FieldType>) {
             return this[Self].__realFields.values();
         },
-        [Symbol.iterator]() {
+        [Symbol.iterator]: function (this: ListImpl<FieldType>) {
             return this[Self].__realFields.values();
         },
     };
-    static listGetter(target: any, prop: string | symbol, receiver: any): any {
+    static listGetter(target: ListImpl<FieldType>, prop: string | symbol, receiver: ListImpl<FieldType>): unknown {
         if (Object.prototype.hasOwnProperty.call(ListImpl.listHandlers, prop)) {
-            return ListImpl.listHandlers[prop];
+            return (ListImpl.listHandlers as { [key: string | symbol]: unknown })[prop];
         }
         return getter(target, prop, receiver);
     }
@@ -251,7 +251,7 @@ class ListImpl<T extends FieldType> extends ObjectField {
             },
         });
         // eslint-disable-next-line no-use-before-define
-        this[SelfProxy] = list as any as List<FieldType>; // bcz: ugh .. don't know how to convince typesecript that list is a List
+        this[SelfProxy] = list as unknown as List<FieldType>; // bcz: ugh .. don't know how to convince typesecript that list is a List
         if (fields) {
             this[SelfProxy].push(...fields);
         }
@@ -260,18 +260,20 @@ class ListImpl<T extends FieldType> extends ObjectField {
     }
 
     [key: number]: T | (T extends RefField ? Promise<T> : never);
+    [key2: symbol]: unknown;
+    [key3: string]: unknown;
 
     // this requests all ProxyFields at the same time to avoid the overhead
     // of separate network requests and separate updates to the React dom.
     @computed private get __realFields() {
-        const unrequested = this[FieldTuples].filter(f => f instanceof ProxyField && f.needsRequesting).map(f => f as ProxyField<RefField>);
+        const unrequested = this[FieldTuples].filter(f => f instanceof ProxyField && f.needsRequesting).map(f => f as ProxyField<Doc>);
         // if we find any ProxyFields that don't have a current value, then
         // start the server request for all of them
         if (unrequested.length) {
             const batchPromise = ObjGetRefFields(unrequested.map(p => p.fieldId));
             // as soon as we get the fields from the server, set all the list values in one
             // action to generate one React dom update.
-            const allSetPromise = batchPromise.then(action(pfields => unrequested.map(toReq => toReq.setValue(pfields[toReq.fieldId]))));
+            const allSetPromise = batchPromise.then(action(pfields => unrequested.map(toReq => toReq.setValue(pfields.get(toReq.fieldId)))));
             // we also have to mark all lists items with this promise so that any calls to them
             // will await the batch request and return the requested field value.
             unrequested.forEach(p => p.setExternalValuePromise(allSetPromise));
@@ -280,11 +282,11 @@ class ListImpl<T extends FieldType> extends ObjectField {
     }
 
     @serializable(alias(ListFieldName, serializrList(autoObject(), { afterDeserialize: afterDocDeserialize })))
-    private get __fieldTuples() {
+    get __fieldTuples() {
         return this[FieldTuples];
     }
 
-    private set __fieldTuples(value) {
+    set __fieldTuples(value) {
         this[FieldTuples] = value;
         Object.keys(value).forEach(key => {
             const item = value[Number(key)];
@@ -297,7 +299,7 @@ class ListImpl<T extends FieldType> extends ObjectField {
 
     [Copy]() {
         const copiedData = this[Self].__fieldTuples.map(f => (f instanceof ObjectField ? f[Copy]() : f));
-        const deepCopy = new ListImpl<T>(copiedData as any);
+        const deepCopy = new ListImpl<T>(copiedData as T[]);
         return deepCopy;
     }
 
@@ -309,19 +311,19 @@ class ListImpl<T extends FieldType> extends ObjectField {
     private [SelfProxy]: List<FieldType>; // also used in utils.ts even though it won't be found using find all references
 
     [ToScriptString]()     { return `new List(${this[ToJavascriptString]()})`; } // prettier-ignore
-    [ToJavascriptString]() { return `[${(this as any).map((field: any) => Field.toScriptString(field))}]`; } // prettier-ignore
-    [ToString]()           { return `[${(this as any).map((field: any) => Field.toString(field))}]`; } // prettier-ignore
+    [ToJavascriptString]() { return `[${(this[FieldTuples]).map(field => Field.toScriptString(field))}]`; } // prettier-ignore
+    [ToString]()           { return `[${(this[FieldTuples]).map(field => Field.toString(field))}]`; } // prettier-ignore
 }
 
 // declare List as a type so you can use it in type declarations, e.g., { l: List, ...}
 export type List<T extends FieldType> = ListImpl<T> & (T | (T extends RefField ? Promise<T> : never))[];
-// decalre List as a value so you can invoke 'new' on it, e.g., new List<Doc>()
+// decalre List as a value so you can invoke 'new' on it, e.g., new List<Doc>()  (since List<T> IS ListImpl<T>, we can safely cast the 'new' return value to return List<T>)
 // eslint-disable-next-line no-redeclare
-export const List: { new <T extends FieldType>(fields?: T[]): List<T> } = ListImpl as any;
+export const List: { new <T extends FieldType>(fields?: T[]): List<T> } = ListImpl as unknown as { new <T extends FieldType>(fields?: T[]): List<T> };
 
 ScriptingGlobals.add('List', List);
 // eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function compareLists(l1: any, l2: any) {
+ScriptingGlobals.add(function compareLists(l1: List<FieldType>, l2: List<FieldType>) {
     const L1 = StrListCast(l1);
     const L2 = StrListCast(l2);
     return !L1 && !L2 ? true : L1 && L2 && L1.length === L2.length && L2.reduce((p, v) => p && L1.includes(v), true);
diff --git a/src/fields/ObjectField.ts b/src/fields/ObjectField.ts
index 231086262..21c4af608 100644
--- a/src/fields/ObjectField.ts
+++ b/src/fields/ObjectField.ts
@@ -2,13 +2,21 @@ import { ScriptingGlobals } from '../client/util/ScriptingGlobals';
 import { Copy, FieldChanged, Parent, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols';
 import { RefField } from './RefField';
 
+export type serverOpType = {
+    $set?: { [key: string]: unknown }; //
+    $unset?: { [key: string]: unknown };
+    $remFromSet?: { [key: string]: unknown };
+    $addToSet?: { [key: string]: unknown };
+    length?: number;
+};
 export abstract class ObjectField {
     // prettier-ignore
     public [FieldChanged]?: (diff?: { op: '$addToSet' | '$remFromSet' | '$set'; 
                              // eslint-disable-next-line no-use-before-define
                              items: FieldType[] | undefined; 
                              length: number | undefined; 
-                             hint?: any }, serverOp?: any) => void;
+                             hint?: unknown }, 
+                             serverOp?: serverOpType) => void;
     // eslint-disable-next-line no-use-before-define
     public [Parent]?: RefField | ObjectField;
     abstract [Copy](): ObjectField;
@@ -22,15 +30,4 @@ export abstract class ObjectField {
 }
 export type FieldType = number | string | boolean | ObjectField | RefField; // bcz: hack for now .. must match the type definition in Doc.ts .. put here to avoid import cycles
 
-// eslint-disable-next-line import/no-mutable-exports
-export let ObjGetRefField: (id: string, force?: boolean) => Promise<RefField | undefined>;
-// eslint-disable-next-line import/no-mutable-exports
-export let ObjGetRefFields: (ids: string[]) => Promise<{ [id: string]: RefField | undefined }>;
-
-export function SetObjGetRefField(func: (id: string, force?: boolean) => Promise<RefField | undefined>) {
-    ObjGetRefField = func;
-}
-export function SetObjGetRefFields(func: (ids: string[]) => Promise<{ [id: string]: RefField | undefined }>) {
-    ObjGetRefFields = func;
-}
 ScriptingGlobals.add(ObjectField);
diff --git a/src/fields/Proxy.ts b/src/fields/Proxy.ts
index 83b5672b3..48c336e60 100644
--- a/src/fields/Proxy.ts
+++ b/src/fields/Proxy.ts
@@ -3,18 +3,19 @@ import { primitive, serializable } from 'serializr';
 import { DocServer } from '../client/DocServer';
 import { scriptingGlobal } from '../client/util/ScriptingGlobals';
 import { Deserializable } from '../client/util/SerializationHelper';
-import { Field, FieldWaiting, Opt } from './Doc';
+import { Doc, Field, FieldWaiting, Opt } from './Doc';
 import { Copy, Id, ToJavascriptString, ToScriptString, ToString, ToValue } from './FieldSymbols';
 import { ObjectField } from './ObjectField';
-import { RefField } from './RefField';
 
-function deserializeProxy(field: any) {
+type serializedProxyType = { cache: { field: unknown; p: undefined | Promise<unknown> }; fieldId: string };
+
+function deserializeProxy(field: serializedProxyType) {
     if (!field.cache.field) {
-        field.cache = { field: DocServer.GetCachedRefField(field.fieldId) as any, p: undefined };
+        field.cache = { field: DocServer.GetCachedRefField(field.fieldId), p: undefined };
     }
 }
-@Deserializable('proxy', deserializeProxy)
-export class ProxyField<T extends RefField> extends ObjectField {
+@Deserializable('proxy', (obj: unknown) => deserializeProxy(obj as serializedProxyType))
+export class ProxyField<T extends Doc> extends ObjectField {
     constructor();
     constructor(value: T);
     constructor(fieldId: string);
@@ -39,10 +40,10 @@ export class ProxyField<T extends RefField> extends ObjectField {
     }
 
     [ToJavascriptString]() {
-        return Field.toScriptString(this[ToValue]()?.value);
+        return Field.toScriptString(this[ToValue]()?.value as T);
     }
     [ToScriptString]() {
-        return Field.toScriptString(this[ToValue]()?.value); // not sure this is quite right since it doesn't recreate a proxy field, but better than 'invalid' ?
+        return Field.toScriptString(this[ToValue]()?.value as T); // not sure this is quite right since it doesn't recreate a proxy field, but better than 'invalid' ?
     }
     [ToString]() {
         return Field.toString(this[ToValue]()?.value);
@@ -83,7 +84,7 @@ export class ProxyField<T extends RefField> extends ObjectField {
         return !!(!this.cache.field && !this.failed && !this._cache.p && !DocServer.GetCachedRefField(this.fieldId));
     }
 
-    setExternalValuePromise(externalValuePromise: Promise<any>) {
+    setExternalValuePromise(externalValuePromise: Promise<unknown>) {
         this.cache.p = externalValuePromise.then(() => this.value) as FieldWaiting<T>;
     }
     @action
@@ -94,7 +95,7 @@ export class ProxyField<T extends RefField> extends ObjectField {
     }
 }
 
-// eslint-disable-next-line no-redeclare
+// eslint-disable-next-line no-redeclare, @typescript-eslint/no-namespace
 export namespace ProxyField {
     let useProxy = true;
     export function DisableProxyFields() {
@@ -114,7 +115,7 @@ export namespace ProxyField {
         }
     }
 
-    export function toValue(value: any) {
+    export function toValue(value: { value: unknown }) {
         if (useProxy) {
             return { value: value.value };
         }
@@ -123,10 +124,10 @@ export namespace ProxyField {
 }
 
 // eslint-disable-next-line no-use-before-define
-function prefetchValue(proxy: PrefetchProxy<RefField>) {
-    return proxy.value as any;
+function prefetchValue(proxy: PrefetchProxy<Doc>) {
+    return proxy.value as Promise<Doc>;
 }
 
 @scriptingGlobal
-@Deserializable('prefetch_proxy', prefetchValue)
-export class PrefetchProxy<T extends RefField> extends ProxyField<T> {}
+@Deserializable('prefetch_proxy', (obj:unknown) => prefetchValue(obj as PrefetchProxy<Doc>))
+export class PrefetchProxy<T extends Doc> extends ProxyField<T> {}
diff --git a/src/fields/RefField.ts b/src/fields/RefField.ts
index 1ce81368a..4ef2a6748 100644
--- a/src/fields/RefField.ts
+++ b/src/fields/RefField.ts
@@ -14,7 +14,7 @@ export abstract class RefField {
         this[Id] = this.__id;
     }
 
-    protected [HandleUpdate]?(diff: any): void | Promise<void>;
+    protected [HandleUpdate]?(diff: unknown): void | Promise<void>;
 
     abstract [ToJavascriptString](): string;
     abstract [ToScriptString](): string;
diff --git a/src/fields/ScriptField.ts b/src/fields/ScriptField.ts
index 8fe365ac2..582c09f29 100644
--- a/src/fields/ScriptField.ts
+++ b/src/fields/ScriptField.ts
@@ -1,15 +1,15 @@
 import { action, makeObservable, observable } from 'mobx';
 import { computedFn } from 'mobx-utils';
 import { PropSchema, SKIP, createSimpleSchema, custom, map, object, primitive, serializable } from 'serializr';
-import { numberRange } from '../Utils';
+import { emptyFunction, numberRange } from '../Utils';
 import { GPTCallType, gptAPICall } from '../client/apis/gpt/GPT';
 import { CompileScript, CompiledScript, ScriptOptions, Transformer } from '../client/util/Scripting';
 import { ScriptingGlobals, scriptingGlobal } from '../client/util/ScriptingGlobals';
 import { Deserializable, autoObject } from '../client/util/SerializationHelper';
-import { Doc, Field, FieldType, FieldResult, Opt } from './Doc';
+import { Doc, Field, FieldType, FieldResult, ObjGetRefField, Opt } from './Doc';
 import { Copy, FieldChanged, Id, ToJavascriptString, ToScriptString, ToString, ToValue } from './FieldSymbols';
 import { List } from './List';
-import { ObjGetRefField, ObjectField } from './ObjectField';
+import { ObjectField } from './ObjectField';
 import { Cast, StrCast } from './Types';
 
 function optional(propSchema: PropSchema) {
@@ -20,7 +20,7 @@ function optional(propSchema: PropSchema) {
             }
             return SKIP;
         },
-        (jsonValue: any, context: any, oldValue: any, callback: (err: any, result: any) => void) => {
+        (jsonValue, context, oldValue, callback) => {
             if (jsonValue !== undefined) {
                 return propSchema.deserializer(jsonValue, callback, context, oldValue);
             }
@@ -63,7 +63,7 @@ function finalizeScript(scriptIn: ScriptField) {
 async function deserializeScript(scriptIn: ScriptField) {
     const script = scriptIn;
     if (script.captures) {
-        const captured: any = {};
+        const captured: { [key: string]: undefined | string | number | boolean | Doc } = {};
         (script.script.options as ScriptOptions).capturedVariables = captured;
         Promise.all(
             script.captures.map(async capture => {
@@ -85,7 +85,7 @@ async function deserializeScript(scriptIn: ScriptField) {
 }
 
 @scriptingGlobal
-@Deserializable('script', deserializeScript)
+@Deserializable('script', (obj: unknown) => deserializeScript(obj as ScriptField))
 export class ScriptField extends ObjectField {
     @serializable
     readonly rawscript: string | undefined;
@@ -114,7 +114,7 @@ export class ScriptField extends ObjectField {
 
         const captured = script?.options?.capturedVariables;
         if (captured) {
-            this.captures = new List<string>(Object.keys(captured).map(key => key + ':' + (captured[key] instanceof Doc ? 'ID->' + (captured[key] as Doc)[Id] : captured[key].toString())));
+            this.captures = new List<string>(Object.keys(captured).map(key => key + ':' + (captured[key] instanceof Doc ? 'ID->' + (captured[key] as Doc)[Id] : captured[key]?.toString())));
         }
         this.rawscript = rawscript;
         this.setterscript = setterscript;
@@ -186,7 +186,7 @@ export class ScriptField extends ObjectField {
 }
 
 @scriptingGlobal
-@Deserializable('computed', deserializeScript)
+@Deserializable('computed', (obj: unknown) => deserializeScript(obj as ComputedField))
 export class ComputedField extends ScriptField {
     static undefined = '__undefined';
     static useComputed = true;
@@ -221,7 +221,7 @@ export class ComputedField extends ScriptField {
                         _readOnly_: true,
                     },
                     console.log
-                ).result
+                ).result as FieldResult
             )(); // prettier-ignore
         return this._lastComputedResult;
     };
@@ -239,7 +239,7 @@ export class ComputedField extends ScriptField {
 
     public static MakeInterpolatedNumber(fieldKey: string, interpolatorKey: string, doc: Doc, curTimecode: number, defaultVal: Opt<number>) {
         if (!doc[`${fieldKey}_indexed`]) {
-            const flist = new List<number>(numberRange(curTimecode + 1).map(() => undefined) as any as number[]);
+            const flist = new List<number>(numberRange(curTimecode + 1).map(emptyFunction) as unknown as number[]);
             flist[curTimecode] = Cast(doc[fieldKey], 'number', null);
             doc[`${fieldKey}_indexed`] = flist;
         }
@@ -249,7 +249,7 @@ export class ComputedField extends ScriptField {
     }
     public static MakeInterpolatedString(fieldKey: string, interpolatorKey: string, doc: Doc, curTimecode: number) {
         if (!doc[`${fieldKey}_`]) {
-            const flist = new List<string>(numberRange(curTimecode + 1).map(() => undefined) as any as string[]);
+            const flist = new List<string>(numberRange(curTimecode + 1).map(emptyFunction) as unknown as string[]);
             flist[curTimecode] = StrCast(doc[fieldKey]);
             doc[`${fieldKey}_indexed`] = flist;
         }
@@ -260,7 +260,7 @@ export class ComputedField extends ScriptField {
     public static MakeInterpolatedDataField(fieldKey: string, interpolatorKey: string, doc: Doc, curTimecode: number) {
         if (doc[`${fieldKey}`] instanceof List) return undefined;
         if (!doc[`${fieldKey}_indexed`]) {
-            const flist = new List<FieldType>(numberRange(curTimecode + 1).map(() => undefined) as any as FieldType[]);
+            const flist = new List<FieldType>(numberRange(curTimecode + 1).map(emptyFunction) as unknown as FieldType[]);
             flist[curTimecode] = Field.Copy(doc[fieldKey]);
             doc[`${fieldKey}_indexed`] = flist;
         }
@@ -278,7 +278,7 @@ export class ComputedField extends ScriptField {
 
 ScriptingGlobals.add(
     // eslint-disable-next-line prefer-arrow-callback
-    function setIndexVal(list: any[], index: number, value: any) {
+    function setIndexVal(list: FieldResult[], index: number, value: FieldType) {
         while (list.length <= index) list.push(undefined);
         list[index] = value;
     },
@@ -288,7 +288,7 @@ ScriptingGlobals.add(
 
 ScriptingGlobals.add(
     // eslint-disable-next-line prefer-arrow-callback
-    function getIndexVal(list: any[], index: number, defaultVal: Opt<number> = undefined) {
+    function getIndexVal(list: unknown[], index: number, defaultVal: Opt<number> = undefined) {
         return list?.reduce((p, x, i) => ((i <= index && x !== undefined) || p === undefined ? x : p), defaultVal);
     },
     'returns the value at a given index of a list',
diff --git a/src/fields/util.ts b/src/fields/util.ts
index a6499c3e3..69ece82a2 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -7,7 +7,7 @@ import { UndoManager } from '../client/util/UndoManager';
 import { Doc, DocListCast, FieldType, FieldResult, HierarchyMapping, ReverseHierarchyMap, StrListCast, aclLevel, updateCachedAcls } from './Doc';
 import { AclAdmin, AclAugment, AclEdit, AclPrivate, DirectLinks, DocAcl, DocData, DocLayout, FieldKeys, ForceServerWrite, Height, Initializing, SelfProxy, UpdatingFromServer, Width } from './DocSymbols';
 import { FieldChanged, Id, Parent, ToValue } from './FieldSymbols';
-import { List } from './List';
+import { List, ListImpl } from './List';
 import { ObjectField } from './ObjectField';
 import { PrefetchProxy, ProxyField } from './Proxy';
 import { RefField } from './RefField';
@@ -44,15 +44,23 @@ export function TraceMobx() {
     tracing && trace();
 }
 
-export const _propSetterCB = new Map<string, ((target: any, value: any) => void) | undefined>();
+export const _propSetterCB = new Map<string, ((target: Doc, value: FieldType) => void) | undefined>();
 
-const _setterImpl = action((target: any, prop: string | symbol | number, valueIn: any, receiver: any): boolean => {
+const _setterImpl = action((target: Doc | ListImpl<FieldType>, prop: string | symbol | number, valueIn: unknown, receiver: Doc | ListImpl<FieldType>): boolean => {
+    if (target instanceof ListImpl) {
+        if (typeof prop !== 'symbol' && +prop == prop) {
+            target[SelfProxy].splice(+prop, 1, valueIn as FieldType);
+        } else {
+            target[prop] = valueIn as FieldType;
+        }
+        return true;
+    }
     if (SerializationHelper.IsSerializing() || typeof prop === 'symbol') {
-        target[prop] = valueIn;
+        target[prop] = valueIn as FieldResult;
         return true;
     }
 
-    let value = valueIn?.[SelfProxy] ?? valueIn; // convert any Doc type values to Proxy's
+    let value = (valueIn as Doc | ListImpl<FieldType>)?.[SelfProxy] ?? valueIn; // convert any Doc type values to Proxy's
 
     const curValue = target.__fieldTuples[prop];
     if (curValue === value || (curValue instanceof ProxyField && value instanceof RefField && curValue.fieldId === value[Id])) {
@@ -60,7 +68,7 @@ const _setterImpl = action((target: any, prop: string | symbol | number, valueIn
         // curValue should get filled in with value if it isn't already filled in, in case we fetched the referenced field some other way
         return true;
     }
-    if (value instanceof RefField) {
+    if (value instanceof Doc) {
         value = new ProxyField(value);
     }
 
@@ -77,7 +85,7 @@ const _setterImpl = action((target: any, prop: string | symbol | number, valueIn
         delete curValue[FieldChanged];
     }
 
-    if (typeof prop === 'string' && _propSetterCB.has(prop)) _propSetterCB.get(prop)!(target[SelfProxy], value);
+    if (typeof prop === 'string' && _propSetterCB.has(prop)) _propSetterCB.get(prop)!(target[SelfProxy], value as FieldType);
 
     // eslint-disable-next-line no-use-before-define
     const effectiveAcl = GetEffectiveAcl(target);
@@ -108,16 +116,17 @@ const _setterImpl = action((target: any, prop: string | symbol | number, valueIn
                  (target as Doc|ObjectField)[FieldChanged]?.(undefined, { $unset: { ['fields.' + prop]: '' } });
             else (target as Doc|ObjectField)[FieldChanged]?.(undefined, { $set:   { ['fields.' + prop]: value instanceof ObjectField ? SerializationHelper.Serialize(value) :value}});
             if (prop === 'author' || prop.toString().startsWith('acl_')) updateCachedAcls(target);
-        } else {
+        } else if (receiver instanceof Doc) {
             DocServer.registerDocWithCachedUpdate(receiver, prop as string, curValue);
         }
         !receiver[Initializing] &&
+            receiver instanceof Doc &&
             !StrListCast(receiver.undoIgnoreFields).includes(prop.toString()) &&
             (!receiver[UpdatingFromServer] || receiver[ForceServerWrite]) &&
             UndoManager.AddEvent(
                 {
                     redo: () => {
-                        receiver[prop] = value;
+                        receiver[prop] = value as FieldType;
                     },
                     undo: () => {
                         const wasUpdate = receiver[UpdatingFromServer];
@@ -137,7 +146,7 @@ const _setterImpl = action((target: any, prop: string | symbol | number, valueIn
     return true;
 });
 
-let _setter: (target: any, prop: string | symbol | number, value: any, receiver: any) => boolean = _setterImpl;
+let _setter: (target: Doc | ListImpl<FieldType>, prop: string | symbol | number, value: FieldType | undefined, receiver: Doc | ListImpl<FieldType>) => boolean = _setterImpl;
 
 export function makeReadOnly() {
     _setter = _readOnlySetter;
@@ -156,18 +165,18 @@ export function denormalizeEmail(email: string) {
 
 // return acl from cache or cache the acl and return.
 // eslint-disable-next-line no-use-before-define
-const getEffectiveAclCache = computedFn((target: any, user?: string) => getEffectiveAcl(target, user), true);
+const getEffectiveAclCache = computedFn((target: Doc | ListImpl<FieldType>, user?: string) => getEffectiveAcl(target, user), true);
 
 /**
  * Calculates the effective access right to a document for the current user.
  */
-export function GetEffectiveAcl(target: any, user?: string): symbol {
+export function GetEffectiveAcl(target: Doc | ListImpl<FieldType>, user?: string): symbol {
     if (!target) return AclPrivate;
     if (target[UpdatingFromServer] || ClientUtils.CurrentUserEmail() === 'guest') return AclAdmin;
     return getEffectiveAclCache(target, user); // all changes received from the server must be processed as Admin.  return this directly so that the acls aren't cached (UpdatingFromServer is not observable)
 }
 
-export function GetPropAcl(target: any, prop: string | symbol | number) {
+export function GetPropAcl(target: Doc | ListImpl<FieldType>, prop: string | symbol | number) {
     if (typeof prop === 'symbol' || target[UpdatingFromServer]) return AclAdmin; // requesting the UpdatingFromServer prop or AclSym must always go through to keep the local DB consistent
     if (prop && DocServer.IsPlaygroundField(prop.toString())) return AclEdit; // playground props are always editable
     return GetEffectiveAcl(target);
@@ -182,7 +191,8 @@ export function GetCachedGroupByName(name: string) {
 export function SetCachedGroups(groups: string[]) {
     runInAction(() => cachedGroups.push(...groups));
 }
-function getEffectiveAcl(target: any, user?: string): symbol {
+function getEffectiveAcl(target: Doc | ListImpl<FieldType>, user?: string): symbol {
+    if (target instanceof ListImpl) return AclAdmin;
     const targetAcls = target[DocAcl];
     if (targetAcls?.acl_Me === AclAdmin || GetCachedGroupByName('Admin')) return AclAdmin;
 
@@ -287,14 +297,14 @@ export function inheritParentAcls(parent: Doc, child: Doc, layoutOnly: boolean)
  * @param prop
  * @param propSetter
  */
-export function SetPropSetterCb(prop: string, propSetter: ((target: any, value: any) => void) | undefined) {
+export function SetPropSetterCb(prop: string, propSetter: ((target: Doc, value: FieldType) => void) | undefined) {
     _propSetterCB.set(prop, propSetter);
 }
 
 //
 // target should be either a Doc or ListImpl.  receiver should be a Proxy<Doc> Or List.
 //
-export function setter(target: any, inProp: string | symbol | number, value: any, receiver: any): boolean {
+export function setter(target: ListImpl<FieldType> | Doc, inProp: string | symbol | number, value: unknown, receiver: Doc | ListImpl<FieldType>): boolean {
     if (!inProp) {
         console.log('WARNING: trying to set an empty property.  This should be fixed. ');
         return false;
@@ -303,12 +313,12 @@ export function setter(target: any, inProp: string | symbol | number, value: any
     const effectiveAcl = inProp === 'constructor' || typeof inProp === 'symbol' ? AclAdmin : GetPropAcl(target, prop);
     if (effectiveAcl !== AclEdit && effectiveAcl !== AclAugment && effectiveAcl !== AclAdmin) return true;
     // if you're trying to change an acl but don't have Admin access / you're trying to change it to something that isn't an acceptable acl, you can't
-    if (typeof prop === 'string' && prop.startsWith('acl_') && (effectiveAcl !== AclAdmin || ![...Object.values(SharingPermissions), undefined].includes(value))) return true;
+    if (typeof prop === 'string' && prop.startsWith('acl_') && (effectiveAcl !== AclAdmin || ![...Object.values(SharingPermissions), undefined].includes(value as SharingPermissions))) return true;
 
     if (typeof prop === 'string' && prop !== '__id' && prop !== '__fieldTuples' && prop.startsWith('_')) {
         if (!prop.startsWith('__')) prop = prop.substring(1);
-        if (target.__LAYOUT__) {
-            target.__LAYOUT__[prop] = value;
+        if (target.__LAYOUT__ instanceof Doc) {
+            target.__LAYOUT__[prop] = value as FieldResult;
             return true;
         }
     }
@@ -317,10 +327,10 @@ export function setter(target: any, inProp: string | symbol | number, value: any
             return !!ScriptCast(target.__fieldTuples[prop])?.setterscript?.run({ self: target[SelfProxy], this: target[SelfProxy], value }).success;
         }
     }
-    return _setter(target, prop, value, receiver);
+    return _setter(target, prop, value as FieldType, receiver);
 }
 
-function getFieldImpl(target: any, prop: string | number, proxy: any, ignoreProto: boolean = false): any {
+function getFieldImpl(target: ListImpl<FieldType> | Doc, prop: string | number, proxy: ListImpl<FieldType> | Doc, ignoreProto: boolean = false): FieldType {
     const field = target.__fieldTuples[prop];
     const value = field?.[ToValue]?.(proxy); // converts ComputedFields to values, or unpacks ProxyFields into Proxys
     if (value) return value.value;
@@ -332,7 +342,7 @@ function getFieldImpl(target: any, prop: string | number, proxy: any, ignoreProt
     }
     return field;
 }
-export function getter(target: any, prop: string | symbol, proxy: any): any {
+export function getter(target: Doc | ListImpl<FieldType>, prop: string | symbol, proxy: ListImpl<FieldType> | Doc): unknown {
     // prettier-ignore
     switch (prop) {
         case 'then' :   return undefined;
@@ -352,19 +362,23 @@ export function getter(target: any, prop: string | symbol, proxy: any): any {
     }
 
     const layoutProp = prop.startsWith('_') ? prop.substring(1) : undefined;
-    if (layoutProp && target.__LAYOUT__) return target.__LAYOUT__[layoutProp];
+    if (layoutProp && target.__LAYOUT__) return (target.__LAYOUT__ as Doc)[layoutProp];
     return getFieldImpl(target, layoutProp ?? prop, proxy);
 }
 
-export function getField(target: any, prop: string | number, ignoreProto: boolean = false): any {
-    return getFieldImpl(target, prop, target[SelfProxy], ignoreProto);
+export function getField(target: ListImpl<FieldType> | Doc, prop: string | number, ignoreProto: boolean = false): unknown {
+    return getFieldImpl(target, prop, target[SelfProxy] as Doc, ignoreProto);
 }
 
-export function deleteProperty(target: any, prop: string | number | symbol) {
+export function deleteProperty(target: Doc | ListImpl<FieldType>, prop: string | number | symbol) {
     if (typeof prop === 'symbol') {
         delete target[prop];
     } else {
-        target[SelfProxy][prop] = undefined;
+        if (target instanceof Doc) {
+            target[SelfProxy][prop] = undefined;
+        } else if (+prop == prop) {
+            target[SelfProxy].splice(+prop, 1);
+        }
     }
     return true;
 }
@@ -378,39 +392,42 @@ export function deleteProperty(target: any, prop: string | number | symbol) {
 // were replaced.  Based on this specification, an Undo event is setup that will save enough information about the ObjectField to be
 // able to undo and redo the partial change.
 //
-export function containedFieldChangedHandler(container: List<FieldType> | Doc, prop: string | number, liveContainedField: ObjectField) {
+export function containedFieldChangedHandler(container: ListImpl<FieldType> | Doc, prop: string | number, liveContainedField: ObjectField) {
     let lastValue: FieldResult = liveContainedField instanceof ObjectField ? ObjectField.MakeCopy(liveContainedField) : liveContainedField;
-    return (diff?: { op: '$addToSet' | '$remFromSet' | '$set'; items: FieldType[] | undefined; length: number | undefined; hint?: any } /* , dummyServerOp?: any */) => {
+    return (diff?: { op: '$addToSet' | '$remFromSet' | '$set'; items: (FieldType & { value?: FieldType })[] | undefined; length: number | undefined; hint?: unknown } /* , dummyServerOp?: any */) => {
         const serializeItems = () => ({ __type: 'list', fields: diff?.items?.map((item: FieldType) => SerializationHelper.Serialize(item)) });
         // prettier-ignore
         const serverOp = diff?.op === '$addToSet'
             ? { $addToSet:   { ['fields.' + prop]: serializeItems() }, length: diff.length }
             : diff?.op === '$remFromSet'
             ? { $remFromSet: { ['fields.' + prop]: serializeItems(), hint: diff.hint}, length: diff.length }
-            : { $set:        { ['fields.' + prop]: liveContainedField ? SerializationHelper.Serialize(liveContainedField) : undefined } };
+            : { $set:        { ['fields.' + prop]: liveContainedField ? SerializationHelper.Serialize(liveContainedField) as FieldType : undefined } };
 
         if (!(container instanceof Doc) || !container[UpdatingFromServer]) {
-            const prevValue = ObjectField.MakeCopy(lastValue as List<any>);
+            const cont = container as { [key: string | number]: FieldType };
+            const prevValue = ObjectField.MakeCopy(lastValue as List<FieldType>);
             lastValue = ObjectField.MakeCopy(liveContainedField);
             const newValue = ObjectField.MakeCopy(liveContainedField);
             if (diff?.op === '$addToSet') {
                 UndoManager.AddEvent(
                     {
                         redo: () => {
+                            const contList = cont[prop] as List<FieldType>;
                             // console.log('redo $add: ' + prop, diff.items); // bcz: uncomment to log undo
-                            (container as any)[prop as any]?.push(...((diff.items || [])?.map((item: any) => item.value ?? item) ?? []));
-                            lastValue = ObjectField.MakeCopy((container as any)[prop as any]);
+                            contList?.push(...((diff.items || [])?.map(item => item.value ?? item) ?? []));
+                            lastValue = ObjectField.MakeCopy(contList);
                         },
                         undo: action(() => {
+                            const contList = cont[prop] as List<FieldType>;
                             // console.log('undo $add: ' + prop, diff.items); // bcz: uncomment to log undo
-                            diff.items?.forEach((item: any) => {
+                            diff.items?.forEach(item => {
                                 const ind =
                                     item instanceof SchemaHeaderField //
-                                        ? (container as any)[prop as any]?.findIndex((ele: any) => ele instanceof SchemaHeaderField && ele.heading === item.heading)
-                                        : (container as any)[prop as any]?.indexOf(item.value ?? item);
-                                ind !== undefined && ind !== -1 && (container as any)[prop as any]?.splice(ind, 1);
+                                        ? contList?.findIndex(ele => ele instanceof SchemaHeaderField && ele.heading === item.heading)
+                                        : contList?.indexOf(item.value ?? item);
+                                ind !== undefined && ind !== -1 && (cont[prop] as List<FieldType>)?.splice(ind, 1);
                             });
-                            lastValue = ObjectField.MakeCopy((container as any)[prop as any]);
+                            lastValue = ObjectField.MakeCopy(contList);
                         }),
                         prop: 'add ' + (diff.items?.length ?? 0) + ' items to list',
                     },
@@ -420,48 +437,53 @@ export function containedFieldChangedHandler(container: List<FieldType> | Doc, p
                 UndoManager.AddEvent(
                     {
                         redo: action(() => {
+                            const contList = cont[prop] as List<FieldType>;
                             // console.log('redo $rem: ' + prop, diff.items); // bcz: uncomment to log undo
-                            diff.items?.forEach((item: any) => {
+                            diff.items?.forEach(item => {
                                 const ind =
                                     item instanceof SchemaHeaderField //
-                                        ? (container as any)[prop as any]?.findIndex((ele: any) => ele instanceof SchemaHeaderField && ele.heading === item.heading)
-                                        : (container as any)[prop as any]?.indexOf(item.value ?? item);
-                                ind !== undefined && ind !== -1 && (container as any)[prop as any]?.splice(ind, 1);
+                                        ? contList?.findIndex(ele => ele instanceof SchemaHeaderField && ele.heading === item.heading)
+                                        : contList?.indexOf(item.value ?? item);
+                                ind !== undefined && ind !== -1 && contList?.splice(ind, 1);
                             });
-                            lastValue = ObjectField.MakeCopy((container as any)[prop as any]);
+                            lastValue = ObjectField.MakeCopy(contList);
                         }),
                         undo: () => {
+                            const contList = cont[prop] as List<FieldType>;
+                            const prevList = prevValue as List<FieldType>;
                             // console.log('undo $rem: ' + prop, diff.items); // bcz: uncomment to log undo
-                            diff.items?.forEach((item: any) => {
+                            diff.items?.forEach(item => {
                                 if (item instanceof SchemaHeaderField) {
-                                    const ind = (prevValue as List<any>).findIndex((ele: any) => ele instanceof SchemaHeaderField && ele.heading === item.heading);
-                                    ind !== -1 && (container as any)[prop as any].findIndex((ele: any) => ele instanceof SchemaHeaderField && ele.heading === item.heading) === -1 && (container as any)[prop as any].splice(ind, 0, item);
+                                    const ind = prevList.findIndex(ele => ele instanceof SchemaHeaderField && ele.heading === item.heading);
+                                    ind !== -1 && contList.findIndex(ele => ele instanceof SchemaHeaderField && ele.heading === item.heading) === -1 && contList.splice(ind, 0, item);
                                 } else {
-                                    const ind = (prevValue as List<any>).indexOf(item.value ?? item);
-                                    ind !== -1 && (container as any)[prop as any].indexOf(item.value ?? item) === -1 && (container as any)[prop as any].splice(ind, 0, item);
+                                    const ind = prevList.indexOf(item.value ?? item);
+                                    ind !== -1 && contList.indexOf(item.value ?? item) === -1 && (cont[prop] as List<FieldType>).splice(ind, 0, item);
                                 }
                             });
-                            lastValue = ObjectField.MakeCopy((container as any)[prop as any]);
+                            lastValue = ObjectField.MakeCopy(contList);
                         },
-                        prop: 'remove ' + (diff.items?.length ?? 0) + ' items from list(' + ((container as any)?.title ?? '') + ':' + prop + ')',
+                        prop: 'remove ' + (diff.items?.length ?? 0) + ' items from list(' + (cont?.title ?? '') + ':' + prop + ')',
                     },
                     diff?.items
                 );
             } else {
                 const setFieldVal = (val: FieldType | undefined) => {
-                    container instanceof Doc ? (container[prop as string] = val) : (container[prop as number] = val as FieldType);
+                    container instanceof Doc ? (container[prop] = val) : (container[prop as number] = val as FieldType);
                 };
                 UndoManager.AddEvent(
                     {
                         redo: () => {
                             // console.log('redo list: ' + prop, fieldVal()); // bcz: uncomment to log undo
-                            setFieldVal(newValue instanceof ObjectField ? ObjectField.MakeCopy(newValue) : undefined);
-                            lastValue = ObjectField.MakeCopy((container as any)[prop as any]);
+                            setFieldVal(ObjectField.MakeCopy(newValue));
+                            const containerProp = cont[prop];
+                            lastValue = containerProp instanceof ObjectField && ObjectField.MakeCopy(containerProp);
                         },
                         undo: () => {
                             // console.log('undo list: ' + prop, fieldVal()); // bcz: uncomment to log undo
-                            setFieldVal(prevValue instanceof ObjectField ? ObjectField.MakeCopy(prevValue) : undefined);
-                            lastValue = ObjectField.MakeCopy((container as any)[prop as any]);
+                            setFieldVal(ObjectField.MakeCopy(prevValue));
+                            const containerProp = cont[prop];
+                            lastValue = containerProp instanceof ObjectField && ObjectField.MakeCopy(containerProp);
                         },
                         prop: 'set list field',
                     },
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index 7a1e35636..36c0d6a4d 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
@@ -16,6 +14,7 @@ import { listSpec } from '../fields/Schema';
 import { Cast } from '../fields/Types';
 import './ImageUpload.scss';
 
+// eslint-disable-next-line @typescript-eslint/no-var-requires
 const { DFLT_IMAGE_NATIVE_DIM } = require('../client/views/global/globalCssVariables.module.scss'); // prettier-ignore
 
 export interface ImageUploadProps {
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index d8ba89fdb..4f37c45a8 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -265,7 +265,6 @@ export class MobileInterface extends React.Component {
         this._menuListView = this._homeDoc._type_collection === 'stacking' ? true : false;
         Doc.ActiveTool = InkTool.None; // ink should intially be set to none
         Doc.UserDoc().activeMobile = this._homeDoc; // active mobile set to home
-        AudioBox.Enabled = true;
 
         // remove double click to avoid mobile zoom in
         document.removeEventListener('dblclick', this.onReactDoubleClick);
diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts
index 28323d62f..bf5475042 100644
--- a/src/pen-gestures/GestureUtils.ts
+++ b/src/pen-gestures/GestureUtils.ts
@@ -2,14 +2,15 @@ import { Rect } from 'react-measure';
 import { Gestures, PointData } from './GestureTypes';
 import { NDollarRecognizer } from './ndollar';
 
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace GestureUtils {
     export class GestureEvent {
         readonly gesture: Gestures;
         readonly points: PointData[];
         readonly bounds: Rect;
-        readonly text?: any;
+        readonly text?: string;
 
-        constructor(gesture: Gestures, points: PointData[], bounds: Rect, text?: any) {
+        constructor(gesture: Gestures, points: PointData[], bounds: Rect, text?: string) {
             this.gesture = gesture;
             this.points = points;
             this.bounds = bounds;
diff --git a/src/server/ApiManagers/GooglePhotosManager.ts b/src/server/ApiManagers/GooglePhotosManager.ts
index 5feb25fd4..0970dee81 100644
--- a/src/server/ApiManagers/GooglePhotosManager.ts
+++ b/src/server/ApiManagers/GooglePhotosManager.ts
@@ -139,13 +139,13 @@
 //                 const completed: Opt<Upload.ImageInformation>[] = [];
 //                 for (const { baseUrl } of mediaItems) {
 //                     // start by getting the content size of the remote image
-//                     const results = await DashUploadUtils.InspectImage(baseUrl);
-//                     if (results instanceof Error) {
+//                     const result = await DashUploadUtils.InspectImage(baseUrl);
+//                     if (result instanceof Error) {
 //                         // if something went wrong here, we can't hope to upload it, so just move on to the next
 //                         failed++;
 //                         continue;
 //                     }
-//                     const { contentSize, ...attributes } = results;
+//                     const { contentSize, ...attributes } = result;
 //                     // check to see if we have uploaded a Google user content image *specifically via this route* already
 //                     // that has this exact content size
 //                     const found: Opt<Upload.ImageInformation> = await Database.Auxiliary.QueryUploadHistory(contentSize);
diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts
index 4cb3d8baf..b2624f654 100644
--- a/src/server/ApiManagers/UploadManager.ts
+++ b/src/server/ApiManagers/UploadManager.ts
@@ -144,7 +144,7 @@ export default class UploadManager extends ApiManager {
                     ids[id] = uuid.v4();
                     return ids[id];
                 };
-                const mapFn = (docIn: any) => {
+                const mapFn = (docIn: { id: string; fields: any[] }) => {
                     const doc = docIn;
                     if (doc.id) {
                         doc.id = getId(doc.id);
@@ -170,10 +170,10 @@ export default class UploadManager extends ApiManager {
                             mapFn(field);
                         } else if (typeof field === 'string') {
                             const re = /("(?:dataD|d)ocumentId"\s*:\s*")([\w-]*)"/g;
-                            doc.fields[key] = (field as any).replace(re, (match: any, p1: string, p2: string) => `${p1}${getId(p2)}"`);
+                            doc.fields[key] = field.replace(re, (match: string, p1: string, p2: string) => `${p1}${getId(p2)}"`);
                         } else if (field.__type === 'RichTextField') {
                             const re = /("href"\s*:\s*")(.*?)"/g;
-                            field.Data = field.Data.replace(re, (match: any, p1: string, p2: string) => `${p1}${getId(p2)}"`);
+                            field.Data = field.Data.replace(re, (match: string, p1: string, p2: string) => `${p1}${getId(p2)}"`);
                         }
                     }
                 };
@@ -192,7 +192,7 @@ export default class UploadManager extends ApiManager {
                                     if (!f) continue;
                                     const path2 = f[0]; // what about the rest of the array? are we guaranteed only one value is set?
                                     const zip = new AdmZip(path2.filepath);
-                                    zip.getEntries().forEach((entry: any) => {
+                                    zip.getEntries().forEach(entry => {
                                         const entryName = entry.entryName.replace(/%%%/g, '/');
                                         if (!entryName.startsWith('files/')) {
                                             return;
@@ -245,7 +245,7 @@ export default class UploadManager extends ApiManager {
                                 }
                             }
                             SolrManager.update();
-                            res.send(JSON.stringify({ id, docids, linkids } || 'error'));
+                            res.send(JSON.stringify({ id, docids, linkids }) || 'error');
                         } catch (e) {
                             console.log(e);
                         }
@@ -282,8 +282,8 @@ export default class UploadManager extends ApiManager {
                     const serverPath = serverPathToFile(Directory.images, '');
                     const regex = new RegExp(`${deleteFiles}.*`);
                     fs.readdirSync(serverPath)
-                        .filter((f: any) => regex.test(f))
-                        .map((f: any) => fs.unlinkSync(serverPath + f));
+                        .filter(f => regex.test(f))
+                        .map(f => fs.unlinkSync(serverPath + f));
                 }
                 imageDataUri.outputFile(uri, serverPathToFile(Directory.images, InjectSize(filename, origSuffix))).then((savedName: string) => {
                     const ext = path.extname(savedName).toLowerCase();
diff --git a/src/server/DashStats.ts b/src/server/DashStats.ts
index 808d2c6f2..6b9fb8971 100644
--- a/src/server/DashStats.ts
+++ b/src/server/DashStats.ts
@@ -9,6 +9,7 @@ import { socketMap, timeMap, userOperations } from './SocketData';
  * This includes time connected, number of operations, and
  * the rate of their operations
  */
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace DashStats {
     export const SAMPLING_INTERVAL = 1000; // in milliseconds (ms) - Time interval to update the frontend.
     export const RATE_INTERVAL = 10; // in seconds (s) - Used to calculate rate
diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts
index 08cea1de5..5e58db103 100644
--- a/src/server/DashUploadUtils.ts
+++ b/src/server/DashUploadUtils.ts
@@ -1,6 +1,7 @@
 import axios from 'axios';
+import { spawn, exec } from 'child_process';
 import { green, red } from 'colors';
-import { ExifImage } from 'exif';
+import { ExifData, ExifImage } from 'exif';
 import * as exifr from 'exifr';
 import * as ffmpeg from 'fluent-ffmpeg';
 import * as formidable from 'formidable';
@@ -18,13 +19,11 @@ import { Duplex, Stream } from 'stream';
 import { Utils } from '../Utils';
 import { createIfNotExists } from './ActionUtilities';
 import { AzureManager } from './ApiManagers/AzureManager';
-import { ParsedPDF } from './PdfTypes';
 import { AcceptableMedia, Upload } from './SharedMediaTypes';
 import { Directory, clientPathToFile, filesDirectory, pathToDirectory, publicDirectory, serverPathToFile } from './SocketData';
 import { resolvedServerUrl } from './server_Initialization';
 
-const { spawn } = require('child_process');
-const { exec } = require('child_process');
+// eslint-disable-next-line @typescript-eslint/no-var-requires
 const requestImageSize = require('../client/util/request-image-size');
 
 export enum SizeSuffix {
@@ -48,6 +47,7 @@ function usingAzure() {
     return process.env.USE_AZURE === 'true';
 }
 
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace DashUploadUtils {
     export interface Size {
         width: number;
@@ -111,7 +111,7 @@ export namespace DashUploadUtils {
                 // .outputOptions('-c copy')
                 // .videoCodec("copy")
                 .save(outputFilePath)
-                .on('error', (err: any) => {
+                .on('error', err => {
                     console.log(err);
                     reject();
                 })
@@ -130,8 +130,8 @@ export namespace DashUploadUtils {
     }
 
     function resolveExistingFile(name: string, pat: string, directory: Directory, mimetype?: string | null, duration?: number, rawText?: string): Upload.FileResponse<Upload.FileInformation> {
-        const data = { size: 0, filepath: pat, name, type: mimetype ?? '', originalFilename: name, newFilename: path.basename(pat), mimetype: mimetype || null, hashAlgorithm: false as any };
-        const file = { ...data, toJSON: () => ({ ...data, length: 0, filename: data.filepath.replace(/.*\//, ''), mtime: new Date(), mimetype: mimetype || null, toJson: () => undefined as any }) };
+        const data = { size: 0, filepath: pat, name, type: mimetype ?? '', originalFilename: name, newFilename: path.basename(pat), mimetype: mimetype || null, hashAlgorithm: false as falsetype };
+        const file = { ...data, toJSON: () => ({ ...data, length: 0, filename: data.filepath.replace(/.*\//, ''), mtime: new Date(), mimetype: mimetype || null }) };
         return {
             source: file || null,
             result: {
@@ -184,11 +184,10 @@ export namespace DashUploadUtils {
 
     const parseExifData = async (source: string) => {
         const image = await request.get(source, { encoding: null });
-        const { /* data, */ error } = await new Promise<{ data: any; error: any }>(resolve => {
+        const { /* data, */ error } = await new Promise<{ data: ExifData; error: string | undefined }>(resolve => {
             // eslint-disable-next-line no-new
             new ExifImage({ image }, (exifError, data) => {
-                const reason = (exifError as any)?.code;
-                resolve({ data, error: reason });
+                resolve({ data, error: exifError?.message });
             });
         });
         return error ? { data: undefined, error } : { data: await exifr.parse(image), error };
@@ -252,11 +251,12 @@ export namespace DashUploadUtils {
         };
 
         // Use the request library to parse out file level image information in the headers
-        const { headers } = await new Promise<any>((resolve, reject) => {
-            request.head(resolvedUrl, (error, res) => (error ? reject(error) : resolve(res)));
+        const headerResult = await new Promise<{ headers: { [key: string]: string } }>((resolve, reject) => {
+            request.head(resolvedUrl, (error, res) => (error ? reject(error) : resolve(res as { headers: { [key: string]: string } })));
         }).catch(e => {
             console.log('Error processing headers: ', e);
         });
+        const { headers } = headerResult !== null && typeof headerResult === 'object' ? headerResult : { headers: {} as { [key: string]: string } };
 
         try {
             // Compute the native width and height ofthe image with an npm module
@@ -272,9 +272,9 @@ export namespace DashUploadUtils {
                 filename,
                 ...results,
             };
-        } catch (e: any) {
+        } catch (e: unknown) {
             console.log(e);
-            return e;
+            return new Error(e ? e.toString?.() : 'unkown error');
         }
     };
 
@@ -331,7 +331,7 @@ export namespace DashUploadUtils {
         )); // prettier-ignore
 
         return Jimp.read(imgBuffer)
-            .then(async (imgIn: any) => {
+            .then(async imgIn => {
                 let img = imgIn;
                 await Promise.all( sizes.filter(({ width }) => width).map(({ width, suffix }) => {
                     img = img.resize(width, Jimp.AUTO).write(outputPath(suffix));
@@ -339,7 +339,7 @@ export namespace DashUploadUtils {
                 } )); // prettier-ignore
                 return writtenFiles;
             })
-            .catch((e: any) => {
+            .catch(e => {
                 console.log('ERROR' + e);
                 return writtenFiles;
             });
@@ -432,15 +432,17 @@ export namespace DashUploadUtils {
      * 4) the content type of the image, i.e. image/(jpeg | png | ...)
      */
     export const UploadImage = async (source: string, filename?: string, prefix: string = ''): Promise<Upload.ImageInformation | Error> => {
-        const metadata = await InspectImage(source);
-        if (metadata instanceof Error) {
-            return { name: metadata.name, message: metadata.message };
+        const result = await InspectImage(source);
+        if (result instanceof Error) {
+            return { name: result.name, message: result.message };
         }
-        const outputFile = filename || metadata.filename || '';
+        const outputFile = filename || result.filename || '';
 
-        return UploadInspectedImage(metadata, outputFile, prefix);
+        return UploadInspectedImage(result, outputFile, prefix);
     };
 
+    type md5 = 'md5';
+    type falsetype = false;
     export function uploadYoutube(videoId: string, overwriteId: string): Promise<Upload.FileResponse> {
         return new Promise<Upload.FileResponse<Upload.FileInformation>>(res => {
             const name = videoId;
@@ -448,6 +450,7 @@ export namespace DashUploadUtils {
             const finalPath = serverPathToFile(Directory.videos, filepath);
             if (existsSync(finalPath)) {
                 uploadProgress.set(overwriteId, 'computing duration');
+                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                 exec(`yt-dlp -o ${finalPath} "https://www.youtube.com/watch?v=${videoId}" --get-duration`, (error: any, stdout: any /* , stderr: any */) => {
                     const time = Array.from(stdout.trim().split(':')).reverse();
                     const duration = (time.length > 2 ? Number(time[2]) * 1000 * 60 : 0) + (time.length > 1 ? Number(time[1]) * 60 : 0) + (time.length > 0 ? Number(time[0]) : 0);
@@ -457,14 +460,17 @@ export namespace DashUploadUtils {
                 uploadProgress.set(overwriteId, 'starting download');
                 const ytdlp = spawn(`yt-dlp`, ['-o', filepath, `https://www.youtube.com/watch?v=${videoId}`, '--max-filesize', '100M', '-f', 'mp4']);
 
+                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                 ytdlp.stdout.on('data', (data: any) => uploadProgress.set(overwriteId, data.toString()));
 
                 let errors = '';
+                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                 ytdlp.stderr.on('data', (data: any) => {
                     uploadProgress.set(overwriteId, 'error:' + data.toString());
                     errors = data.toString();
                 });
 
+                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                 ytdlp.on('exit', (code: any) => {
                     if (code) {
                         res({
@@ -484,8 +490,8 @@ export namespace DashUploadUtils {
                         exec(`yt-dlp-o ${filepath} "https://www.youtube.com/watch?v=${videoId}" --get-duration`, (/* error: any, stdout: any, stderr: any */) => {
                             // const time = Array.from(stdout.trim().split(':')).reverse();
                             // const duration = (time.length > 2 ? Number(time[2]) * 1000 * 60 : 0) + (time.length > 1 ? Number(time[1]) * 60 : 0) + (time.length > 0 ? Number(time[0]) : 0);
-                            const data = { size: 0, filepath, name, mimetype: 'video', originalFilename: name, newFilename: name, hashAlgorithm: 'md5' as 'md5', type: 'video/mp4' };
-                            const file = { ...data, toJSON: () => ({ ...data, length: 0, filename: data.filepath.replace(/.*\//, ''), mtime: new Date(), toJson: () => undefined as any }) };
+                            const data = { size: 0, filepath, name, mimetype: 'video', originalFilename: name, newFilename: name, hashAlgorithm: 'md5' as md5, type: 'video/mp4' };
+                            const file = { ...data, toJSON: () => ({ ...data, length: 0, filename: data.filepath.replace(/.*\//, ''), mtime: new Date() }) };
                             MoveParsedFile(file, Directory.videos).then(output => res(output));
                         });
                     }
@@ -517,15 +523,15 @@ export namespace DashUploadUtils {
             });
         }
         const dataBuffer = readFileSync(file.filepath);
-        const result: ParsedPDF | any = await parse(dataBuffer).catch((e: any) => e);
-        if (!result.code) {
+        const result: parse.Result = await parse(dataBuffer).catch(e => e);
+        if (result) {
             await new Promise<void>((resolve, reject) => {
                 const writeStream = createWriteStream(serverPathToFile(Directory.text, textFilename));
                 writeStream.write(result?.text, error => (error ? reject(error) : resolve()));
             });
             return MoveParsedFile(file, Directory.pdfs, undefined, result?.text, undefined, fileKey);
         }
-        return { source: file, result: { name: 'faile pdf pupload', message: `Could not upload (${file.originalFilename}).${result.message}` } };
+        return { source: file, result: { name: 'faile pdf pupload', message: `Could not upload (${file.originalFilename}).${result}` } };
     }
 
     async function UploadCsv(file: File) {
@@ -563,7 +569,7 @@ export namespace DashUploadUtils {
                             .videoCodec('copy') // this will copy the data instead of reencode it
                             .save(vidFile.filepath.replace('.mkv', '.mp4'))
                             .on('end', res)
-                            .on('error', (e: any) => console.log(e));
+                            .on('error', console.log);
                     });
                     vidFile.filepath = vidFile.filepath.replace('.mkv', '.mp4');
                     format = '.mp4';
@@ -571,8 +577,9 @@ export namespace DashUploadUtils {
                 if (format.includes('quicktime')) {
                     let abort = false;
                     await new Promise<void>(res => {
-                        ffmpeg.ffprobe(vidFile.filepath, (err: any, metadata: any) => {
-                            if (metadata.streams.some((stream: any) => stream.codec_name === 'hevc')) {
+                        // eslint-disable-next-line @typescript-eslint/no-explicit-any
+                        ffmpeg.ffprobe(vidFile.filepath, (err: any, metadata: ffmpeg.FfprobeData) => {
+                            if (metadata.streams.some(stream => stream.codec_name === 'hevc')) {
                                 abort = true;
                             }
                             res();
diff --git a/src/server/SharedMediaTypes.ts b/src/server/SharedMediaTypes.ts
index 8ae13454e..680db9cd0 100644
--- a/src/server/SharedMediaTypes.ts
+++ b/src/server/SharedMediaTypes.ts
@@ -1,6 +1,7 @@
 import { ExifData } from 'exif';
 import { File } from 'formidable';
 
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace AcceptableMedia {
     export const gifs = ['.gif'];
     export const pngs = ['.png'];
@@ -18,6 +19,7 @@ export enum AudioAnnoState {
     playing = 'playing',
 }
 
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace Upload {
     export function isImageInformation(uploadResponse: Upload.FileInformation): uploadResponse is Upload.ImageInformation {
         return 'nativeWidth' in uploadResponse;
@@ -36,7 +38,7 @@ export namespace Upload {
         duration?: number;
     }
     export interface EnrichedExifData {
-        data: ExifData & ExifData['gps'];
+        data: ExifData & ExifData['gps'] & { Orientation?: string };
         error?: string;
     }
     export interface InspectionResults {
diff --git a/src/server/index.ts b/src/server/index.ts
index 3151c2975..3e0d86814 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -29,7 +29,6 @@ import initializeServer from './server_Initialization';
 
 dotenv.config();
 export const onWindows = process.platform === 'win32';
-// eslint-disable-next-line import/no-mutable-exports
 export let sessionAgent: AppliedSessionAgent;
 
 /**
diff --git a/src/server/websocket.ts b/src/server/websocket.ts
index cece8a1b7..821607df5 100644
--- a/src/server/websocket.ts
+++ b/src/server/websocket.ts
@@ -16,12 +16,11 @@ import YoutubeApi from './apis/youtube/youtubeApiSample';
 import { initializeGuest } from './authentication/DashUserModel';
 import { Database } from './database';
 
+// eslint-disable-next-line @typescript-eslint/no-namespace
 export namespace WebSocket {
     let CurUser: string | undefined;
-    // eslint-disable-next-line import/no-mutable-exports
     export let _socket: Socket;
-    // eslint-disable-next-line import/no-mutable-exports
-    export let _disconnect: Function;
+    export let _disconnect: () => void;
     export const clients: { [key: string]: Client } = {};
 
     function processGesturePoints(socket: Socket, content: GestureContent) {
diff --git a/webpack.config.js b/webpack.config.js
index 58df9a57d..9c74bf24e 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,8 +1,7 @@
-/* eslint-disable node/no-unpublished-require */
+/* eslint-disable @typescript-eslint/no-var-requires */
 const path = require('path');
 const webpack = require('webpack');
 const HtmlWebpackPlugin = require('html-webpack-plugin');
-// eslint-disable-next-line import/no-extraneous-dependencies
 // const ESLintPlugin = require('eslint-webpack-plugin');
 // const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
 const { parsed } = require('dotenv').config();
-- 
cgit v1.2.3-70-g09d2

