From 2a313f28fcb8675223708b0657de7517a3281095 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 17 Apr 2024 12:27:21 -0400
Subject: restoring eslint - updates not complete yet

---
 src/client/views/nodes/RecordingBox/RecordingView.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/client/views/nodes/RecordingBox/RecordingView.tsx')

diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx
index f7ed82643..9c05a3e94 100644
--- a/src/client/views/nodes/RecordingBox/RecordingView.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx
@@ -4,7 +4,7 @@ import { IconContext } from 'react-icons';
 import { FaCheckCircle } from 'react-icons/fa';
 import { MdBackspace } from 'react-icons/md';
 import { Upload } from '../../../../server/SharedMediaTypes';
-import { returnFalse, returnTrue, setupMoveUpEvents } from '../../../../Utils';
+import { returnFalse, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils';
 import { Networking } from '../../../Network';
 import { Presentation, TrackMovements } from '../../../util/TrackMovements';
 import { ProgressBar } from './ProgressBar';
-- 
cgit v1.2.3-70-g09d2


From b1376d401e709515cee078cc08b05fd3fb89caeb Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 24 Apr 2024 18:12:30 -0400
Subject: completing eslint pass

---
 src/client/apis/GoogleAuthenticationManager.tsx    | 119 ++++++------
 .../apis/google_docs/GooglePhotosClientUtils.ts    |   2 +-
 src/client/documents/Documents.ts                  |  37 ++--
 src/client/util/CalendarManager.tsx                |   5 +-
 src/client/util/CaptureManager.tsx                 |  17 +-
 src/client/util/CurrentUserUtils.ts                |  24 +--
 src/client/util/DictationManager.ts                |  63 ++++---
 src/client/util/GroupMemberView.tsx                |  32 ++--
 src/client/util/History.ts                         |  34 ++--
 .../util/Import & Export/ImportMetadataEntry.tsx   |  40 ++--
 src/client/util/KeyCodes.ts                        |   2 +-
 src/client/util/LinkFollower.ts                    |   2 +-
 src/client/util/PingManager.ts                     |   6 +-
 src/client/util/RTFMarkup.tsx                      |  25 +--
 src/client/util/ReplayMovements.ts                 |  22 +--
 src/client/util/ScriptManager.ts                   |  10 +-
 src/client/util/Scripting.ts                       |   4 +-
 src/client/util/SelectionManager.ts                |  16 +-
 src/client/util/ServerStats.tsx                    |  45 +++--
 src/client/util/SharingManager.tsx                 |   5 +-
 src/client/util/TrackMovements.ts                  |  24 +--
 src/client/util/Transform.ts                       |  14 +-
 src/client/util/TypedEvent.ts                      |  18 +-
 src/client/util/bezierFit.ts                       |   6 +-
 .../util/reportManager/ReportManagerComponents.tsx | 131 +++++++------
 .../util/reportManager/reportManagerSchema.ts      |   1 +
 .../util/reportManager/reportManagerUtils.ts       |  17 +-
 src/client/views/animationtimeline/Timeline.tsx    |  60 +++---
 .../views/animationtimeline/TimelineOverview.tsx   |  16 +-
 .../views/collections/CollectionCalendarView.tsx   |  30 ++-
 .../views/collections/CollectionCarouselView.tsx   |   7 +-
 .../views/collections/CollectionDockingView.tsx    |   6 +-
 .../collections/CollectionNoteTakingViewColumn.tsx |  39 ++--
 .../CollectionNoteTakingViewDivider.tsx            |   2 +-
 .../CollectionStackingViewFieldColumn.tsx          |   6 +-
 .../views/collections/CollectionTreeView.tsx       |  21 +--
 src/client/views/collections/KeyRestrictionRow.tsx |  32 +++-
 .../CollectionFreeFormBackgroundGrid.tsx           |   1 +
 .../CollectionFreeFormInfoState.tsx                |  31 ++--
 .../CollectionFreeFormLayoutEngines.tsx            |   8 +-
 .../CollectionFreeFormRemoteCursors.tsx            |  72 ++++----
 .../collectionFreeForm/MarqueeOptionsMenu.tsx      |  12 +-
 .../collectionGrid/CollectionGridView.tsx          |  52 ++++--
 .../collectionLinear/CollectionLinearView.tsx      |   3 +-
 .../views/collections/collectionLinear/index.ts    |   2 +-
 .../CollectionMulticolumnView.tsx                  |  57 ++++--
 .../CollectionMultirowView.tsx                     |  24 ++-
 .../collectionMulticolumn/MulticolumnResizer.tsx   |  24 +--
 .../MulticolumnWidthLabel.tsx                      |   2 +-
 .../collectionMulticolumn/MultirowHeightLabel.tsx  |   3 +-
 .../collectionMulticolumn/MultirowResizer.tsx      |  26 +--
 .../collectionSchema/SchemaColumnHeader.tsx        |  18 +-
 .../collections/collectionSchema/SchemaRowBox.tsx  |  23 +--
 src/client/views/global/globalEnums.tsx            |  52 +++---
 src/client/views/linking/LinkMenuGroup.tsx         |  27 ++-
 src/client/views/linking/LinkMenuItem.tsx          |  10 +-
 .../views/linking/LinkRelationshipSearch.tsx       |  63 -------
 src/client/views/nodes/AudioBox.tsx                |  11 +-
 .../views/nodes/DataVizBox/SchemaCSVPopUp.tsx      |  62 +++----
 .../views/nodes/DataVizBox/components/PieChart.tsx | 197 ++++++++++----------
 src/client/views/nodes/DataVizBox/utils/D3Utils.ts |  29 +--
 src/client/views/nodes/DocumentLinksButton.tsx     |   6 +-
 src/client/views/nodes/EquationBox.tsx             |  11 +-
 src/client/views/nodes/FaceRectangle.tsx           |  10 +-
 .../views/nodes/FontIconBox/ButtonInterface.ts     |   2 +-
 src/client/views/nodes/FontIconBox/TrailsIcon.tsx  |  86 ++++-----
 src/client/views/nodes/LinkAnchorBox.tsx           |   2 +-
 src/client/views/nodes/LinkBox.tsx                 |  83 +++++----
 src/client/views/nodes/LinkDescriptionPopup.tsx    |  33 ++--
 src/client/views/nodes/LinkDocPreview.tsx          |  64 ++++---
 src/client/views/nodes/LoadingBox.tsx              |   4 +-
 .../views/nodes/MapBox/AnimationSpeedIcons.tsx     |  39 ++--
 src/client/views/nodes/MapBox/AnimationUtility.ts  |  57 +++---
 .../views/nodes/MapBox/DirectionsAnchorMenu.tsx    |  11 +-
 src/client/views/nodes/MapBox/GeocoderControl.tsx  |   7 +-
 src/client/views/nodes/MapBox/MapAnchorMenu.tsx    |  99 +++++-----
 src/client/views/nodes/MapBox/MapboxApiUtility.ts  |  76 ++++----
 src/client/views/nodes/MapBox/MarkerIcons.tsx      |   3 +-
 .../views/nodes/MapboxMapBox/MapboxContainer.tsx   |  28 +--
 src/client/views/nodes/RadialMenu.tsx              | 140 +++++---------
 src/client/views/nodes/RadialMenuItem.tsx          |   4 +-
 .../views/nodes/RecordingBox/ProgressBar.tsx       | 205 +++++++++++----------
 .../views/nodes/RecordingBox/RecordingBox.tsx      |  17 +-
 .../views/nodes/RecordingBox/RecordingView.tsx     |  41 ++---
 src/client/views/nodes/RecordingBox/index.ts       |   4 +-
 src/client/views/nodes/ScriptingBox.tsx            | 162 ++++++++--------
 src/client/views/nodes/SliderBox-components.tsx    | 114 ++++++------
 src/client/views/nodes/VideoBox.tsx                |  42 +++--
 src/client/views/nodes/audio/AudioWaveform.tsx     |   8 +-
 src/client/views/nodes/audio/WaveCanvas.tsx        |  12 +-
 src/client/views/nodes/calendarBox/CalendarBox.tsx |   7 +-
 .../nodes/formattedText/DashDocCommentView.tsx     | 159 ++++++++--------
 .../views/nodes/formattedText/DashDocView.tsx      | 123 +++++++------
 .../views/nodes/formattedText/EquationEditor.tsx   |   3 +-
 .../views/nodes/formattedText/EquationView.tsx     |  93 +++++-----
 .../views/nodes/formattedText/FootnoteView.tsx     |   8 +-
 .../formattedText/FormattedTextBoxComment.tsx      |  24 ++-
 .../views/nodes/formattedText/OrderedListView.tsx  |   9 +-
 .../views/nodes/formattedText/ParagraphNodeSpec.ts | 101 +++++-----
 .../views/nodes/formattedText/RichTextRules.ts     |  15 +-
 .../views/nodes/formattedText/SummaryView.tsx      |  24 +--
 .../views/nodes/generativeFill/GenerativeFill.tsx  |  21 ++-
 .../nodes/generativeFill/GenerativeFillButtons.tsx |  10 +-
 .../GenerativeFillMathHelpers.ts                   |   8 +-
 .../generativeFillUtils/ImageHandler.ts            |  36 ++--
 .../generativeFillUtils/PointerHandler.ts          |  18 +-
 .../views/nodes/importBox/ImportElementBox.tsx     |   3 +-
 src/client/views/nodes/trails/index.ts             |   6 +-
 src/client/views/pdf/AnchorMenu.tsx                |  14 +-
 src/mobile/ImageUpload.tsx                         |   3 +-
 110 files changed, 1913 insertions(+), 1891 deletions(-)
 delete mode 100644 src/client/views/linking/LinkRelationshipSearch.tsx

(limited to 'src/client/views/nodes/RecordingBox/RecordingView.tsx')

diff --git a/src/client/apis/GoogleAuthenticationManager.tsx b/src/client/apis/GoogleAuthenticationManager.tsx
index 855f48f7e..5269f763b 100644
--- a/src/client/apis/GoogleAuthenticationManager.tsx
+++ b/src/client/apis/GoogleAuthenticationManager.tsx
@@ -1,14 +1,14 @@
-import { action, IReactionDisposer, observable, reaction, runInAction } from "mobx";
-import { observer } from "mobx-react";
-import * as React from "react";
-import { Opt } from "../../fields/Doc";
-import { Networking } from "../Network";
-import { ScriptingGlobals } from "../util/ScriptingGlobals";
-import { MainViewModal } from "../views/MainViewModal";
-import "./GoogleAuthenticationManager.scss";
+import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import { Opt } from '../../fields/Doc';
+import { Networking } from '../Network';
+import { ScriptingGlobals } from '../util/ScriptingGlobals';
+import { MainViewModal } from '../views/MainViewModal';
+import './GoogleAuthenticationManager.scss';
 
-const AuthenticationUrl = "https://accounts.google.com/o/oauth2/v2/auth";
-const prompt = "Paste authorization code here...";
+const AuthenticationUrl = 'https://accounts.google.com/o/oauth2/v2/auth';
+const prompt = 'Paste authorization code here...';
 
 @observer
 export class GoogleAuthenticationManager extends React.Component<{}> {
@@ -23,11 +23,11 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
     private disposer: Opt<IReactionDisposer>;
 
     private set isOpen(value: boolean) {
-        runInAction(() => this.openState = value);
+        runInAction(() => (this.openState = value));
     }
 
     private set shouldShowPasteTarget(value: boolean) {
-        runInAction(() => this.showPasteTargetState = value);
+        runInAction(() => (this.showPasteTargetState = value));
     }
 
     public cancel() {
@@ -35,7 +35,7 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
     }
 
     public fetchOrGenerateAccessToken = async (displayIfFound = false) => {
-        let response: any = await Networking.FetchFromServer("/readGoogleAccessToken");
+        let response: any = await Networking.FetchFromServer('/readGoogleAccessToken');
         // if this is an authentication url, activate the UI to register the new access token
         if (new RegExp(AuthenticationUrl).test(response)) {
             this.isOpen = true;
@@ -47,7 +47,7 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
                     async authenticationCode => {
                         if (authenticationCode && /\d{1}\/[\w-]{55}/.test(authenticationCode)) {
                             this.disposer?.();
-                            const response = await Networking.PostToServer("/writeGoogleAccessToken", { authenticationCode });
+                            const response = await Networking.PostToServer('/writeGoogleAccessToken', { authenticationCode });
                             runInAction(() => {
                                 this.success = true;
                                 this.credentials = response;
@@ -71,7 +71,7 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
             this.isOpen = true;
         }
         return response.access_token;
-    }
+    };
 
     resetState = action((visibleForMS: number = 3000, fadesOutInMS: number = 500) => {
         if (!visibleForMS && !fadesOutInMS) {
@@ -89,14 +89,20 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
         this.displayLauncher = false;
         this.shouldShowPasteTarget = false;
         if (visibleForMS > 0 && fadesOutInMS > 0) {
-            setTimeout(action(() => {
-                this.isOpen = false;
-                setTimeout(action(() => {
-                    this.success = undefined;
-                    this.displayLauncher = true;
-                    this.credentials = undefined;
-                }), fadesOutInMS);
-            }), visibleForMS);
+            setTimeout(
+                action(() => {
+                    this.isOpen = false;
+                    setTimeout(
+                        action(() => {
+                            this.success = undefined;
+                            this.displayLauncher = true;
+                            this.credentials = undefined;
+                        }),
+                        fadesOutInMS
+                    );
+                }),
+                visibleForMS
+            );
         }
     });
 
@@ -108,61 +114,44 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
     private get renderPrompt() {
         return (
             <div className={'authorize-container'}>
-
-                {this.displayLauncher ? <button
-                    className={"dispatch"}
-                    onClick={() => {
-                        window.open(this.authenticationLink);
-                        setTimeout(() => this.shouldShowPasteTarget = true, 500);
-                    }}
-                    style={{ marginBottom: this.showPasteTargetState ? 15 : 0 }}
-                >Authorize a Google account...</button> : (null)}
-                {this.showPasteTargetState ? <input
-                    className={'paste-target'}
-                    onChange={action(e => this.authenticationCode = e.currentTarget.value)}
-                    placeholder={prompt}
-                /> : (null)}
-                {this.credentials ?
+                {this.displayLauncher ? (
+                    <button
+                        className={'dispatch'}
+                        onClick={() => {
+                            window.open(this.authenticationLink);
+                            setTimeout(() => (this.shouldShowPasteTarget = true), 500);
+                        }}
+                        style={{ marginBottom: this.showPasteTargetState ? 15 : 0 }}>
+                        Authorize a Google account...
+                    </button>
+                ) : null}
+                {this.showPasteTargetState ? <input className={'paste-target'} onChange={action(e => (this.authenticationCode = e.currentTarget.value))} placeholder={prompt} /> : null}
+                {this.credentials ? (
                     <>
-                        <img
-                            className={'avatar'}
-                            src={this.credentials.userInfo.picture}
-                        />
-                        <span
-                            className={'welcome'}
-                        >Welcome to Dash, {this.credentials.userInfo.name}
-                        </span>
+                        <img className={'avatar'} src={this.credentials.userInfo.picture} />
+                        <span className={'welcome'}>Welcome to Dash, {this.credentials.userInfo.name}</span>
                         <div
                             className={'disconnect'}
                             onClick={async () => {
-                                await Networking.FetchFromServer("/revokeGoogleAccessToken");
+                                await Networking.FetchFromServer('/revokeGoogleAccessToken');
                                 this.resetState(0, 0);
-                            }}
-                        >Disconnect Account</div>
-                    </> : (null)}
+                            }}>
+                            Disconnect Account
+                        </div>
+                    </>
+                ) : null}
             </div>
         );
     }
 
     private get dialogueBoxStyle() {
-        const borderColor = this.success === undefined ? "black" : this.success ? "green" : "red";
-        return { borderColor, transition: "0.2s borderColor ease", zIndex: 1002 };
+        const borderColor = this.success === undefined ? 'black' : this.success ? 'green' : 'red';
+        return { borderColor, transition: '0.2s borderColor ease', zIndex: 1002 };
     }
 
     render() {
-        return (
-            <MainViewModal
-                isDisplayed={this.openState}
-                interactive={true}
-                contents={this.renderPrompt}
-                // overlayDisplayedOpacity={0.9}
-                dialogueBoxStyle={this.dialogueBoxStyle}
-                overlayStyle={{ zIndex: 1001 }}
-                closeOnExternalClick={action(() => this.isOpen = false)}
-            />
-        );
+        return <MainViewModal isDisplayed={this.openState} interactive={true} contents={this.renderPrompt} dialogueBoxStyle={this.dialogueBoxStyle} overlayStyle={{ zIndex: 1001 }} closeOnExternalClick={action(() => (this.isOpen = false))} />;
     }
-
 }
 
-ScriptingGlobals.add("GoogleAuthenticationManager", GoogleAuthenticationManager);
\ No newline at end of file
+ScriptingGlobals.add('GoogleAuthenticationManager', GoogleAuthenticationManager);
diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
index 07a2708ec..1eb977813 100644
--- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts
+++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
@@ -291,7 +291,7 @@ export namespace GooglePhotos {
                 response.results.map(
                     item =>
                         new Promise<string>(resolve => {
-                            Query.GetImage(item.mediaItem.id).then(item => resolve(item.baseUrl));
+                            Query.GetImage(item.mediaItem.id).then(itm => resolve(itm.baseUrl));
                         })
                 )
             );
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index f827ea81c..cf397e85a 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1,9 +1,13 @@
+/* eslint-disable prefer-destructuring */
+/* eslint-disable default-param-last */
+/* eslint-disable no-use-before-define */
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { saveAs } from 'file-saver';
 import * as JSZip from 'jszip';
 import { action, reaction, runInAction } from 'mobx';
 import { basename } from 'path';
 import { ClientUtils, OmitKeys } from '../../ClientUtils';
+// eslint-disable-next-line import/extensions
 import * as JSZipUtils from '../../JSZipUtils';
 import { decycle } from '../../decycler/decycler';
 import { DateField } from '../../fields/DateField';
@@ -81,6 +85,7 @@ export enum FInfoFieldType {
     string = 'string',
     boolean = 'boolean',
     number = 'number',
+    // eslint-disable-next-line @typescript-eslint/no-shadow
     Doc = 'Doc',
     enumeration = 'enum',
     date = 'date',
@@ -1360,9 +1365,9 @@ export namespace DocUtils {
         if (key === LinkedTo) {
             // links are not a field value, so handled here.  value is an expression of form ([field=]idToDoc("..."))
             const allLinks = LinkManager.Instance.getAllRelatedLinks(doc);
-            const matchLink = (value: string, anchor: Doc) => {
-                const linkedToExp = (value ?? '').split('=');
-                if (linkedToExp.length === 1) return Field.toScriptString(anchor) === value;
+            const matchLink = (val: string, anchor: Doc) => {
+                const linkedToExp = (val ?? '').split('=');
+                if (linkedToExp.length === 1) return Field.toScriptString(anchor) === val;
                 return Field.toScriptString(DocCast(anchor[linkedToExp[0]])) === linkedToExp[1];
             };
             // prettier-ignore
@@ -1493,17 +1498,17 @@ export namespace DocUtils {
         if (!linkSettings.link_relationship) linkSettings.link_relationship = target.type === DocumentType.RTF ? 'Commentary:Comments On' : 'link';
         if (target.doc === Doc.UserDoc()) return undefined;
 
-        const makeLink = action((linkDoc: Doc, showPopup?: number[]) => {
-            if (showPopup) {
+        const makeLink = action((linkDoc: Doc, showAt?: number[]) => {
+            if (showAt) {
                 LinkManager.Instance.currentLink = linkDoc;
 
                 TaskCompletionBox.textDisplayed = 'Link Created';
-                TaskCompletionBox.popupX = showPopup[0];
-                TaskCompletionBox.popupY = showPopup[1] - 33;
+                TaskCompletionBox.popupX = showAt[0];
+                TaskCompletionBox.popupY = showAt[1] - 33;
                 TaskCompletionBox.taskCompleted = true;
 
-                LinkDescriptionPopup.Instance.popupX = showPopup[0];
-                LinkDescriptionPopup.Instance.popupY = showPopup[1];
+                LinkDescriptionPopup.Instance.popupX = showAt[0];
+                LinkDescriptionPopup.Instance.popupY = showAt[1];
                 LinkDescriptionPopup.Instance.display = true;
 
                 const rect = document.body.getBoundingClientRect();
@@ -1811,7 +1816,7 @@ export namespace DocUtils {
         batch.end();
         return doc;
     }
-    export function findTemplate(templateName: string, type: string, signature: string) {
+    export function findTemplate(templateName: string, type: string) {
         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);
@@ -1841,7 +1846,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), templateSignature);
+        docLayoutTemplate = docLayoutTemplate || findTemplate(templateName, StrCast(doc.isGroup && doc.transcription ? 'transcription' : doc.type));
 
         const customName = 'layout_' + templateSignature;
         const _width = NumCast(doc._width);
@@ -2166,12 +2171,16 @@ export namespace DocUtils {
 
         const docs: { [id: string]: any } = {};
         const links: { [id: string]: any } = {};
-        Array.from(map.entries()).forEach(f => (docs[f[0]] = f[1]));
-        Array.from(linkMap.entries()).forEach(l => (links[l[0]] = l[1]));
+        Array.from(map.entries()).forEach(f => {
+            docs[f[0]] = f[1];
+        });
+        Array.from(linkMap.entries()).forEach(l => {
+            links[l[0]] = l[1];
+        });
         const jsonDocs = JSON.stringify({ id: clone[Id], docs, links }, decycle(replacer));
 
         const zip = new JSZip();
-        var count = 0;
+        let count = 0;
         const promArr = Array.from(proms)
             .filter(url => url?.startsWith('/files'))
             .map(url => url.replace('/', '')); // window.location.origin));
diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
index 46aa4d238..8e3936d34 100644
--- a/src/client/util/CalendarManager.tsx
+++ b/src/client/util/CalendarManager.tsx
@@ -54,7 +54,6 @@ export class CalendarManager extends ObservableReactComponent<{}> {
     @observable private targetDoc: Doc | undefined = undefined; // the target document
     @observable private targetDocView: DocumentView | undefined = undefined; // the DocumentView of the target doc
     @observable private dialogueBoxOpacity = 1; // for the modal
-    @observable private overlayOpacity = 0.4; // for the modal
 
     @observable private layoutDocAcls: boolean = false; // whether the layout doc or data doc's acls are to be used
 
@@ -205,14 +204,12 @@ export class CalendarManager extends ObservableReactComponent<{}> {
                     if (docs.length) {
                         docs.forEach(doc => doc && Doc.BrushDoc(doc));
                         this.dialogueBoxOpacity = 0.1;
-                        this.overlayOpacity = 0.1;
                     }
                 })}
                 onPointerLeave={action(() => {
                     if (docs.length) {
                         docs.forEach(doc => doc && Doc.UnBrushDoc(doc));
                         this.dialogueBoxOpacity = 1;
-                        this.overlayOpacity = 0.4;
                     }
                 })}>
                 {contents}
@@ -352,6 +349,6 @@ export class CalendarManager extends ObservableReactComponent<{}> {
     }
 
     render() {
-        return <MainViewModal contents={this.calendarInterface} isDisplayed={this.isOpen} interactive dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} overlayDisplayedOpacity={this.overlayOpacity} closeOnExternalClick={this.close} />;
+        return <MainViewModal contents={this.calendarInterface} isDisplayed={this.isOpen} interactive dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} closeOnExternalClick={this.close} />;
     }
 }
diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx
index 2939ba581..a03c80f2a 100644
--- a/src/client/util/CaptureManager.tsx
+++ b/src/client/util/CaptureManager.tsx
@@ -1,3 +1,5 @@
+/* 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';
@@ -13,18 +15,22 @@ import { SelectionManager } from './SelectionManager';
 
 @observer
 export class CaptureManager extends React.Component<{}> {
+    // eslint-disable-next-line no-use-before-define
     public static Instance: CaptureManager;
     static _settingsStyle = addStyleSheet();
     @observable _document: any = undefined;
     @observable isOpen: boolean = false; // whether the CaptureManager is to be displayed or not.
 
+    // eslint-disable-next-line react/sort-comp
     constructor(props: {}) {
         super(props);
         makeObservable(this);
         CaptureManager.Instance = this;
     }
 
-    public close = action(() => (this.isOpen = false));
+    public close = action(() => {
+        this.isOpen = false;
+    });
     public open = action((doc: Doc) => {
         this.isOpen = true;
         this._document = doc;
@@ -99,15 +105,15 @@ export class CaptureManager extends React.Component<{}> {
             <div className="capture-interface">
                 <div className="capture-t1">
                     <div className="recordButtonOutline" style={{}}>
-                        <div className="recordButtonInner" style={{}}></div>
+                        <div className="recordButtonInner" style={{}} />
                     </div>
                     Conversation Capture
                 </div>
-                <div className="capture-t2"></div>
+                <div className="capture-t2" />
                 {this.visibilityContent}
                 {this.linksContent}
                 <div className="close-button" onClick={this.close}>
-                    <FontAwesomeIcon icon={'times'} color="black" size={'lg'} />
+                    <FontAwesomeIcon icon="times" color="black" size="lg" />
                 </div>
                 {this.closeButtons}
             </div>
@@ -119,11 +125,10 @@ export class CaptureManager extends React.Component<{}> {
             <MainViewModal
                 contents={this.captureInterface}
                 isDisplayed={this.isOpen}
-                interactive={true}
+                interactive
                 closeOnExternalClick={this.close}
                 dialogueBoxStyle={{ width: '500px', height: '350px', border: 'none', background: 'whitesmoke' }}
                 overlayStyle={{ background: 'black' }}
-                overlayDisplayedOpacity={0.6}
             />
         );
     }
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index acbd0c0b9..65dce34a5 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -67,7 +67,7 @@ export class CurrentUserUtils {
 
     // initializes experimental advanced template views - slideView,  headerView
     static setupUserDocumentCreatorButtons(doc: Doc, userDocTemplates: Opt<Doc>) {
-        const userTemplates = DocListCast(userDocTemplates?.data).filter(doc => !Doc.IsSystem(doc));
+        const userTemplates = DocListCast(userDocTemplates?.data).filter(fdoc => !Doc.IsSystem(fdoc));
         const reqdOpts:DocumentOptions = {
             title: "User Tools", _xMargin: 0, _layout_showTitle: "title", _chromeHidden: true, hidden: false,
             _dragOnlyWithinContainer: true, layout_hideContextMenu: true, isSystem: true, _forceActive: true,
@@ -87,7 +87,7 @@ export class CurrentUserUtils {
             { opts: { title: "Open Detail On Right",  targetScriptKey: "onChildDoubleClick"}, script: `openDoc(this.doubleClickView.${OpenWhere.addRight})`}];
         const reqdClickList = reqdTempOpts.map(opts => {
             const allOpts = {...reqdClickOpts, ...opts.opts};
-            const clickDoc = tempClicks ? DocListCast(tempClicks.data).find(doc => doc.title === opts.opts.title): undefined;
+            const clickDoc = tempClicks ? DocListCast(tempClicks.data).find(fdoc => fdoc.title === opts.opts.title): undefined;
             return DocUtils.AssignOpts(clickDoc, allOpts) ?? Docs.Create.ScriptingDocument(ScriptField.MakeScript(opts.script, allOpts),allOpts);
         });
 
@@ -110,7 +110,7 @@ export class CurrentUserUtils {
         const reqdClickList = reqdTempOpts.map(opts => {
             const title = opts.opts.title?.toString();
             const allOpts = {...reqdClickOpts, ...opts.opts};
-            const clickDoc = tempClicks ? DocListCast(tempClicks.data).find(doc => doc.title === title): undefined;
+            const clickDoc = tempClicks ? DocListCast(tempClicks.data).find(fdoc => fdoc.title === title): undefined;
             const script = ScriptField.MakeScript(opts.script, {heading:Doc.name, checked:"boolean", containingTreeView:Doc.name});
             const scriptDoc = Docs.Create.ScriptingDocument(script, allOpts, title)
             return DocUtils.AssignOpts(clickDoc, allOpts) ?? MakeTemplate(scriptDoc);
@@ -130,7 +130,7 @@ export class CurrentUserUtils {
             { title: "Topic",  backgroundColor: "lightblue", icon: "book-open"  , _layout_showTitle: "title"}];
         const reqdNoteList = [...reqdTempOpts.map(opts => {
             const reqdOpts = {...opts, isSystem:true, width:200, layout_autoHeight: true, layout_fitWidth: true};
-            const noteTemp = tempNotes ? DocListCast(tempNotes.data).find(doc => doc.title === opts.title): undefined;
+            const noteTemp = tempNotes ? DocListCast(tempNotes.data).find(fdoc => fdoc.title === opts.title): undefined;
             return DocUtils.AssignOpts(noteTemp, reqdOpts) ?? MakeTemplate(Docs.Create.TextDocument("",reqdOpts));
         }), ... DocListCast(tempNotes?.data).filter(note => !reqdTempOpts.find(reqd => reqd.title === note.title))];
 
@@ -249,7 +249,7 @@ export class CurrentUserUtils {
                         Docs.Create.TextDocument("", { title: "text", _layout_fitWidth:true,  _height: 100, isSystem: true, _text_fontFamily: StrCast(Doc.UserDoc().fontFamily), _text_fontSize: StrCast(Doc.UserDoc().fontSize) })
                     ], {...opts, title: "Slide View Template"}));
         const plotlyApi = () => {
-            let plotly = Doc.MyPublishedDocs.find(doc => doc.title === "@plotly");
+            let plotly = Doc.MyPublishedDocs.find(fdoc => fdoc.title === "@plotly");
             if (!plotly) {
                 plotly = Docs.Create.TextDocument(
                     `await import("https://cdn.plot.ly/plotly-2.27.0.min.js");
@@ -289,7 +289,7 @@ export class CurrentUserUtils {
             return slide; 
         }
         const mermaidsApi = () => {
-            let mermaids = Doc.MyPublishedDocs.find(doc => doc.title === "@mermaids");
+            let mermaids = Doc.MyPublishedDocs.find(fdoc => fdoc.title === "@mermaids");
             if (!mermaids) {
                 mermaids = Docs.Create.TextDocument(
                 `const mdef = (await import("https://cdn.jsdelivr.net/npm/mermaid@10.8.0/dist/mermaid.esm.min.mjs")).default;
@@ -416,7 +416,7 @@ pie title Minerals in my tap water
     /// Initalizes the "creator" buttons for the sidebar-- eg. the default set of draggable document creation tools
     static setupCreatorButtons(doc: Doc, dragCreatorDoc?:Doc):Doc {
         const creatorBtns = CurrentUserUtils.creatorBtnDescriptors(doc).map((reqdOpts) => {
-            const btn = dragCreatorDoc ? DocListCast(dragCreatorDoc.data).find(doc => doc.title === reqdOpts.title): undefined;
+            const btn = dragCreatorDoc ? DocListCast(dragCreatorDoc.data).find(fdoc => fdoc.title === reqdOpts.title): undefined;
             const opts:DocumentOptions = {...OmitKeys(reqdOpts, ["funcs", "scripts", "backgroundColor"]).omit, 
                 _width: 60, _height: 60, _dragOnlyWithinContainer: true, 
                 btnType: ButtonType.ToolButton, backgroundColor: reqdOpts.backgroundColor ?? Colors.DARK_GRAY, color: Colors.WHITE, isSystem: true,
@@ -460,7 +460,7 @@ pie title Minerals in my tap water
         this.setupLeftSidebarPanel(doc);
         const myLeftSidebarMenu = DocCast(doc[field]);
         const menuBtns = CurrentUserUtils.leftSidebarMenuBtnDescriptions(doc).map(({ title, target, icon, toolTip, hidden, scripts, funcs }) => {
-            const btnDoc = myLeftSidebarMenu ? DocListCast(myLeftSidebarMenu.data).find(doc => doc.title === title) : undefined;
+            const btnDoc = myLeftSidebarMenu ? DocListCast(myLeftSidebarMenu.data).find(fdoc => fdoc.title === title) : undefined;
             const reqdBtnOpts:DocumentOptions = {
                 title, icon, target, toolTip, hidden, btnType: ButtonType.MenuButton, isSystem: true, undoIgnoreFields: new List<string>(['height', 'data_columnHeaders']), dontRegisterView: true,
                 _width: 60, _height: 60,  _dragOnlyWithinContainer: true,
@@ -614,7 +614,7 @@ pie title Minerals in my tap water
     static setupDockedButtons(doc: Doc, field="myDockedBtns") {
         const dockedBtns = DocCast(doc[field]);
         const dockBtn = (opts: DocumentOptions, scripts: {[key:string]:string|undefined}, funcs?: {[key:string]:string}) =>
-            DocUtils.AssignScripts(DocUtils.AssignOpts(DocListCast(dockedBtns?.data)?.find(doc => doc.title === opts.title), opts) ?? 
+            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
@@ -780,7 +780,7 @@ pie title Minerals in my tap water
             childDontRegisterViews: true, flexGap: 0, _height: 30, ignoreClick: !params.scripts?.onClick,
             linearView_SubMenu: true, linearView_Expandable: true, embedContainer: menuDoc};
         
-        const items = (menuBtnDoc?:Doc) => !menuBtnDoc ? [] : subMenu.map(sub => this.setupContextMenuBtn(sub, menuBtnDoc) );
+        const items = (menutBtn?:Doc) => !menutBtn ? [] : subMenu.map(sub => this.setupContextMenuBtn(sub, menutBtn) );
         const creator = params.btnType === ButtonType.MultiToggleButton ? this.multiToggleList : this.linearButtonList;
         const btnDoc = DocUtils.AssignScripts( DocUtils.AssignDocField(menuDoc, StrCast(params.title), 
                 (opts) => creator(opts, items(menuBtnDoc)), reqdSubMenuOpts, items(menuBtnDoc)), params.scripts, params.funcs);
@@ -802,7 +802,7 @@ pie title Minerals in my tap water
         Doc.UserDoc().workspaceReplayingState = undefined;
         const dockedBtns = DocCast(doc[field]);
         const dockBtn = (opts: DocumentOptions, scripts: {[key:string]:string|undefined}, funcs?: {[key:string]:any}) =>
-            DocUtils.AssignScripts(DocUtils.AssignOpts(DocListCast(dockedBtns?.data)?.find(doc => doc.title === opts.title), opts) ?? 
+            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
@@ -964,7 +964,7 @@ pie title Minerals in my tap water
                     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
                 }
-                DocUtils.AssignDocField(infos, pair[0], opts => Doc.assign(new Doc(), OmitKeys(opts,["values"]).omit), opts);
+                DocUtils.AssignDocField(infos, pair[0], docOpts => Doc.assign(new Doc(), OmitKeys(docOpts,["values"]).omit), opts);
             }
         });
     }
diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts
index 207d3ea0b..08fd80882 100644
--- a/src/client/util/DictationManager.ts
+++ b/src/client/util/DictationManager.ts
@@ -1,3 +1,4 @@
+/* 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';
@@ -6,7 +7,7 @@ import { Doc, Opt } from '../../fields/Doc';
 import { List } from '../../fields/List';
 import { RichTextField } from '../../fields/RichTextField';
 import { listSpec } from '../../fields/Schema';
-import { Cast, CastCtor, DocCast } from '../../fields/Types';
+import { Cast, CastCtor } from '../../fields/Types';
 import { AudioField, ImageField } from '../../fields/URLField';
 import { DocumentType } from '../documents/DocumentTypes';
 import { Docs } from '../documents/Documents';
@@ -14,6 +15,7 @@ import { DictationOverlay } from '../views/DictationOverlay';
 import { DocumentView, OpenWhere } from '../views/nodes/DocumentView';
 import { SelectionManager } from './SelectionManager';
 import { UndoManager } from './UndoManager';
+import { DocData } from '../../fields/DocSymbols';
 
 /**
  * This namespace provides a singleton instance of a manager that
@@ -64,9 +66,10 @@ export namespace DictationManager {
         export let isListening = false;
         let isManuallyStopped = false;
 
-        let current: string | undefined = undefined;
+        let current: string | undefined;
         let sessionResults: string[] = [];
 
+        // eslint-disable-next-line new-cap
         const recognizer: Opt<SpeechRecognition> = webkitSpeechRecognition ? new webkitSpeechRecognition() : undefined;
 
         export type InterimResultHandler = (results: string) => any;
@@ -87,7 +90,7 @@ export namespace DictationManager {
         let pendingListen: Promise<string> | string | undefined;
 
         export const listen = async (options?: Partial<ListeningOptions>) => {
-            if (pendingListen instanceof Promise) return pendingListen.then(pl => innerListen(options));
+            if (pendingListen instanceof Promise) return pendingListen.then(() => innerListen(options));
             return innerListen(options);
         };
         const innerListen = async (options?: Partial<ListeningOptions>) => {
@@ -150,29 +153,29 @@ export namespace DictationManager {
 
             recognizer.start();
 
-            return new Promise<string>((resolve, reject) => {
+            return new Promise<string>(resolve => {
                 recognizer.onerror = (e: any) => {
                     // e is SpeechRecognitionError but where is that defined?
                     if (!(indefinite && e.error === 'no-speech')) {
                         recognizer.stop();
                         resolve(e);
-                        //reject(e);
                     }
                 };
 
                 recognizer.onresult = (e: SpeechRecognitionEvent) => {
                     current = synthesize(e, intra);
-                    let matchedTerminator: string | undefined;
-                    if (options?.terminators && (matchedTerminator = options.terminators.find(end => (current ? current.trim().toLowerCase().endsWith(end.toLowerCase()) : false)))) {
+                    const matchedTerminator = options?.terminators?.find(end => (current ? current.trim().toLowerCase().endsWith(end.toLowerCase()) : false));
+                    if (options?.terminators && matchedTerminator) {
                         current = matchedTerminator;
                         recognizer.abort();
                         return complete();
                     }
                     !isManuallyStopped && handler?.(current);
-                    //isManuallyStopped && complete();
+                    // isManuallyStopped && complete()
+                    return undefined;
                 };
 
-                recognizer.onend = (e: Event) => {
+                recognizer.onend = () => {
                     if (!indefinite || isManuallyStopped) {
                         return complete();
                     }
@@ -182,6 +185,7 @@ export namespace DictationManager {
                         current = undefined;
                     }
                     recognizer.start();
+                    return undefined;
                 };
 
                 const complete = () => {
@@ -202,7 +206,7 @@ export namespace DictationManager {
             });
         };
 
-        export const stop = (salvageSession = true) => {
+        export const stop = (/* salvageSession = true */) => {
             if (!isListening || !recognizer) {
                 return;
             }
@@ -212,7 +216,7 @@ export namespace DictationManager {
         };
 
         const synthesize = (e: SpeechRecognitionEvent, delimiter?: string) => {
-            const results = e.results;
+            const { results } = e;
             const transcripts: string[] = [];
             for (let i = 0; i < results.length; i++) {
                 transcripts.push(results.item(i).item(0).transcript.trim());
@@ -233,22 +237,25 @@ export namespace DictationManager {
         export const RegisterIndependent = (key: string, value: IndependentEntry) => Independent.set(key, value);
         export const RegisterDependent = (entry: DependentEntry) => Dependent.push(entry);
 
-        export const execute = async (phrase: string) => {
-            return UndoManager.RunInBatch(async () => {
+        export const execute = async (phrase: string) =>
+            UndoManager.RunInBatch(async () => {
                 console.log('PHRASE: ' + phrase);
                 const targets = SelectionManager.Views;
                 if (!targets || !targets.length) {
-                    return;
+                    return undefined;
                 }
 
+                // eslint-disable-next-line no-param-reassign
                 phrase = phrase.toLowerCase();
                 const entry = Independent.get(phrase);
 
                 if (entry) {
                     let success = false;
-                    const restrictTo = entry.restrictTo;
+                    const { restrictTo } = entry;
+                    // eslint-disable-next-line no-restricted-syntax
                     for (const target of targets) {
                         if (!restrictTo || validate(target, restrictTo)) {
+                            // eslint-disable-next-line no-await-in-loop
                             await entry.action(target);
                             success = true;
                         }
@@ -256,16 +263,19 @@ export namespace DictationManager {
                     return success;
                 }
 
-                for (const entry of Dependent) {
-                    const regex = entry.expression;
+                // eslint-disable-next-line no-restricted-syntax
+                for (const depEntry of Dependent) {
+                    const regex = depEntry.expression;
                     const matches = regex.exec(phrase);
                     regex.lastIndex = 0;
                     if (matches !== null) {
                         let success = false;
-                        const restrictTo = entry.restrictTo;
+                        const { restrictTo } = depEntry;
+                        // eslint-disable-next-line no-restricted-syntax
                         for (const target of targets) {
                             if (!restrictTo || validate(target, restrictTo)) {
-                                await entry.action(target, matches);
+                                // eslint-disable-next-line no-await-in-loop
+                                await depEntry.action(target, matches);
                                 success = true;
                             }
                         }
@@ -275,7 +285,6 @@ export namespace DictationManager {
 
                 return false;
             }, 'Execute Command');
-        };
 
         const ConstructorMap = new Map<DocumentType, CastCtor>([
             [DocumentType.COL, listSpec(Doc)],
@@ -294,6 +303,7 @@ export namespace DictationManager {
         };
 
         const validate = (target: DocumentView, types: DocumentType[]) => {
+            // eslint-disable-next-line no-restricted-syntax
             for (const type of types) {
                 if (tryCast(target, type)) {
                     return true;
@@ -318,7 +328,9 @@ export namespace DictationManager {
             [
                 'clear',
                 {
-                    action: (target: DocumentView) => (Doc.GetProto(target.Document).data = new List()),
+                    action: (target: DocumentView) => {
+                        Doc.GetProto(target.Document).data = new List();
+                    },
                     restrictTo: [DocumentType.COL],
                 },
             ],
@@ -328,7 +340,7 @@ export namespace DictationManager {
                 {
                     action: (target: DocumentView) => {
                         const newBox = Docs.Create.TextDocument('', { _width: 400, _height: 200, title: 'My Outline', _layout_autoHeight: true });
-                        const proto = DocCast(newBox.proto);
+                        const proto = newBox[DocData];
                         const prompt = 'Press alt + r to start dictating here...';
                         const head = 3;
                         const anchor = head + prompt.length;
@@ -341,7 +353,7 @@ export namespace DictationManager {
             ],
         ]);
 
-        const Dependent = new Array<DependentEntry>(
+        const Dependent = [
             {
                 expression: /create (\w+) documents of type (image|nested collection)/g,
                 action: (target: DocumentView, matches: RegExpExecArray) => {
@@ -361,6 +373,7 @@ export namespace DictationManager {
                             case 'nested collection':
                                 created = Docs.Create.FreeformDocument([], {});
                                 break;
+                            default:
                         }
                         created && Doc.AddDocToList(dataDoc, fieldKey, created);
                     }
@@ -375,7 +388,7 @@ export namespace DictationManager {
                     mode && (target.Document._type_collection = mode);
                 },
                 restrictTo: [DocumentType.COL],
-            }
-        );
+            },
+        ];
     }
 }
diff --git a/src/client/util/GroupMemberView.tsx b/src/client/util/GroupMemberView.tsx
index 894583711..c703c3f98 100644
--- a/src/client/util/GroupMemberView.tsx
+++ b/src/client/util/GroupMemberView.tsx
@@ -1,4 +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 { Button, IconButton, Size, Type } from 'browndash-components';
 import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -8,7 +11,6 @@ import { StrCast } from '../../fields/Types';
 import { MainViewModal } from '../views/MainViewModal';
 import { GroupManager, UserOptions } from './GroupManager';
 import './GroupMemberView.scss';
-import { Button, IconButton, Size, Type } from 'browndash-components';
 import { SettingsManager } from './SettingsManager';
 
 interface GroupMemberViewProps {
@@ -38,20 +40,23 @@ export class GroupMemberView extends React.Component<GroupMemberViewProps> {
                         className="group-title"
                         style={{ marginLeft: !hasEditAccess ? '-14%' : 0 }}
                         value={StrCast(this.group.title || this.group.groupName)}
-                        onChange={e => (this.group.title = e.currentTarget.value)}
-                        disabled={!hasEditAccess}></input>
-                    <div className={'memberView-closeButton'}>
-                        <Button icon={<FontAwesomeIcon icon={'times'} size={'lg'} />} onClick={action(this.props.onCloseButtonClick)} color={StrCast(Doc.UserDoc().userColor)} />
+                        onChange={e => {
+                            this.group.title = e.currentTarget.value;
+                        }}
+                        disabled={!hasEditAccess}
+                    />
+                    <div className="memberView-closeButton">
+                        <Button icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={action(this.props.onCloseButtonClick)} color={StrCast(Doc.UserDoc().userColor)} />
                     </div>
                     {GroupManager.Instance.hasEditAccess(this.group) ? (
                         <div className="group-buttons">
                             <div style={{ border: StrCast(Doc.UserDoc().userColor) }}>
                                 <Select
                                     className="add-member-dropdown"
-                                    isSearchable={true}
+                                    isSearchable
                                     options={options}
                                     onChange={selectedOption => GroupManager.Instance.addMemberToGroup(this.group, (selectedOption as UserOptions).value)}
-                                    placeholder={'Add members'}
+                                    placeholder="Add members"
                                     value={null}
                                     styles={{
                                         control: () => ({
@@ -80,7 +85,12 @@ export class GroupMemberView extends React.Component<GroupMemberViewProps> {
                             </div>
                         </div>
                     ) : null}
-                    <div className="sort-emails" style={{ paddingTop: hasEditAccess ? 0 : 35 }} onClick={action(() => (this.memberSort = this.memberSort === 'ascending' ? 'descending' : this.memberSort === 'descending' ? 'none' : 'ascending'))}>
+                    <div
+                        className="sort-emails"
+                        style={{ paddingTop: hasEditAccess ? 0 : 35 }}
+                        onClick={action(() => {
+                            this.memberSort = this.memberSort === 'ascending' ? 'descending' : this.memberSort === 'descending' ? 'none' : 'ascending';
+                        })}>
                         Emails {this.memberSort === 'ascending' ? '↑' : this.memberSort === 'descending' ? '↓' : ''} {/* → */}
                     </div>
                 </div>
@@ -90,8 +100,8 @@ export class GroupMemberView extends React.Component<GroupMemberViewProps> {
                         <div className="editing-row" key={member}>
                             <div className="user-email">{member}</div>
                             {hasEditAccess ? (
-                                <div className={'remove-button'} onClick={() => GroupManager.Instance.removeMemberFromGroup(this.group, member)}>
-                                    <IconButton icon={<FontAwesomeIcon icon={'trash-alt'} />} size={Size.XSMALL} color={StrCast(Doc.UserDoc().userColor)} onClick={() => GroupManager.Instance.removeMemberFromGroup(this.group, member)} />
+                                <div className="remove-button" onClick={() => GroupManager.Instance.removeMemberFromGroup(this.group, member)}>
+                                    <IconButton icon={<FontAwesomeIcon icon="trash-alt" />} size={Size.XSMALL} color={StrCast(Doc.UserDoc().userColor)} onClick={() => GroupManager.Instance.removeMemberFromGroup(this.group, member)} />
                                 </div>
                             ) : null}
                         </div>
@@ -102,6 +112,6 @@ export class GroupMemberView extends React.Component<GroupMemberViewProps> {
     }
 
     render() {
-        return <MainViewModal isDisplayed={true} interactive={true} contents={this.editingInterface} dialogueBoxStyle={{ width: 400, height: 250 }} closeOnExternalClick={this.props.onCloseButtonClick} />;
+        return <MainViewModal isDisplayed interactive contents={this.editingInterface} dialogueBoxStyle={{ width: 400, height: 250 }} closeOnExternalClick={this.props.onCloseButtonClick} />;
     }
 }
diff --git a/src/client/util/History.ts b/src/client/util/History.ts
index b500a5af9..52d0223d5 100644
--- a/src/client/util/History.ts
+++ b/src/client/util/History.ts
@@ -1,3 +1,9 @@
+/* eslint-disable no-use-before-define */
+/* eslint-disable no-empty */
+/* eslint-disable no-continue */
+/* eslint-disable guard-for-in */
+/* eslint-disable no-restricted-syntax */
+/* eslint-disable no-param-reassign */
 import * as qs from 'query-string';
 import { Doc } from '../../fields/Doc';
 import { OmitKeys, ClientUtils } from '../../ClientUtils';
@@ -32,6 +38,7 @@ export namespace HistoryUtil {
                     case 'doc':
                         onDocUrl(url);
                         break;
+                    default:
                 }
             }
         }
@@ -124,11 +131,11 @@ export namespace HistoryUtil {
                 const val = customParser(pathname, opts, current);
                 if (val === null) {
                     return undefined;
-                } else if (val === undefined) {
+                }
+                if (val === undefined) {
                     return current;
-                } else {
-                    return val;
                 }
+                return val;
             }
             return current;
         };
@@ -142,26 +149,27 @@ export namespace HistoryUtil {
             }
             const queryObj = OmitKeys(state, keys).extract;
             const query: any = {};
-            Object.keys(queryObj).forEach(key => (query[key] = queryObj[key] === null ? null : JSON.stringify(queryObj[key])));
+            Object.keys(queryObj).forEach(key => {
+                query[key] = queryObj[key] === null ? null : JSON.stringify(queryObj[key]);
+            });
             const queryString = qs.stringify(query);
             return path + (queryString ? `?${queryString}` : '');
         };
     }
 
     addParser('doc', {}, { readonly: true, initializers: true, nro: true, sharing: true }, (pathname, opts, current) => {
-        if (pathname.length !== 2) return undefined;
-
-        current.initializers = current.initializers || {};
-        const docId = pathname[1];
-        current.docId = docId;
-    });
-    addStringifier('doc', ['initializers', 'readonly', 'nro'], (state, current) => {
-        return `${current}/${state.docId}`;
+        if (pathname.length === 2) {
+            current.initializers = current.initializers || {};
+            const docId = pathname[1];
+            current.docId = docId;
+        }
+        return undefined;
     });
+    addStringifier('doc', ['initializers', 'readonly', 'nro'], (state, current) => `${current}/${state.docId}`);
 
     export function parseUrl(location: Location | URL): ParsedUrl | undefined {
         const pathname = location.pathname.substring(1);
-        const search = location.search;
+        const { search } = location;
         const opts = search.length ? qs.parse(search, { sort: false }) : {};
         const pathnameSplit = pathname.split('/');
 
diff --git a/src/client/util/Import & Export/ImportMetadataEntry.tsx b/src/client/util/Import & Export/ImportMetadataEntry.tsx
index 58a09b9c9..db1e3d6cd 100644
--- a/src/client/util/Import & Export/ImportMetadataEntry.tsx	
+++ b/src/client/util/Import & Export/ImportMetadataEntry.tsx	
@@ -1,10 +1,13 @@
-import * as React from 'react';
-import { observer } from 'mobx-react';
-import { EditableView } from '../../views/EditableView';
-import { action, computed } from 'mobx';
+/* 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';
+import { observer } from 'mobx-react';
+import * as React from 'react';
 import { Doc } from '../../../fields/Doc';
-import { StrCast, BoolCast } from '../../../fields/Types';
+import { BoolCast, StrCast } from '../../../fields/Types';
+import { EditableView } from '../../views/EditableView';
 
 interface KeyValueProps {
     Document: Doc;
@@ -93,18 +96,27 @@ export default class ImportMetadataEntry extends React.Component<KeyValueProps>
                     alignItems: 'center',
                     alignContent: 'center',
                 }}>
-                <input onChange={e => (this.onDataDoc = e.target.checked)} ref={this.checkRef} style={{ margin: '0 10px 0 15px' }} type="checkbox" title={'Add to Data Document?'} checked={this.onDataDoc} />
-                <div className={'key_container'} style={keyValueStyle}>
-                    <EditableView ref={this.keyRef} contents={this.key} SetValue={this.updateKey} GetValue={() => ''} oneLine={true} />
+                <input
+                    onChange={e => {
+                        this.onDataDoc = e.target.checked;
+                    }}
+                    ref={this.checkRef}
+                    style={{ margin: '0 10px 0 15px' }}
+                    type="checkbox"
+                    title="Add to Data Document?"
+                    checked={this.onDataDoc}
+                />
+                <div className="key_container" style={keyValueStyle}>
+                    <EditableView ref={this.keyRef} contents={this.key} SetValue={this.updateKey} GetValue={() => ''} oneLine />
                 </div>
-                <div className={'value_container'} style={keyValueStyle}>
-                    <EditableView ref={this.valueRef} contents={this.value} SetValue={this.updateValue} GetValue={() => ''} oneLine={true} />
+                <div className="value_container" style={keyValueStyle}>
+                    <EditableView ref={this.valueRef} contents={this.value} SetValue={this.updateValue} GetValue={() => ''} oneLine />
                 </div>
-                <div onClick={() => this.props.remove(this)} title={'Delete Entry'}>
+                <div onClick={() => this.props.remove(this)} title="Delete Entry">
                     <FontAwesomeIcon
-                        icon={'plus'}
-                        color={'red'}
-                        size={'1x'}
+                        icon="plus"
+                        color="red"
+                        size="1x"
                         style={{
                             marginLeft: 15,
                             marginRight: 15,
diff --git a/src/client/util/KeyCodes.ts b/src/client/util/KeyCodes.ts
index de2457a5a..fb21f78ee 100644
--- a/src/client/util/KeyCodes.ts
+++ b/src/client/util/KeyCodes.ts
@@ -133,4 +133,4 @@ export class KeyCodes {
     public static NUM_9: number = 57;
     public static SUBTRACT: number = 189;
     public static ADD: number = 187;
-}
\ No newline at end of file
+}
diff --git a/src/client/util/LinkFollower.ts b/src/client/util/LinkFollower.ts
index 85bada8c9..09262f5ac 100644
--- a/src/client/util/LinkFollower.ts
+++ b/src/client/util/LinkFollower.ts
@@ -44,7 +44,7 @@ export class LinkFollower {
 
     public static traverseLink(link: Opt<Doc>, sourceDoc: Doc, finished?: () => void, traverseBacklink?: boolean) {
         const getView = (doc: Doc) => DocumentManager.Instance.getFirstDocumentView(DocCast(doc.layout_unrendered ? doc.annotationOn : doc));
-        const isAnchor = (sourceDoc: Doc, anchor: Doc) => Doc.AreProtosEqual(anchor, sourceDoc) || Doc.AreProtosEqual(anchor.annotationOn as Doc, sourceDoc);
+        const isAnchor = (source: Doc, anchor: Doc) => Doc.AreProtosEqual(anchor, source) || Doc.AreProtosEqual(anchor.annotationOn as Doc, source);
         const linkDocs = link ? [link] : LinkManager.Links(sourceDoc);
         const fwdLinks = linkDocs.filter(l => isAnchor(sourceDoc, l.link_anchor_1 as Doc)); // link docs where 'sourceDoc' is link_anchor_1
         const backLinks = linkDocs.filter(l => isAnchor(sourceDoc, l.link_anchor_2 as Doc)); // link docs where 'sourceDoc' is link_anchor_2
diff --git a/src/client/util/PingManager.ts b/src/client/util/PingManager.ts
index 7638e2ce0..e5e69c5ac 100644
--- a/src/client/util/PingManager.ts
+++ b/src/client/util/PingManager.ts
@@ -1,8 +1,10 @@
 import { action, makeObservable, observable, runInAction } from 'mobx';
 import { Networking } from '../Network';
 import { CurrentUserUtils } from './CurrentUserUtils';
+
 export class PingManager {
     // create static instance and getter for global use
+    // eslint-disable-next-line no-use-before-define
     @observable static _instance: PingManager;
     @observable IsBeating = true;
     static get Instance(): PingManager {
@@ -29,7 +31,9 @@ export class PingManager {
     sendPing = async (): Promise<void> => {
         try {
             const res = await Networking.PostToServer('/ping', { date: new Date() });
-            runInAction(() => (CurrentUserUtils.ServerVersion = res.message));
+            runInAction(() => {
+                CurrentUserUtils.ServerVersion = res.message;
+            });
             !this.IsBeating && this.setIsBeating(true);
         } catch {
             if (this.IsBeating) {
diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx
index 35b1579df..05fb849fd 100644
--- a/src/client/util/RTFMarkup.tsx
+++ b/src/client/util/RTFMarkup.tsx
@@ -6,23 +6,16 @@ import { SettingsManager } from './SettingsManager';
 
 @observer
 export class RTFMarkup extends React.Component<{}> {
+    // eslint-disable-next-line no-use-before-define
     static Instance: RTFMarkup;
     @observable private isOpen = false; // whether the SharingManager modal is open or not
 
-    @action
-    public open = () => (this.isOpen = true);
-
-    @action
-    public close = () => (this.isOpen = false);
-
     constructor(props: {}) {
         super(props);
         makeObservable(this);
         RTFMarkup.Instance = this;
     }
 
-    @observable _stats: { [key: string]: any } | undefined = undefined;
-
     /**
      * @returns the main interface of the SharingManager.
      */
@@ -30,11 +23,11 @@ export class RTFMarkup extends React.Component<{}> {
         return (
             <div style={{ background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor, textAlign: 'initial', height: '100%' }}>
                 <p>
-                    <b style={{ fontSize: 'larger' }}>{`(@wiki:phrase)`}</b>
+                    <b style={{ fontSize: 'larger' }}>(@wiki:phrase)</b>
                     {` display wikipedia page for entered text (terminate with carriage return)`}
                 </p>
                 <p>
-                    <b style={{ fontSize: 'larger' }}>{`(( any text ))`}</b>
+                    <b style={{ fontSize: 'larger' }}>(( any text ))</b>
                     {` submit text to Chat GPT to have results appended afterward`}
                 </p>
                 <p>
@@ -129,13 +122,23 @@ export class RTFMarkup extends React.Component<{}> {
         );
     }
 
+    @action
+    public open = () => {
+        this.isOpen = true;
+    };
+
+    @action
+    public close = () => {
+        this.isOpen = false;
+    };
+
     render() {
         return (
             <MainViewModal
                 dialogueBoxStyle={{ backgroundColor: SettingsManager.userBackgroundColor, alignContent: 'normal', color: SettingsManager.userColor, padding: '16px' }}
                 contents={this.cheatSheet}
                 isDisplayed={this.isOpen}
-                interactive={true}
+                interactive
                 closeOnExternalClick={this.close}
             />
         );
diff --git a/src/client/util/ReplayMovements.ts b/src/client/util/ReplayMovements.ts
index b881f18b4..2c8fdf483 100644
--- a/src/client/util/ReplayMovements.ts
+++ b/src/client/util/ReplayMovements.ts
@@ -14,6 +14,7 @@ export class ReplayMovements {
     private isPlaying: boolean;
 
     // create static instance and getter for global use
+    // eslint-disable-next-line no-use-before-define
     @observable static _instance: ReplayMovements;
     static get Instance(): ReplayMovements {
         return ReplayMovements._instance;
@@ -90,7 +91,7 @@ export class ReplayMovements {
     loadPresentation = (presentation: Presentation) => {
         const { movements } = presentation;
         if (movements === null) {
-            throw '[recordingApi.ts] followMovements() failed: no presentation data';
+            throw new Error('[recordingApi.ts] followMovements() failed: no presentation data');
         }
 
         movements.forEach((movement, i) => {
@@ -106,9 +107,7 @@ export class ReplayMovements {
     // returns undefined if the docView isn't open on the screen
     getCollectionFFView = (doc: Doc) => {
         const isInView = DocumentManager.Instance.getDocumentView(doc);
-        if (isInView) {
-            return isInView.ComponentView as CollectionFreeFormView;
-        }
+        return isInView?.ComponentView as CollectionFreeFormView;
     };
 
     // will open the doc in a tab then return the CollectionFFView that holds it
@@ -136,9 +135,9 @@ export class ReplayMovements {
         if (movements === null) return new Map();
         // generate a set of all unique docIds
         const docIdtoFirstMove = new Map<Doc, Movement>();
-        for (const move of movements) {
+        movements.forEach(move => {
             if (!docIdtoFirstMove.has(move.doc)) docIdtoFirstMove.set(move.doc, move);
-        }
+        });
         return docIdtoFirstMove;
     };
 
@@ -151,10 +150,10 @@ export class ReplayMovements {
         // console.info('playMovements', presentation, timeViewed, docIdtoDoc);
 
         if (presentation.movements === null || presentation.movements.length === 0) {
-            //|| this.playFFView === null) {
-            return new Error('[recordingApi.ts] followMovements() failed: no presentation data');
+            // || this.playFFView === null) {
+            return '[recordingApi.ts] followMovements() failed: no presentation data';
         }
-        if (this.isPlaying) return;
+        if (this.isPlaying) return undefined;
 
         this.isPlaying = true;
         Doc.UserDoc().presentationMode = 'watching';
@@ -170,10 +169,10 @@ export class ReplayMovements {
 
             // for the open tabs, set it to the first move
             const docIdtoFirstMove = this.getFirstMovements(filteredMovements);
-            for (const [doc, firstMove] of docIdtoFirstMove) {
+            Array.from(docIdtoFirstMove).forEach(([doc, firstMove]) => {
                 const colFFView = this.getCollectionFFView(doc);
                 if (colFFView) this.zoomAndPan(firstMove, colFFView);
-            }
+            });
         };
         handleFirstMovements();
 
@@ -197,5 +196,6 @@ export class ReplayMovements {
                 }
             }, timeDiff);
         });
+        return undefined;
     };
 }
diff --git a/src/client/util/ScriptManager.ts b/src/client/util/ScriptManager.ts
index 87509f2ea..9158f6c0b 100644
--- a/src/client/util/ScriptManager.ts
+++ b/src/client/util/ScriptManager.ts
@@ -7,8 +7,10 @@ import { ScriptingGlobals } from './ScriptingGlobals';
 
 export class ScriptManager {
     static _initialized = false;
+    // eslint-disable-next-line no-use-before-define
     private static _instance: ScriptManager;
     public static get Instance(): ScriptManager {
+        // eslint-disable-next-line no-return-assign
         return this._instance || (this._instance = new this());
     }
     private constructor() {
@@ -58,14 +60,16 @@ export class ScriptManager {
 
         const params = Cast(scriptDoc['data-params'], listSpec('string'), []);
         const paramNames = params.reduce((o: string, p: string) => {
+            let out = o;
             if (params.indexOf(p) === params.length - 1) {
-                o = o + p.split(':')[0].trim();
+                out += p.split(':')[0].trim();
             } else {
-                o = o + p.split(':')[0].trim() + ',';
+                out += p.split(':')[0].trim() + ',';
             }
-            return o;
+            return out;
         }, '' as string);
 
+        // eslint-disable-next-line no-new-func
         const f = new Function(paramNames, StrCast(scriptDoc.script));
 
         Object.defineProperty(f, 'name', { value: StrCast(scriptDoc.name), writable: false });
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index de5e8b92e..f7d7ba6a4 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -124,7 +124,7 @@ class ScriptingCompilerHost {
         return 'node_modules/typescript/lib/lib.d.ts'; // No idea what this means...
     }
     writeFile(fileName: string, content: string) {
-        const file = this.files.find(file => file.fileName === fileName);
+        const file = this.files.find(f => f.fileName === fileName);
         if (file) {
             file.content = content;
         } else {
@@ -147,7 +147,7 @@ class ScriptingCompilerHost {
         return this.files.some(file => file.fileName === fileName);
     }
     readFile(fileName: string): string | undefined {
-        const file = this.files.find(file => file.fileName === fileName);
+        const file = this.files.find(f => f.fileName === fileName);
         if (file) {
             return file.content;
         }
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 36b926053..1328e90e9 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -11,6 +11,7 @@ import { ScriptingGlobals } from './ScriptingGlobals';
 import { UndoManager } from './UndoManager';
 
 export class SelectionManager {
+    // eslint-disable-next-line no-use-before-define
     private static _manager: SelectionManager;
     private static get Instance() {
         return SelectionManager._manager ?? new SelectionManager();
@@ -61,7 +62,9 @@ export class SelectionManager {
             dv.IsSelected = false;
             dv._props.whenChildContentsActiveChanged(false);
         });
-        runInAction(() => (this.Instance.SelectedViews.length = 0));
+        runInAction(() => {
+            this.Instance.SelectedViews.length = 0;
+        });
         if (found) this.SelectView(found, false);
     };
 
@@ -71,17 +74,20 @@ export class SelectionManager {
     public static get Docs() { return this.Instance.SelectedViews.map(dv => dv.Document).filter(doc => doc?._type_collection !== CollectionViewType.Docking); } // prettier-ignore
 }
 
+// eslint-disable-next-line prefer-arrow-callback
 ScriptingGlobals.add(function SelectionManager_selectedDocType(type: string, expertMode: boolean, checkContext?: boolean) {
     if (Doc.noviceMode && expertMode) return false;
     if (type === 'tab') {
         return SelectionManager.Views.lastElement()?._props.renderDepth === 0;
     }
-    let selected = (sel => (checkContext ? DocCast(sel?.embedContainer) : sel))(SelectionManager.SelectedSchemaDoc ?? SelectionManager.Docs.lastElement());
+    const selected = (sel => (checkContext ? DocCast(sel?.embedContainer) : sel))(SelectionManager.SelectedSchemaDoc ?? SelectionManager.Docs.lastElement());
     return selected?.type === type || selected?.type_collection === type || !type;
 });
+// eslint-disable-next-line prefer-arrow-callback
 ScriptingGlobals.add(function deselectAll() {
     SelectionManager.DeselectAll();
 });
+// eslint-disable-next-line prefer-arrow-callback
 ScriptingGlobals.add(function undo() {
     SelectionManager.DeselectAll();
     return UndoManager.Undo();
@@ -89,17 +95,19 @@ ScriptingGlobals.add(function undo() {
 
 export function ShowUndoStack() {
     SelectionManager.DeselectAll();
-    var buffer = '';
+    let buffer = '';
     UndoManager.undoStack.forEach((batch, i) => {
         buffer += 'Batch => ' + UndoManager.undoStackNames[i] + '\n';
-        ///batch.forEach(undo => (buffer += '   ' + undo.prop + '\n'));
+        // /batch.forEach(undo => (buffer += '   ' + undo.prop + '\n'));
     });
     alert(buffer);
 }
+// eslint-disable-next-line prefer-arrow-callback
 ScriptingGlobals.add(function redo() {
     SelectionManager.DeselectAll();
     return UndoManager.Redo();
 });
+// eslint-disable-next-line prefer-arrow-callback
 ScriptingGlobals.add(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) {
     const docs = SelectionManager.Views.map(dv => dv.Document).filter(
         d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.KVP && (!excludeCollections || d.type !== DocumentType.COL || !Cast(d.data, listSpec(Doc), null))
diff --git a/src/client/util/ServerStats.tsx b/src/client/util/ServerStats.tsx
index c8df9182d..891561245 100644
--- a/src/client/util/ServerStats.tsx
+++ b/src/client/util/ServerStats.tsx
@@ -1,44 +1,28 @@
-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 { MainViewModal } from '../views/MainViewModal';
 import './SharingManager.scss';
 import { PingManager } from './PingManager';
-import { StrCast } from '../../fields/Types';
-import { Doc } from '../../fields/Doc';
 import { SettingsManager } from './SettingsManager';
 
 @observer
 export class ServerStats extends React.Component<{}> {
+    // 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;
     // private get linkVisible() {
     //     return this.targetDoc ? this.targetDoc["acl-" + PublicKey] !== SharingPermissions.None : false;
     // }
 
-    @action
-    public open = async () => {
-        /**
-         * Populates the list of users.
-         */
-        fetch('/stats').then((res: Response) => res.text().then(action(stats => (this._stats = JSON.parse(stats)))));
-
-        this.isOpen = true;
-    };
-
-    public close = action(() => {
-        this.isOpen = false;
-    });
-
     constructor(props: {}) {
         super(props);
         makeObservable(this);
         ServerStats.Instance = this;
     }
 
-    @observable _stats: { [key: string]: any } | undefined = undefined;
-
     /**
      * @returns the main interface of the SharingManager.
      */
@@ -63,7 +47,28 @@ export class ServerStats extends React.Component<{}> {
         );
     }
 
+    // eslint-disable-next-line react/sort-comp
+    public close = action(() => {
+        this.isOpen = false;
+    });
+    public open = async () => {
+        /**
+         * Populates the list of users.
+         */
+        fetch('/stats').then((res: Response) =>
+            res.text().then(
+                action(stats => {
+                    this._stats = JSON.parse(stats);
+                })
+            )
+        );
+
+        runInAction(() => {
+            this.isOpen = true;
+        });
+    };
+
     render() {
-        return <MainViewModal contents={this.sharingInterface} isDisplayed={this.isOpen} interactive={true} closeOnExternalClick={this.close} />;
+        return <MainViewModal contents={this.sharingInterface} isDisplayed={this.isOpen} interactive closeOnExternalClick={this.close} />;
     }
 }
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 6676e4e03..5b4ac5aff 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -78,7 +78,6 @@ export class SharingManager extends React.Component<{}> {
     @observable private targetDocView: DocumentView | undefined = undefined; // the DocumentView of the document being shared
     // @observable private copied = false;
     @observable private dialogueBoxOpacity = 1; // for the modal
-    @observable private overlayOpacity = 0.4; // for the modal
     @observable private selectedUsers: UserOptions[] | null = null; // users (individuals/groups) selected to share with
     @observable private permissions: SharingPermissions = SharingPermissions.Edit; // the permission with which to share with other users
     @observable private individualSort: 'ascending' | 'descending' | 'none' = 'none'; // sorting options for the list of individuals
@@ -661,14 +660,12 @@ export class SharingManager extends React.Component<{}> {
                     if (docs.length) {
                         docs.forEach(doc => doc && Doc.BrushDoc(doc));
                         this.dialogueBoxOpacity = 0.1;
-                        this.overlayOpacity = 0.1;
                     }
                 })}
                 onPointerLeave={action(() => {
                     if (docs.length) {
                         docs.forEach(doc => doc && Doc.UnBrushDoc(doc));
                         this.dialogueBoxOpacity = 1;
-                        this.overlayOpacity = 0.4;
                     }
                 })}>
                 {contents}
@@ -742,6 +739,6 @@ export class SharingManager extends React.Component<{}> {
     }
 
     render() {
-        return <MainViewModal contents={this.sharingInterface} isDisplayed={this.isOpen} interactive dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} overlayDisplayedOpacity={this.overlayOpacity} closeOnExternalClick={this.close} />;
+        return <MainViewModal contents={this.sharingInterface} isDisplayed={this.isOpen} interactive dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} closeOnExternalClick={this.close} />;
     }
 }
diff --git a/src/client/util/TrackMovements.ts b/src/client/util/TrackMovements.ts
index f9c2d522f..25a3c9ad8 100644
--- a/src/client/util/TrackMovements.ts
+++ b/src/client/util/TrackMovements.ts
@@ -1,8 +1,7 @@
-import { IReactionDisposer, makeObservable, observable, observe, reaction } from 'mobx';
+import { IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
 import { NumCast } from '../../fields/Types';
 import { Doc, DocListCast } from '../../fields/Doc';
 import { CollectionDockingView } from '../views/collections/CollectionDockingView';
-import { Id } from '../../fields/FieldSymbols';
 import { CollectionViewType } from '../documents/DocumentTypes';
 
 export type Movement = {
@@ -33,6 +32,7 @@ export class TrackMovements {
     private tabChangeDisposeFunc: IReactionDisposer | null;
 
     // create static instance and getter for global use
+    // eslint-disable-next-line no-use-before-define
     @observable static _instance: TrackMovements;
     static get Instance(): TrackMovements {
         return TrackMovements._instance;
@@ -92,12 +92,13 @@ export class TrackMovements {
         // so that the size comparisons are correct, we must filter to only the FFViews
         const isFFView = (doc: Doc) => doc && doc._type_collection === CollectionViewType.Freeform;
         const tabbedFFViews = new Set<Doc>();
-        for (const DashDoc of tabbedDocs) {
+        tabbedDocs.forEach(DashDoc => {
             if (isFFView(DashDoc)) tabbedFFViews.add(DashDoc);
-        }
+        });
 
         // new tab was added - need to add it
         if (tabbedFFViews.size > this.recordingFFViews.size) {
+            // eslint-disable-next-line no-restricted-syntax
             for (const DashDoc of tabbedDocs) {
                 if (!this.recordingFFViews.has(DashDoc)) {
                     if (isFFView(DashDoc)) {
@@ -111,6 +112,7 @@ export class TrackMovements {
         }
         // tab was removed - need to remove it from recordingFFViews
         else if (tabbedFFViews.size < this.recordingFFViews.size) {
+            // eslint-disable-next-line no-restricted-syntax
             for (const [doc] of this.recordingFFViews) {
                 if (!tabbedFFViews.has(doc)) {
                     this.removeRecordingFFView(doc);
@@ -208,11 +210,11 @@ export class TrackMovements {
             return;
         }
 
-        for (const [id, disposeFunc] of this.recordingFFViews) {
+        Array.from(this.recordingFFViews).forEach(([id, disposeFunc]) => {
             // console.info('calling dispose func : docId', id);
             disposeFunc();
-            this.recordingFFViews.delete(id);
-        }
+            this.recordingFFViews?.delete(id);
+        });
     };
 
     private trackMovement = (panX: number, panY: number, doc: Doc, scale: number = 0) => {
@@ -241,9 +243,9 @@ export class TrackMovements {
     // method that concatenates an array of presentatations into one
     public concatPresentations = (presentations: Presentation[]): Presentation => {
         // these three will lead to the combined presentation
-        let combinedMovements: Movement[] = [];
+        const combinedMovements: Movement[] = [];
         let sumTime = 0;
-        let combinedMetas: any[] = [];
+        const combinedMetas: any[] = [];
 
         presentations.forEach(presentation => {
             const { movements, totalTime, meta } = presentation;
@@ -251,9 +253,7 @@ export class TrackMovements {
             // update movements if they had one
             if (movements) {
                 // add the summed time to the movements
-                const addedTimeMovements = movements.map(move => {
-                    return { ...move, time: move.time + sumTime };
-                });
+                const addedTimeMovements = movements.map(move => ({ ...move, time: move.time + sumTime }));
                 // concat the movements already in the combined presentation with these new ones
                 combinedMovements.push(...addedTimeMovements);
             }
diff --git a/src/client/util/Transform.ts b/src/client/util/Transform.ts
index dca37c960..1a07dd6ae 100644
--- a/src/client/util/Transform.ts
+++ b/src/client/util/Transform.ts
@@ -116,20 +116,14 @@ export class Transform {
 
     preTransformed = (transform: Transform): Transform => this.copy().preTransform(transform);
 
-    transformPoint = (x: number, y: number): [number, number] => {
-        x *= this._scale;
-        x += this._translateX;
-        y *= this._scale;
-        y += this._translateY;
-        return [x, y];
-    };
+    transformPoint = (x: number, y: number): [number, number] => [x * this._scale + this._translateX, y * this._scale + this._translateY];
 
     transformDirection = (x: number, y: number): [number, number] => [x * this._scale, y * this._scale];
 
     transformBounds(x: number, y: number, width: number, height: number): { x: number; y: number; width: number; height: number } {
-        [x, y] = this.transformPoint(x, y);
-        [width, height] = this.transformDirection(width, height);
-        return { x, y, width, height };
+        const [tx, ty] = this.transformPoint(x, y);
+        const [twidth, theight] = this.transformDirection(width, height);
+        return { x: tx, y: ty, width: twidth, height: theight };
     }
 
     inverse = () => new Transform(-this._translateX / this._scale, -this._translateY / this._scale, 1 / this._scale, -this._rotate);
diff --git a/src/client/util/TypedEvent.ts b/src/client/util/TypedEvent.ts
index 90fd299c1..9ef2aa8d7 100644
--- a/src/client/util/TypedEvent.ts
+++ b/src/client/util/TypedEvent.ts
@@ -14,27 +14,27 @@ export class TypedEvent<T> {
     on = (listener: Listener<T>): Disposable => {
         this.listeners.push(listener);
         return {
-            dispose: () => this.off(listener)
+            dispose: () => this.off(listener),
         };
-    }
+    };
 
     once = (listener: Listener<T>): void => {
         this.listenersOncer.push(listener);
-    }
+    };
 
     off = (listener: Listener<T>) => {
         const callbackIndex = this.listeners.indexOf(listener);
         if (callbackIndex > -1) this.listeners.splice(callbackIndex, 1);
-    }
+    };
 
     emit = (event: T) => {
         /** Update any general listeners */
-        this.listeners.forEach((listener) => listener(event));
+        this.listeners.forEach(listener => listener(event));
 
         /** Clear the `once` queue */
-        this.listenersOncer.forEach((listener) => listener(event));
+        this.listenersOncer.forEach(listener => listener(event));
         this.listenersOncer = [];
-    }
+    };
 
-    pipe = (te: TypedEvent<T>): Disposable => this.on((e) => te.emit(e));
-}
\ No newline at end of file
+    pipe = (te: TypedEvent<T>): Disposable => this.on(e => te.emit(e));
+}
diff --git a/src/client/util/bezierFit.ts b/src/client/util/bezierFit.ts
index 6bbf55e5a..d6f3f2340 100644
--- a/src/client/util/bezierFit.ts
+++ b/src/client/util/bezierFit.ts
@@ -1,3 +1,4 @@
+/* eslint-disable no-use-before-define */
 /* eslint-disable prefer-destructuring */
 /* eslint-disable no-param-reassign */
 /* eslint-disable camelcase */
@@ -242,6 +243,7 @@ function splitCubic(p: Point[], t: number, left: Point[], right: Point[]) {
  * is robust: a near-tangential intersection will yield zero or two
  * intersections.
  */
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
 function recursively_intersect(a: Point[], t0: number, t1: number, deptha: number, b: Point[], u0: number, u1: number, depthb: number, parameters: number[][]) {
     if (deptha > 0) {
         const a1 = new Array<Point>(4);
@@ -538,8 +540,8 @@ function FitCubic(d: Point[], first: number, last: number, tHat1: Point, tHat2:
         for (let i = 0; i < maxIterations; i++) {
             const uPrime = ReparameterizeBezier(d, first, last, u, bezCurve); //  Improved parameter values
             GenerateBezier(d, first, last, uPrime, tHat1, tHat2, bezCurve);
-            const { maxError } = ComputeMaxError(d, first, last, bezCurve, uPrime);
-            if (maxError < error) {
+            const { maxError: maximumError } = ComputeMaxError(d, first, last, bezCurve, uPrime);
+            if (maximumError < error) {
                 result.push(bezCurve[1]);
                 result.push(bezCurve[2]);
                 result.push(bezCurve[3]);
diff --git a/src/client/util/reportManager/ReportManagerComponents.tsx b/src/client/util/reportManager/ReportManagerComponents.tsx
index 1e226bf6d..cecebc648 100644
--- a/src/client/util/reportManager/ReportManagerComponents.tsx
+++ b/src/client/util/reportManager/ReportManagerComponents.tsx
@@ -1,9 +1,15 @@
+/* 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 { Issue } from './reportManagerSchema';
-import { darkColors, dashBlue, getLabelColors, isDarkMode, lightColors } from './reportManagerUtils';
 import ReactMarkdown from 'react-markdown';
 import rehypeRaw from 'rehype-raw';
 import remarkGfm from 'remark-gfm';
+import { darkColors, dashBlue, getLabelColors, isDarkMode, lightColors } from './reportManagerUtils';
+import { Issue } from './reportManagerSchema';
 import { StrCast } from '../../../fields/Types';
 import { Doc } from '../../../fields/Doc';
 
@@ -18,7 +24,7 @@ interface FilterProps<T> {
 }
 
 // filter ui for issues (horizontal list of tags)
-export const Filter = <T extends string>({ items, activeValue, setActiveValue }: FilterProps<T>) => {
+export function Filter<T extends string>({ items, activeValue, setActiveValue }: FilterProps<T>) {
     // establishing theme
     const darkMode = isDarkMode(StrCast(Doc.UserDoc().userBackgroundColor));
     const colors = darkMode ? darkColors : lightColors;
@@ -28,7 +34,7 @@ export const Filter = <T extends string>({ items, activeValue, setActiveValue }:
     return (
         <div className="issues-filter">
             <Tag
-                text={'All'}
+                text="All"
                 onClick={() => {
                     setActiveValue(null);
                 }}
@@ -38,25 +44,23 @@ export const Filter = <T extends string>({ items, activeValue, setActiveValue }:
                 borderColor={activeValue === null ? StrCast(Doc.UserDoc().userColor) : colors.border}
                 border
             />
-            {items.map(item => {
-                return (
-                    <Tag
-                        key={item}
-                        text={item}
-                        onClick={() => {
-                            setActiveValue(item);
-                        }}
-                        fontSize="12px"
-                        backgroundColor={activeValue === item ? StrCast(Doc.UserDoc().userColor) : 'transparent'}
-                        color={activeValue === item ? activeTagTextColor : colors.textGrey}
-                        border
-                        borderColor={activeValue === item ? StrCast(Doc.UserDoc().userColor) : colors.border}
-                    />
-                );
-            })}
+            {items.map(item => (
+                <Tag
+                    key={item}
+                    text={item}
+                    onClick={() => {
+                        setActiveValue(item);
+                    }}
+                    fontSize="12px"
+                    backgroundColor={activeValue === item ? StrCast(Doc.UserDoc().userColor) : 'transparent'}
+                    color={activeValue === item ? activeTagTextColor : colors.textGrey}
+                    border
+                    borderColor={activeValue === item ? StrCast(Doc.UserDoc().userColor) : colors.border}
+                />
+            ))}
         </div>
     );
-};
+}
 
 interface IssueCardProps {
     issue: Issue;
@@ -64,7 +68,7 @@ interface IssueCardProps {
 }
 
 // Component for the issue cards list on the left
-export const IssueCard = ({ issue, onSelect }: IssueCardProps) => {
+export function IssueCard({ issue, onSelect }: IssueCardProps) {
     const [textColor, setTextColor] = React.useState('');
     const [bgColor, setBgColor] = React.useState('transparent');
     const [borderColor, setBorderColor] = React.useState('transparent');
@@ -103,14 +107,14 @@ export const IssueCard = ({ issue, onSelect }: IssueCardProps) => {
             <h3 className="issue-title">{issue.title}</h3>
         </div>
     );
-};
+}
 
 interface IssueViewProps {
     issue: Issue;
 }
 
 // Detailed issue view that displays on the right
-export const IssueView = ({ issue }: IssueViewProps) => {
+export function IssueView({ issue }: IssueViewProps) {
     const [issueBody, setIssueBody] = React.useState('');
 
     // Parses the issue body into a formatted markdown (main functionality is replacing urls with tags)
@@ -127,15 +131,16 @@ export const IssueView = ({ issue }: IssueViewProps) => {
             parts.map(async part => {
                 if (imgTagRegex.test(part) || videoTagRegex.test(part) || audioTagRegex.test(part)) {
                     return `\n${await parseFileTag(part)}\n`;
-                } else if (fileRegex.test(part)) {
+                }
+                if (fileRegex.test(part)) {
                     const tag = await parseDashFiles(part);
                     return tag;
-                } else if (localRegex.test(part)) {
+                }
+                if (localRegex.test(part)) {
                     const tag = await parseLocalFiles(part);
                     return tag;
-                } else {
-                    return part;
                 }
+                return part;
             })
         );
 
@@ -143,7 +148,7 @@ export const IssueView = ({ issue }: IssueViewProps) => {
     };
 
     // Extracts the src from an image tag and either returns the raw url if not accessible or a new image tag
-    const parseFileTag = async (tag: string): Promise<string> => {
+    const parseFileTag = async (tag: string): Promise<string | undefined> => {
         const regex = /src="([^"]+)"/;
         let url = '';
         const match = tag.match(regex);
@@ -160,18 +165,19 @@ export const IssueView = ({ issue }: IssueViewProps) => {
             case '.png':
             case '.jpeg':
             case '.gif':
-                return await getDisplayedFile(url, 'image');
+                return getDisplayedFile(url, 'image');
             // video
             case '.mp4':
             case '.mpeg':
             case '.webm':
             case '.mov':
-                return await getDisplayedFile(url, 'video');
-            //audio
+                return getDisplayedFile(url, 'video');
+            // audio
             case '.mp3':
             case '.wav':
             case '.ogg':
-                return await getDisplayedFile(url, 'audio');
+                return getDisplayedFile(url, 'audio');
+            default:
         }
         return tag;
     };
@@ -183,14 +189,15 @@ export const IssueView = ({ issue }: IssueViewProps) => {
         const dashAudioRegex = /https:\/\/browndash\.com\/files[/\\]audio/;
 
         if (dashImgRegex.test(url)) {
-            return await getDisplayedFile(url, 'image');
-        } else if (dashVideoRegex.test(url)) {
-            return await getDisplayedFile(url, 'video');
-        } else if (dashAudioRegex.test(url)) {
-            return await getDisplayedFile(url, 'audio');
-        } else {
-            return url;
+            return getDisplayedFile(url, 'image');
         }
+        if (dashVideoRegex.test(url)) {
+            return getDisplayedFile(url, 'video');
+        }
+        if (dashAudioRegex.test(url)) {
+            return getDisplayedFile(url, 'audio');
+        }
+        return url;
     };
 
     // Returns the corresponding HTML tag for a src url
@@ -200,31 +207,37 @@ export const IssueView = ({ issue }: IssueViewProps) => {
         const dashAudioRegex = /http:\/\/localhost:1050\.com\/files[/\\]audio/;
 
         if (imgRegex.test(url)) {
-            return await getDisplayedFile(url, 'image');
-        } else if (dashVideoRegex.test(url)) {
-            return await getDisplayedFile(url, 'video');
-        } else if (dashAudioRegex.test(url)) {
-            return await getDisplayedFile(url, 'audio');
-        } else {
-            return url;
+            return getDisplayedFile(url, 'image');
+        }
+        if (dashVideoRegex.test(url)) {
+            return getDisplayedFile(url, 'video');
+        }
+        if (dashAudioRegex.test(url)) {
+            return getDisplayedFile(url, 'audio');
         }
+        return url;
     };
 
-    const getDisplayedFile = async (url: string, fileType: 'image' | 'video' | 'audio'): Promise<string> => {
+    const getDisplayedFile = async (url: string, fileType: 'image' | 'video' | 'audio'): Promise<string | undefined> => {
         switch (fileType) {
-            case 'image':
+            case 'image': {
                 const imgValid = await isImgValid(url);
                 if (!imgValid) return `\n${url} (This image could not be loaded)\n`;
                 return `\n${url}\n<img width="100%" alt="Issue asset" src=${url} />\n`;
-            case 'video':
+            }
+            case 'video': {
                 const videoValid = await isVideoValid(url);
                 if (!videoValid) return `\n${url} (This video could not be loaded)\n`;
                 return `\n${url}\n<video class="report-default-video" width="100%" controls alt="Issue asset" src=${url} />\n`;
-            case 'audio':
+            }
+            case 'audio': {
                 const audioValid = await isAudioValid(url);
                 if (!audioValid) return `\n${url} (This audio could not be loaded)\n`;
                 return `\n${url}\n<audio src=${url} controls />\n`;
+            }
+            default:
         }
+        return undefined;
     };
 
     // Loads an image and returns a promise that resolves as whether the image is valid or not
@@ -270,7 +283,7 @@ export const IssueView = ({ issue }: IssueViewProps) => {
         <div className="issue-view">
             <span className="issue-label">
                 Issue{' '}
-                <a className="issue-link" href={issue.html_url} target="_blank">
+                <a className="issue-link" href={issue.html_url} target="_blank" rel="noreferrer">
                     #{issue.number}
                 </a>
             </span>
@@ -292,7 +305,7 @@ export const IssueView = ({ issue }: IssueViewProps) => {
             <ReactMarkdown children={issueBody} className="issue-content" remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]} />
         </div>
     );
-};
+}
 
 interface TagProps {
     text: string;
@@ -305,7 +318,7 @@ interface TagProps {
 }
 
 // Small tag for labels of the issue
-export const Tag = ({ text, color, backgroundColor, fontSize, border, borderColor, onClick }: TagProps) => {
+export function Tag({ text, color, backgroundColor, fontSize, border, borderColor, onClick }: TagProps) {
     return (
         <div
             onClick={onClick ?? (() => {})}
@@ -314,14 +327,14 @@ export const Tag = ({ text, color, backgroundColor, fontSize, border, borderColo
             {text}
         </div>
     );
-};
+}
 
 interface FormInputProps {
     value: string;
     placeholder: string;
     onChange: (val: string) => void;
 }
-export const FormInput = ({ value, placeholder, onChange }: FormInputProps) => {
+export function FormInput({ value, placeholder, onChange }: FormInputProps) {
     const [inputBorderColor, setInputBorderColor] = React.useState('');
 
     return (
@@ -349,9 +362,9 @@ export const FormInput = ({ value, placeholder, onChange }: FormInputProps) => {
             }}
         />
     );
-};
+}
 
-export const FormTextArea = ({ value, placeholder, onChange }: FormInputProps) => {
+export function FormTextArea({ value, placeholder, onChange }: FormInputProps) {
     const [textAreaBorderColor, setTextAreaBorderColor] = React.useState('');
 
     return (
@@ -378,4 +391,4 @@ export const FormTextArea = ({ value, placeholder, onChange }: FormInputProps) =
             }}
         />
     );
-};
+}
diff --git a/src/client/util/reportManager/reportManagerSchema.ts b/src/client/util/reportManager/reportManagerSchema.ts
index 9a1c7c3e9..171c24393 100644
--- a/src/client/util/reportManager/reportManagerSchema.ts
+++ b/src/client/util/reportManager/reportManagerSchema.ts
@@ -1,3 +1,4 @@
+/* eslint-disable no-use-before-define */
 /**
  * Issue interface schema from Github.
  */
diff --git a/src/client/util/reportManager/reportManagerUtils.ts b/src/client/util/reportManager/reportManagerUtils.ts
index 22e5eebbb..f14967e0a 100644
--- a/src/client/util/reportManager/reportManagerUtils.ts
+++ b/src/client/util/reportManager/reportManagerUtils.ts
@@ -63,9 +63,8 @@ export const getAllIssues = async (octokit: Octokit): Promise<any[]> => {
     // 200 status means success
     if (res.status === 200) {
         return res.data;
-    } else {
-        throw new Error('Error getting issues');
     }
+    throw new Error('Error getting issues');
 };
 
 /**
@@ -104,9 +103,7 @@ export const fileLinktoServerLink = (fileLink: string): string => {
  * @param link response from file upload
  * @returns server file path
  */
-export const getServerPath = (link: any): string => {
-    return link.result.accessPaths.agnostic.server as string;
-};
+export const getServerPath = (link: any): string => link.result.accessPaths.agnostic.server as string;
 
 /**
  * Uploads media files to the server.
@@ -124,6 +121,7 @@ export const uploadFilesToServer = async (mediaFiles: FileData[]): Promise<strin
             alert(err);
         }
     }
+    return undefined;
 };
 
 // helper functions
@@ -141,18 +139,16 @@ export const passesTagFilter = (issue: Issue, priorityFilter: string | null, bug
         passesPriority = issue.labels.some(label => {
             if (typeof label === 'string') {
                 return label === priorityFilter;
-            } else {
-                return label.name === priorityFilter;
             }
+            return label.name === priorityFilter;
         });
     }
     if (bugFilter) {
         passesBug = issue.labels.some(label => {
             if (typeof label === 'string') {
                 return label === bugFilter;
-            } else {
-                return label.name === bugFilter;
             }
+            return label.name === bugFilter;
         });
     }
     return passesPriority && passesBug;
@@ -217,7 +213,8 @@ export const bugColors: { [key: string]: string[] } = {
 export const getLabelColors = (label: string): string[] => {
     if (prioritySet.has(label as Priority)) {
         return priorityColors[label];
-    } else if (bugSet.has(label as BugType)) {
+    }
+    if (bugSet.has(label as BugType)) {
         return bugColors[label];
     }
     return ['#0f73f6', '#ffffff'];
diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx
index f03e316a2..57498f39f 100644
--- a/src/client/views/animationtimeline/Timeline.tsx
+++ b/src/client/views/animationtimeline/Timeline.tsx
@@ -47,13 +47,13 @@ import { Track } from './Track';
 
 @observer
 export class Timeline extends ObservableReactComponent<FieldViewProps> {
-    //readonly constants
+    // readonly constants
     private readonly DEFAULT_TICK_SPACING: number = 50;
     private readonly MAX_TITLE_HEIGHT = 75;
     private readonly MAX_CONTAINER_HEIGHT: number = 800;
     private readonly DEFAULT_TICK_INCREMENT: number = 1000;
 
-    //height variables
+    // height variables
     private DEFAULT_CONTAINER_HEIGHT: number = 330;
     private MIN_CONTAINER_HEIGHT: number = 205;
 
@@ -62,7 +62,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
         makeObservable(this);
     }
 
-    //react refs
+    // react refs
     @observable private _trackbox = React.createRef<HTMLDivElement>();
     @observable private _titleContainer = React.createRef<HTMLDivElement>();
     @observable private _timelineContainer = React.createRef<HTMLDivElement>();
@@ -70,7 +70,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
     @observable private _roundToggleRef = React.createRef<HTMLDivElement>();
     @observable private _roundToggleContainerRef = React.createRef<HTMLDivElement>();
 
-    //boolean vars and instance vars
+    // boolean vars and instance vars
     @observable private _currentBarX: number = 0;
     @observable private _windSpeed: number = 1;
     @observable private _totalLength: number = 0;
@@ -79,11 +79,11 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
     @observable private _containerHeight: number = this.DEFAULT_CONTAINER_HEIGHT;
     @observable private _tickSpacing = this.DEFAULT_TICK_SPACING;
     @observable private _tickIncrement = this.DEFAULT_TICK_INCREMENT;
-    @observable private _time = 100000; //DEFAULT
+    @observable private _time = 100000; // DEFAULT
     @observable private _playButton = faPlayCircle;
     @observable private _titleHeight = 0;
 
-    @observable public IsPlaying: boolean = false; //scrubber playing
+    @observable public IsPlaying: boolean = false; // scrubber playing
 
     /**
      * collection get method. Basically defines what defines collection's children. These will be tracked in the timeline. Do not edit.
@@ -97,30 +97,30 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
         return DocListCast(this._props.Document[this._props.fieldKey]);
     }
 
-    /////////lifecycle functions////////////
+    /// //////lifecycle functions////////////
     @action
     componentDidMount() {
-        const relativeHeight = window.innerHeight / 20; //sets height to arbitrary size, relative to innerHeight
-        this._titleHeight = relativeHeight < this.MAX_TITLE_HEIGHT ? relativeHeight : this.MAX_TITLE_HEIGHT; //check if relHeight is less than Maxheight. Else, just set relheight to max
-        this.MIN_CONTAINER_HEIGHT = this._titleHeight + 130; //offset
-        this.DEFAULT_CONTAINER_HEIGHT = this._titleHeight * 2 + 130; //twice the titleheight + offset
+        const relativeHeight = window.innerHeight / 20; // sets height to arbitrary size, relative to innerHeight
+        this._titleHeight = relativeHeight < this.MAX_TITLE_HEIGHT ? relativeHeight : this.MAX_TITLE_HEIGHT; // check if relHeight is less than Maxheight. Else, just set relheight to max
+        this.MIN_CONTAINER_HEIGHT = this._titleHeight + 130; // offset
+        this.DEFAULT_CONTAINER_HEIGHT = this._titleHeight * 2 + 130; // twice the titleheight + offset
         if (!this._props.Document.AnimationLength) {
-            //if animation length did not exist
-            this._props.Document.AnimationLength = this._time; //set it to default time
+            // if animation length did not exist
+            this._props.Document.AnimationLength = this._time; // set it to default time
         } else {
-            this._time = NumCast(this._props.Document.AnimationLength); //else, set time to animationlength stored from before
+            this._time = NumCast(this._props.Document.AnimationLength); // else, set time to animationlength stored from before
         }
-        this._totalLength = this._tickSpacing * (this._time / this._tickIncrement); //the entire length of the timeline div (actual div part itself)
-        this._visibleLength = this._infoContainer.current!.getBoundingClientRect().width; //the visible length of the timeline (the length that you current see)
-        this._visibleStart = this._infoContainer.current!.scrollLeft; //where the div starts
-        this._props.Document.isATOn = !this._props.Document.isATOn; //turns the boolean on, saying AT (animation timeline) is on
+        this._totalLength = this._tickSpacing * (this._time / this._tickIncrement); // the entire length of the timeline div (actual div part itself)
+        this._visibleLength = this._infoContainer.current!.getBoundingClientRect().width; // the visible length of the timeline (the length that you current see)
+        this._visibleStart = this._infoContainer.current!.scrollLeft; // where the div starts
+        this._props.Document.isATOn = !this._props.Document.isATOn; // turns the boolean on, saying AT (animation timeline) is on
         this.toggleHandle();
     }
 
     componentWillUnmount() {
-        this._props.Document.AnimationLength = this._time; //save animation length
+        this._props.Document.AnimationLength = this._time; // save animation length
     }
-    /////////////////////////////////////////////////
+    /// //////////////////////////////////////////////
 
     /**
      * React Functional Component
@@ -148,7 +148,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
         pixel <= 0 ? (this._currentBarX = 0) : pixel >= this._totalLength ? (this._currentBarX = this._totalLength) : (this._currentBarX = pixel);
     };
 
-    //for playing
+    // for playing
     onPlay = (e: React.MouseEvent) => {
         e.stopPropagation();
         this.play();
@@ -181,7 +181,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
         e.preventDefault();
         e.stopPropagation();
         if (this._windSpeed < 64) {
-            //max speed is 32
+            // max speed is 32
             this._windSpeed = this._windSpeed * 2;
         }
     };
@@ -215,7 +215,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
         const scrubberbox = this._infoContainer.current!;
         const left = scrubberbox.getBoundingClientRect().left;
         const offsetX = Math.round(e.clientX - left) * this._props.ScreenToLocalTransform().Scale;
-        this.changeCurrentBarX(offsetX + this._visibleStart); //changes scrubber to clicked scrubber position
+        this.changeCurrentBarX(offsetX + this._visibleStart); // changes scrubber to clicked scrubber position
         return false;
     };
 
@@ -355,12 +355,12 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
      * tool box includes the toggle buttons at the top of the timeline (both editing mode and play mode)
      */
     private timelineToolBox = (scale: number, totalTime: number) => {
-        const size = 40 * scale; //50 is default
+        const size = 40 * scale; // 50 is default
         const iconSize = 25;
         const width: number = this._props.PanelWidth();
         const modeType = this._props.Document.isATOn ? 'Author' : 'Play';
 
-        //decides if information should be omitted because the timeline is very small
+        // decides if information should be omitted because the timeline is very small
         // if its less than 950 pixels then it's going to be overlapping
         let modeString = modeType,
             overviewString = '',
@@ -469,7 +469,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
 
         this._props.Document.isATOn = !this._props.Document.isATOn;
         if (!BoolCast(this._props.Document.isATOn)) {
-            //turning on playmode...
+            // turning on playmode...
             roundToggle.style.transform = 'translate(0px, 0px)';
             roundToggle.style.animationName = 'turnoff';
             roundToggleContainer.style.animationName = 'turnoff';
@@ -477,7 +477,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
             timelineContainer.style.top = `${-this._containerHeight}px`;
             this.toPlay();
         } else {
-            //turning on authoring mode...
+            // turning on authoring mode...
             roundToggle.style.transform = 'translate(20px, 0px)';
             roundToggle.style.animationName = 'turnon';
             roundToggleContainer.style.animationName = 'turnon';
@@ -490,8 +490,8 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
     @action.bound
     changeLengths() {
         if (this._infoContainer.current) {
-            this._visibleLength = this._infoContainer.current.getBoundingClientRect().width; //the visible length of the timeline (the length that you current see)
-            this._visibleStart = this._infoContainer.current.scrollLeft; //where the div starts
+            this._visibleLength = this._infoContainer.current.getBoundingClientRect().width; // the visible length of the timeline (the length that you current see)
+            this._visibleStart = this._infoContainer.current.scrollLeft; // where the div starts
         }
     }
 
@@ -515,7 +515,7 @@ export class Timeline extends ObservableReactComponent<FieldViewProps> {
                     }
                 }
             } else {
-                //TODO: remove undefineds and duplicates
+                // TODO: remove undefineds and duplicates
             }
         });
         return longestTime;
diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx
index 489c4dcde..7bf685c9e 100644
--- a/src/client/views/animationtimeline/TimelineOverview.tsx
+++ b/src/client/views/animationtimeline/TimelineOverview.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/no-unused-prop-types */
 import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -32,7 +33,6 @@ export class TimelineOverview extends React.Component<TimelineOverviewProps> {
     @observable private visibleTime: number = 0;
     @observable private currentX: number = 0;
     @observable private visibleStart: number = 0;
-    private readonly DEFAULT_HEIGHT = 50;
     private readonly DEFAULT_WIDTH = 300;
 
     componentDidMount() {
@@ -50,9 +50,9 @@ export class TimelineOverview extends React.Component<TimelineOverviewProps> {
         );
     }
 
-    componentWillUnmount = () => {
+    componentWillUnmount() {
         this._authoringReaction && this._authoringReaction();
-    };
+    }
 
     @action
     setOverviewWidth() {
@@ -109,7 +109,7 @@ export class TimelineOverview extends React.Component<TimelineOverviewProps> {
         e.preventDefault();
         e.stopPropagation();
         const scrubberRef = this._scrubberRef.current!;
-        const left = scrubberRef.getBoundingClientRect().left;
+        const { left } = scrubberRef.getBoundingClientRect();
         const offsetX = Math.round(e.clientX - left);
         this.props.changeCurrentBarX((offsetX / this.activeOverviewWidth) * this.props.totalLength + this.props.currentBarX);
     };
@@ -152,17 +152,17 @@ export class TimelineOverview extends React.Component<TimelineOverviewProps> {
         const timeline = this.props.isAuthoring
             ? [
                   <div key="timeline-overview-container" className="timeline-overview-container overviewBar" id="timelineOverview" ref={this.authoringContainer}>
-                      <div ref={this._visibleRef} key="1" className="timeline-overview-visible" style={{ left: `${barStart}px`, width: `${visibleBarWidth}px` }} onPointerDown={this.onPointerDown}></div>,
+                      <div ref={this._visibleRef} key="1" className="timeline-overview-visible" style={{ left: `${barStart}px`, width: `${visibleBarWidth}px` }} onPointerDown={this.onPointerDown} />,
                       <div ref={this._scrubberRef} key="2" className="timeline-overview-scrubber-container" style={{ left: `${scrubberStart}px` }} onPointerDown={this.onScrubberDown}>
-                          <div key="timeline-overview-scrubber-head" className="timeline-overview-scrubber-head"></div>
+                          <div key="timeline-overview-scrubber-head" className="timeline-overview-scrubber-head" />
                       </div>
                   </div>,
               ]
             : [
                   <div key="1" className="timeline-play-bar overviewBar" id="timelinePlay" ref={this.playbackContainer}>
-                      <div ref={this._scrubberRef} className="timeline-play-head" style={{ left: `${scrubberStart}px` }} onPointerDown={this.onScrubberDown}></div>
+                      <div ref={this._scrubberRef} className="timeline-play-head" style={{ left: `${scrubberStart}px` }} onPointerDown={this.onScrubberDown} />
                   </div>,
-                  <div key="2" className="timeline-play-tail" style={{ width: `${playWidth}px` }}></div>,
+                  <div key="2" className="timeline-play-tail" style={{ width: `${playWidth}px` }} />,
               ];
         return (
             <div className="timeline-flex">
diff --git a/src/client/views/collections/CollectionCalendarView.tsx b/src/client/views/collections/CollectionCalendarView.tsx
index 578ce77a5..43e5a68eb 100644
--- a/src/client/views/collections/CollectionCalendarView.tsx
+++ b/src/client/views/collections/CollectionCalendarView.tsx
@@ -25,16 +25,13 @@ export class CollectionCalendarView extends CollectionSubView() {
 
     removeCalendar = () => {};
 
-    addCalendar = (doc: Doc | Doc[], annotationKey?: string | undefined): boolean => {
+    addCalendar = (/* doc: Doc | Doc[], annotationKey?: string | undefined */): boolean =>
         // bring up calendar modal with option to create a calendar
-        return true;
-    };
+        true;
 
     _stackRef = React.createRef<CollectionStackingView>();
 
-    panelHeight = () => {
-        return this._props.PanelHeight() - 40; // this should be the height of the stacking view. For now, it's the hieight of the calendar view minus 40 to allow for a title
-    };
+    panelHeight = () => this._props.PanelHeight() - 40; // this should be the height of the stacking view. For now, it's the hieight of the calendar view minus 40 to allow for a title
 
     // most recent calendar should come first
     sortByMostRecentDate = (calendarA: Doc, calendarB: Doc) => {
@@ -46,18 +43,18 @@ export class CollectionCalendarView extends CollectionSubView() {
 
         if (aFromDate > bFromDate) {
             return -1; // a comes first
-        } else if (aFromDate < bFromDate) {
+        }
+        if (aFromDate < bFromDate) {
+            return 1; // b comes first
+        }
+        // start dates are the same
+        if (aToDate > bToDate) {
+            return -1; // a comes first
+        }
+        if (aToDate < bToDate) {
             return 1; // b comes first
-        } else {
-            // start dates are the same
-            if (aToDate > bToDate) {
-                return -1; // a comes first
-            } else if (aToDate < bToDate) {
-                return 1; // b comes first
-            } else {
-                return 0; // same start and end dates
-            }
         }
+        return 0; // same start and end dates
     };
 
     screenToLocalTransform = () =>
@@ -74,6 +71,7 @@ export class CollectionCalendarView extends CollectionSubView() {
         return (
             <div className="collectionCalendarView">
                 <CollectionStackingView
+                    // eslint-disable-next-line react/jsx-props-no-spreading
                     {...this._props}
                     setContentViewBox={emptyFunction}
                     ref={this._stackRef}
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 6dda6e545..51352d3e2 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -1,3 +1,6 @@
+/* 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';
 import { observer } from 'mobx-react';
@@ -107,10 +110,10 @@ export class CollectionCarouselView extends CollectionSubView() {
         return (
             <>
                 <div key="back" className="carouselView-back" onClick={this.goback}>
-                    <FontAwesomeIcon icon={'chevron-left'} size={'2x'} />
+                    <FontAwesomeIcon icon="chevron-left" size="2x" />
                 </div>
                 <div key="fwd" className="carouselView-fwd" onClick={this.advance}>
-                    <FontAwesomeIcon icon={'chevron-right'} size={'2x'} />
+                    <FontAwesomeIcon icon="chevron-right" size="2x" />
                 </div>
             </>
         );
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 9a1781b93..fefaf6591 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -120,7 +120,7 @@ export class CollectionDockingView extends CollectionSubView() {
     @undoBatch
     public static CloseSplit(document: Opt<Doc>, panelName?: string): boolean {
         if (CollectionDockingView.Instance) {
-            const tab = Array.from(CollectionDockingView.Instance.tabMap.keys()).find(tab => (panelName ? tab.contentItem.config.props.panelName === panelName : tab.DashDoc === document));
+            const tab = Array.from(CollectionDockingView.Instance.tabMap.keys()).find(tabView => (panelName ? tabView.contentItem.config.props.panelName === panelName : tabView.DashDoc === document));
             if (tab) {
                 const j = tab.header.parent.contentItems.indexOf(tab.contentItem);
                 if (j !== -1) {
@@ -147,7 +147,7 @@ export class CollectionDockingView extends CollectionSubView() {
             stack.contentItems[activeContentItemIndex].remove();
             return instance.layoutChanged();
         }
-        const tab = Array.from(instance.tabMap.keys()).find(tab => tab.contentItem.config.props.panelName === panelName);
+        const tab = Array.from(instance.tabMap.keys()).find(tabView => tabView.contentItem.config.props.panelName === panelName);
         if (tab) {
             const j = tab.header.parent.contentItems.indexOf(tab.contentItem);
             if (newConfig.props.documentId !== tab.header.parent.contentItems[j].config.props.documentId) {
@@ -172,7 +172,7 @@ export class CollectionDockingView extends CollectionSubView() {
     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;
-        const tab = Array.from(CollectionDockingView.Instance.tabMap).find(tab => tab.DashDoc === document && !tab.contentItem.config.props.keyValue && !keyValue);
+        const tab = Array.from(CollectionDockingView.Instance.tabMap).find(tabView => tabView.DashDoc === document && !tabView.contentItem.config.props.keyValue && !keyValue);
         if (tab) {
             tab.header.parent.setActiveContentItem(tab.contentItem);
             return true;
diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
index e00fdb50c..95aecc7d0 100644
--- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
@@ -1,3 +1,4 @@
+/* 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';
@@ -14,7 +15,7 @@ import { DocUtils, Docs } from '../../documents/Documents';
 import { DragManager } from '../../util/DragManager';
 import { SnappingManager } from '../../util/SnappingManager';
 import { Transform } from '../../util/Transform';
-import { undoBatch } from '../../util/UndoManager';
+import { undoBatch, undoable } from '../../util/UndoManager';
 import { ContextMenu } from '../ContextMenu';
 import { ContextMenuProps } from '../ContextMenuItem';
 import { EditableView } from '../EditableView';
@@ -113,13 +114,15 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
     };
 
     @action
-    headingChanged = (value: string, shiftDown?: boolean) => {
+    headingChanged = (value: string /* , shiftDown?: boolean */) => {
         const castedValue = this.getValue(value);
         if (castedValue) {
             if (this._props.colHeaderData?.map(i => i.heading).indexOf(castedValue.toString()) !== -1) {
                 return false;
             }
-            this._props.docList.forEach(d => (d[this._props.pivotField] = castedValue));
+            this._props.docList.forEach(d => {
+                d[this._props.pivotField] = castedValue;
+            });
             if (this._props.headingObject) {
                 this._props.headingObject.setHeading(castedValue.toString());
                 this._heading = this._props.headingObject.heading;
@@ -129,10 +132,14 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
         return false;
     };
 
-    @action pointerEntered = () => (this._hover = true);
-    @action pointerLeave = () => (this._hover = false);
-    @undoBatch
-    addTextNote = (char: string) => this.addNewTextDoc('-typed text-', false, true);
+    @action pointerEntered = () => {
+        this._hover = true;
+    };
+    @action pointerLeave = () => {
+        this._hover = false;
+    };
+
+    addTextNote = undoable(() => this.addNewTextDoc('-typed text-', false, true), 'add text note');
 
     // addNewTextDoc is called when a user starts typing in a column to create a new node
     @action
@@ -195,6 +202,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
                             }
                             return this._props.addDocument?.(created);
                         }
+                        return undefined;
                     },
                     icon: 'compress-arrows-alt',
                 })
@@ -214,6 +222,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
                             }
                             return this._props.addDocument?.(created) || false;
                         }
+                        return undefined;
                     },
                     icon: 'compress-arrows-alt',
                 })
@@ -238,7 +247,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
         const key = this._props.pivotField;
         const heading = this._heading;
         const columnYMargin = this._props.headingObject ? 0 : this._props.yMargin;
-        const evContents = heading ? heading : '25';
+        const evContents = heading || '25';
         const headingView = this._props.headingObject ? (
             <div
                 key={heading}
@@ -252,17 +261,16 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
                     className="collectionNoteTakingView-sectionHeader-subCont"
                     title={evContents === `No Value` ? `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ''}
                     style={{ background: evContents !== `No Value` ? this._color : 'inherit' }}>
-                    <EditableView GetValue={() => evContents} isEditingCallback={isEditing => isEditing && this._props.select(false)} SetValue={this.headingChanged} contents={evContents} oneLine={true} />
+                    <EditableView GetValue={() => evContents} isEditingCallback={isEditing => isEditing && this._props.select(false)} SetValue={this.headingChanged} contents={evContents} oneLine />
                 </div>
                 {(this._props.colHeaderData?.length ?? 0) > 1 && (
-                    <button className="collectionNoteTakingView-sectionDelete" onClick={this.deleteColumn}>
+                    <button type="button" className="collectionNoteTakingView-sectionDelete" onClick={this.deleteColumn}>
                         <FontAwesomeIcon icon="trash" size="lg" />
                     </button>
                 )}
             </div>
         ) : null;
         const templatecols = this.columnWidth;
-        const type = this._props.Document.type;
         return (
             <>
                 {headingView}
@@ -270,7 +278,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
                     <div className="collectionNoteTakingView-columnStack">
                         <div
                             key={`${heading}-stack`}
-                            className={`collectionNoteTakingView-Nodes`}
+                            className="collectionNoteTakingView-Nodes"
                             style={{
                                 padding: `${columnYMargin}px ${0}px ${this._props.yMargin}px ${0}px`,
                                 gridGap: this._props.gridGap,
@@ -282,10 +290,13 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
                         {!this._props.chromeHidden ? (
                             <div className="collectionNoteTakingView-DocumentButtons" style={{ display: this._props.isContentActive() ? 'flex' : 'none', marginBottom: 10 }}>
                                 <div className="collectionNoteTakingView-addDocumentButton" style={{ color: lightOrDark(this._props.backgroundColor?.()) }}>
-                                    <EditableView GetValue={returnEmptyString} SetValue={this.addNewTextDoc} textCallback={this.addTextNote} placeholder={"Type ':' for commands"} contents={'+ Node'} menuCallback={this.menuCallback} />
+                                    <EditableView GetValue={returnEmptyString} SetValue={this.addNewTextDoc} textCallback={this.addTextNote} placeholder={"Type ':' for commands"} contents="+ Node" menuCallback={this.menuCallback} />
                                 </div>
                                 <div className="collectionNoteTakingView-addDocumentButton" style={{ color: lightOrDark(this._props.backgroundColor?.()) }}>
-                                    <EditableView {...this._props.editableViewProps()} />
+                                    {
+                                        // eslint-disable-next-line react/jsx-props-no-spreading
+                                        <EditableView {...this._props.editableViewProps()} />
+                                    }
                                 </div>
                             </div>
                         ) : null}
diff --git a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
index 67070b24d..ddd4b8137 100644
--- a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
@@ -28,7 +28,7 @@ export class CollectionNoteTakingViewDivider extends ObservableReactComponent<Di
         setupMoveUpEvents(
             this,
             e,
-            (e, down, delta) => {
+            (moveEv, down, delta) => {
                 if (!batch) batch = UndoManager.StartBatch('resizing');
                 this._props.setColumnStartXCoords(delta[0], this._props.index);
                 return false;
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 35f330b44..cb463077c 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -157,7 +157,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
         const key = this._props.pivotField;
         const newDoc = Docs.Create.TextDocument(value, { _height: 18, _width: 200, _layout_fitWidth: true, title: value, _layout_autoHeight: true });
         key && (newDoc[key] = this.getValue(this._props.heading));
-        const maxHeading = this._props.docList.reduce((maxHeading, doc) => (NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading), 0);
+        const maxHeading = this._props.docList.reduce((prevHeading, doc) => (NumCast(doc.heading) > prevHeading ? NumCast(doc.heading) : prevHeading), 0);
         const heading = maxHeading === 0 || this._props.docList.length === 0 ? 1 : maxHeading === 1 ? 2 : 3;
         newDoc.heading = heading;
         FormattedTextBox.SetSelectOnLoad(newDoc);
@@ -220,9 +220,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
     renderMenu = () => (
         <div className="collectionStackingView-optionPicker">
             <div className="optionOptions">
-                <div className={'optionPicker' + (true ? ' active' : '')} onClick={action(() => {})}>
-                    Add options here
-                </div>
+                <div className="optionPicker active">Add options here</div>
             </div>
         </div>
     );
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 538a6fd5e..bf81bdc7f 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -177,24 +177,24 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
     screenToLocalTransform = () => this.ScreenToLocalBoxXf().translate(0, -this._headerHeight);
 
     @action
-    remove = (doc: Doc | Doc[]): boolean => {
-        const docs = doc instanceof Doc ? [doc] : doc;
+    remove = (docIn: Doc | Doc[]): boolean => {
+        const docs = docIn instanceof Doc ? [docIn] : docIn;
         const targetDataDoc = this.Document[DocData];
         const value = DocListCast(targetDataDoc[this._props.fieldKey]);
         const result = value.filter(v => !docs.includes(v));
-        if ((doc instanceof Doc ? [doc] : doc).some(doc => SelectionManager.Views.some(dv => Doc.AreProtosEqual(dv.Document, doc)))) SelectionManager.DeselectAll();
+        if (docs.some(doc => SelectionManager.Views.some(dv => Doc.AreProtosEqual(dv.Document, doc)))) SelectionManager.DeselectAll();
         if (result.length !== value.length) {
-            if (doc instanceof Doc) {
-                const ind = DocListCast(targetDataDoc[this._props.fieldKey]).indexOf(doc);
+            if (docIn instanceof Doc) {
+                const ind = DocListCast(targetDataDoc[this._props.fieldKey]).indexOf(docIn);
                 const prev = ind && DocListCast(targetDataDoc[this._props.fieldKey])[ind - 1];
-                this._props.removeDocument?.(doc);
+                this._props.removeDocument?.(docIn);
                 if (ind > 0 && prev) {
                     FormattedTextBox.SetSelectOnLoad(prev);
                     DocumentManager.Instance.getDocumentView(prev, this.DocumentView?.())?.select(false);
                 }
                 return true;
             }
-            return this._props.removeDocument?.(doc) ?? false;
+            return this._props.removeDocument?.(docIn) ?? false;
         }
         return false;
     };
@@ -299,7 +299,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
     @computed get treeViewElements() {
         TraceMobx();
         const dragAction = StrCast(this.Document.childDragAction) as any as dropActionType;
-        const addDoc = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => this.addDoc(doc, relativeTo, before);
+        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)
             setTimeout(
@@ -315,7 +315,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
             this._props.TemplateDataDocument,
             undefined,
             undefined,
-            addDoc,
+            treeAddDoc,
             this.remove,
             moveDoc,
             dragAction,
@@ -419,8 +419,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
 
     addAnnotationDocument = (doc: Doc | Doc[]) => this.addDocument(doc, `${this._props.fieldKey}_annotations`) || false;
     remAnnotationDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, `${this._props.fieldKey}_annotations`) || false;
-    moveAnnotationDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[], annotationKey?: string) => boolean) =>
-        this.moveDocument(doc, targetCollection, addDocument, `${this._props.fieldKey}_annotations`) || false;
+    moveAnnotationDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (document: Doc | Doc[], annotationKey?: string) => boolean) => this.moveDocument(doc, targetCollection, addDocument) || false;
 
     @observable _headerHeight = 0;
     @computed get content() {
diff --git a/src/client/views/collections/KeyRestrictionRow.tsx b/src/client/views/collections/KeyRestrictionRow.tsx
index 4523a4f1e..7dc08389b 100644
--- a/src/client/views/collections/KeyRestrictionRow.tsx
+++ b/src/client/views/collections/KeyRestrictionRow.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/button-has-type */
 import { observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -35,11 +36,36 @@ export default class KeyRestrictionRow extends React.Component<IKeyRestrictionPr
 
         return (
             <div className="collectionViewBaseChrome-viewSpecsMenu-row">
-                <input className="collectionViewBaseChrome-viewSpecsMenu-rowLeft" value={this._key} onChange={e => runInAction(() => (this._key = e.target.value))} placeholder="KEY" />
-                <button className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle" style={{ background: this._contains ? '#77dd77' : '#ff6961' }} onClick={() => runInAction(() => (this._contains = !this._contains))}>
+                <input
+                    className="collectionViewBaseChrome-viewSpecsMenu-rowLeft"
+                    value={this._key}
+                    onChange={e =>
+                        runInAction(() => {
+                            this._key = e.target.value;
+                        })
+                    }
+                    placeholder="KEY"
+                />
+                <button
+                    className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle"
+                    style={{ background: this._contains ? '#77dd77' : '#ff6961' }}
+                    onClick={() =>
+                        runInAction(() => {
+                            this._contains = !this._contains;
+                        })
+                    }>
                     {this._contains ? 'CONTAINS' : 'DOES NOT CONTAIN'}
                 </button>
-                <input className="collectionViewBaseChrome-viewSpecsMenu-rowRight" value={this._value} onChange={e => runInAction(() => (this._value = e.target.value))} placeholder="VALUE" />
+                <input
+                    className="collectionViewBaseChrome-viewSpecsMenu-rowRight"
+                    value={this._value}
+                    onChange={e =>
+                        runInAction(() => {
+                            this._value = e.target.value;
+                        })
+                    }
+                    placeholder="VALUE"
+                />
             </div>
         );
     }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx
index 0acc99360..d2ce17f99 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx
@@ -10,6 +10,7 @@ export interface CollectionFreeFormViewBackgroundGridProps {
     PanelWidth: () => number;
     PanelHeight: () => number;
     color: () => string;
+    // eslint-disable-next-line react/require-default-props
     isAnnotationOverlay?: boolean;
     nativeDimScaling: () => number;
     zoomScaling: () => number;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
index 73dd7fea3..fc39cafaa 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
@@ -5,13 +5,13 @@ import * as React from 'react';
 import { SettingsManager } from '../../../util/SettingsManager';
 import { ObservableReactComponent } from '../../ObservableReactComponent';
 import './CollectionFreeFormView.scss';
-import { Doc } from '../../../../fields/Doc';
 
 /**
  * An Fsa Arc.  The first array element is a test condition function that will be observed.
  * The second array element is a function that will be invoked when the first test function
  * returns a truthy value
  */
+// eslint-disable-next-line no-use-before-define
 export type infoArc = [() => any, (res?: any) => infoState];
 
 export const StateMessage = Symbol('StateMessage');
@@ -46,6 +46,7 @@ export function InfoState(
     gif?: string,
     entryFunc?: () => any
 ) {
+    // eslint-disable-next-line new-cap
     return new infoState(msg, arcs, gif, entryFunc);
 }
 
@@ -73,14 +74,15 @@ export class CollectionFreeFormInfoState extends ObservableReactComponent<Collec
     }
 
     clearState = () => this._disposers.map(disposer => disposer());
-    initState = () => (this._disposers = 
-        this.Arcs.map(arc => ({ test: arc[0], act: arc[1] })).map(
-            arc => reaction(
-                arc.test,
-                res => res && this._props.next(arc.act(res)),
-                { fireImmediately: true }
-            )
-        )); // prettier-ignore
+    initState = () => {
+        this._disposers = this.Arcs
+            .map(arc => ({ test: arc[0], act: arc[1] }))
+            .map(arc => reaction(
+                    arc.test,
+                    res => res && this._props.next(arc.act(res)),
+                    { fireImmediately: true }
+                )
+        )}; // prettier-ignore
 
     componentDidMount() {
         this.initState();
@@ -97,10 +99,15 @@ export class CollectionFreeFormInfoState extends ObservableReactComponent<Collec
     render() {
         const gif = this.State?.[StateMessageGIF];
         return (
-            <div className={'collectionFreeform-infoUI'}>
+            <div className="collectionFreeform-infoUI">
                 <p className="collectionFreeform-infoUI-msg">
                     {this.State?.[StateMessage]}
-                    <button className={'collectionFreeform-' + (!gif ? 'hidden' : 'infoUI-button')} onClick={action(() => (this._expanded = !this._expanded))}>
+                    <button
+                        type="button"
+                        className={'collectionFreeform-' + (!gif ? 'hidden' : 'infoUI-button')}
+                        onClick={action(() => {
+                            this._expanded = !this._expanded;
+                        })}>
                         {this._expanded ? 'Less...' : 'More...'}
                     </button>
                 </p>
@@ -108,7 +115,7 @@ export class CollectionFreeFormInfoState extends ObservableReactComponent<Collec
                     <img src={`/assets/${gif}`} alt="state message gif" />
                 </div>
                 <div className="collectionFreeform-infoUI-close">
-                    <IconButton icon="x" color={SettingsManager.userColor} size={Size.XSMALL} type={Type.TERT} background={SettingsManager.userBackgroundColor} onClick={action(e => this.props.close())} />
+                    <IconButton icon="x" color={SettingsManager.userColor} size={Size.XSMALL} type={Type.TERT} background={SettingsManager.userBackgroundColor} onClick={action(() => this.props.close())} />
                 </div>
             </div>
         );
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 3970c6807..a4496a417 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -147,10 +147,10 @@ export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Do
         }
         const val = Field.toString(pair.layout[pivotFieldKey] as FieldType);
         if (listValue) {
-            listValue.forEach((val, i) => {
-                !pivotColumnGroups.get(val) && pivotColumnGroups.set(val, { docs: [], filters: [val], replicas: [] });
-                pivotColumnGroups.get(val)!.docs.push(pair.layout);
-                pivotColumnGroups.get(val)!.replicas.push(i.toString());
+            listValue.forEach((lval, i) => {
+                !pivotColumnGroups.get(lval) && pivotColumnGroups.set(lval, { docs: [], filters: [lval], replicas: [] });
+                pivotColumnGroups.get(lval)!.docs.push(pair.layout);
+                pivotColumnGroups.get(lval)!.replicas.push(i.toString());
             });
         } else if (val) {
             !pivotColumnGroups.get(val) && pivotColumnGroups.set(val, { docs: [], filters: [val], replicas: [] });
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
index 35394016d..f64c6715b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
@@ -4,9 +4,7 @@ import * as mobxUtils from 'mobx-utils';
 import * as React from 'react';
 import * as uuid from 'uuid';
 import CursorField from '../../../../fields/CursorField';
-import { Doc, FieldResult } from '../../../../fields/Doc';
 import { Id } from '../../../../fields/FieldSymbols';
-import { List } from '../../../../fields/List';
 import { listSpec } from '../../../../fields/Schema';
 import { Cast } from '../../../../fields/Types';
 import { CollectionViewProps } from '../CollectionSubView';
@@ -16,14 +14,12 @@ import './CollectionFreeFormView.scss';
 export class CollectionFreeFormRemoteCursors extends React.Component<CollectionViewProps> {
     @computed protected get cursors(): CursorField[] {
         const { Document } = this.props;
-
-        let cursors: FieldResult<List<CursorField>>;
-        const id = Doc.UserDoc()[Id];
-        if (!id || !(cursors = Cast(Document.cursors, listSpec(CursorField)))) {
+        const cursors = Cast(Document.cursors, listSpec(CursorField));
+        if (!cursors) {
             return [];
         }
         const now = mobxUtils.now();
-        return (cursors || []).filter(({ data: { metadata } }) => metadata.id !== id && now - metadata.timestamp < 1000);
+        return (cursors || []).filter(({ data: { metadata } }) => metadata.id !== Document[Id] && now - metadata.timestamp < 1000);
     }
 
     @computed get renderedCursors() {
@@ -33,46 +29,44 @@ export class CollectionFreeFormRemoteCursors extends React.Component<CollectionV
                     metadata,
                     position: { x, y },
                 },
-            }) => {
-                return (
-                    <div key={metadata.id} className="collectionFreeFormRemoteCursors-cont" style={{ transform: `translate(${x - 10}px, ${y - 10}px)` }}>
-                        <canvas
-                            className="collectionFreeFormRemoteCursors-canvas"
-                            ref={el => {
-                                if (el) {
-                                    const ctx = el.getContext('2d');
-                                    if (ctx) {
-                                        ctx.fillStyle = '#' + uuid.v5(metadata.id, uuid.v5.URL).substring(0, 6).toUpperCase() + '22';
-                                        ctx.fillRect(0, 0, 20, 20);
+            }) => (
+                <div key={metadata.id} className="collectionFreeFormRemoteCursors-cont" style={{ transform: `translate(${x - 10}px, ${y - 10}px)` }}>
+                    <canvas
+                        className="collectionFreeFormRemoteCursors-canvas"
+                        ref={el => {
+                            if (el) {
+                                const ctx = el.getContext('2d');
+                                if (ctx) {
+                                    ctx.fillStyle = '#' + uuid.v5(metadata.id, uuid.v5.URL).substring(0, 6).toUpperCase() + '22';
+                                    ctx.fillRect(0, 0, 20, 20);
 
-                                        ctx.fillStyle = 'black';
-                                        ctx.lineWidth = 0.5;
+                                    ctx.fillStyle = 'black';
+                                    ctx.lineWidth = 0.5;
 
-                                        ctx.beginPath();
+                                    ctx.beginPath();
 
-                                        ctx.moveTo(10, 0);
-                                        ctx.lineTo(10, 8);
+                                    ctx.moveTo(10, 0);
+                                    ctx.lineTo(10, 8);
 
-                                        ctx.moveTo(10, 20);
-                                        ctx.lineTo(10, 12);
+                                    ctx.moveTo(10, 20);
+                                    ctx.lineTo(10, 12);
 
-                                        ctx.moveTo(0, 10);
-                                        ctx.lineTo(8, 10);
+                                    ctx.moveTo(0, 10);
+                                    ctx.lineTo(8, 10);
 
-                                        ctx.moveTo(20, 10);
-                                        ctx.lineTo(12, 10);
+                                    ctx.moveTo(20, 10);
+                                    ctx.lineTo(12, 10);
 
-                                        ctx.stroke();
-                                    }
+                                    ctx.stroke();
                                 }
-                            }}
-                            width={20}
-                            height={20}
-                        />
-                        <p className="collectionFreeFormRemoteCursors-symbol">{metadata.identifier[0].toUpperCase()}</p>
-                    </div>
-                );
-            }
+                            }
+                        }}
+                        width={20}
+                        height={20}
+                    />
+                    <p className="collectionFreeFormRemoteCursors-symbol">{metadata.identifier[0].toUpperCase()}</p>
+                </div>
+            )
         );
     }
 
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
index 79cc534dc..adac5a102 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
@@ -9,6 +9,7 @@ import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
 
 @observer
 export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> {
+    // eslint-disable-next-line no-use-before-define
     static Instance: MarqueeOptionsMenu;
 
     public createCollection: (e: KeyboardEvent | React.PointerEvent | undefined, group?: boolean) => void = unimplementedFunction;
@@ -29,14 +30,13 @@ export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> {
     }
 
     render() {
-        const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ width: 19 }} />;
         const buttons = (
             <>
-                <IconButton tooltip={'Create a Collection'} onPointerDown={this.createCollection} icon={<FontAwesomeIcon icon="object-group" />} color={this.userColor} />
-                <IconButton tooltip={'Create a Grouping'} onPointerDown={e => this.createCollection(e, true)} icon={<FontAwesomeIcon icon="layer-group" />} color={this.userColor} />
-                <IconButton tooltip={'Summarize Documents'} onPointerDown={this.summarize} icon={<FontAwesomeIcon icon="compress-arrows-alt" />} color={this.userColor} />
-                <IconButton tooltip={'Delete Documents'} onPointerDown={this.delete} icon={<FontAwesomeIcon icon="trash-alt" />} color={this.userColor} />
-                <IconButton tooltip={'Pin selected region'} onPointerDown={this.pinWithView} icon={<FontAwesomeIcon icon="map-pin" />} color={this.userColor} />
+                <IconButton tooltip="Create a Collection" onPointerDown={this.createCollection} icon={<FontAwesomeIcon icon="object-group" />} color={this.userColor} />
+                <IconButton tooltip="Create a Grouping" onPointerDown={e => this.createCollection(e, true)} icon={<FontAwesomeIcon icon="layer-group" />} color={this.userColor} />
+                <IconButton tooltip="Summarize Documents" onPointerDown={this.summarize} icon={<FontAwesomeIcon icon="compress-arrows-alt" />} color={this.userColor} />
+                <IconButton tooltip="Delete Documents" onPointerDown={this.delete} icon={<FontAwesomeIcon icon="trash-alt" />} color={this.userColor} />
+                <IconButton tooltip="Pin selected region" onPointerDown={this.pinWithView} icon={<FontAwesomeIcon icon="map-pin" />} color={this.userColor} />
             </>
         );
         return this.getElement(buttons);
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index ab6788e6f..1634daaf7 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -17,6 +17,7 @@ import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
 import { CollectionSubView } from '../CollectionSubView';
 import './CollectionGridView.scss';
 import Grid, { Layout } from './Grid';
+
 @observer
 export class CollectionGridView extends CollectionSubView() {
     private _containerRef: React.RefObject<HTMLDivElement> = React.createRef();
@@ -77,15 +78,13 @@ export class CollectionGridView extends CollectionSubView() {
                 pairs.forEach((pair, i) => {
                     const existing = oldLayouts.find(l => l.i === pair.layout[Id]);
                     if (existing) newLayouts.push(existing);
-                    else {
-                        if (Object.keys(this.dropLocation).length) {
-                            // external drop
-                            this.addLayoutItem(newLayouts, this.makeLayoutItem(pair.layout, this.dropLocation as { x: number; y: number }, !this.flexGrid));
-                            this.dropLocation = {};
-                        } else {
-                            // internal drop
-                            this.addLayoutItem(newLayouts, this.makeLayoutItem(pair.layout, this.unflexedPosition(i), !this.flexGrid));
-                        }
+                    else if (Object.keys(this.dropLocation).length) {
+                        // external drop
+                        this.addLayoutItem(newLayouts, this.makeLayoutItem(pair.layout, this.dropLocation as { x: number; y: number }, !this.flexGrid));
+                        this.dropLocation = {};
+                    } else {
+                        // internal drop
+                        this.addLayoutItem(newLayouts, this.makeLayoutItem(pair.layout, this.unflexedPosition(i), !this.flexGrid));
                     }
                 });
                 pairs?.length && this.setLayoutList(newLayouts);
@@ -140,9 +139,7 @@ export class CollectionGridView extends CollectionSubView() {
     /**
      * Creates a layout object for a grid item
      */
-    makeLayoutItem = (doc: Doc, pos: { x: number; y: number }, Static: boolean = false, w: number = this.defaultW, h: number = this.defaultH) => {
-        return { i: doc[Id], w, h, x: pos.x, y: pos.y, static: Static };
-    };
+    makeLayoutItem = (doc: Doc, pos: { x: number; y: number }, Static: boolean = false, w: number = this.defaultW, h: number = this.defaultH) => ({ i: doc[Id], w, h, x: pos.x, y: pos.y, static: Static });
 
     /**
      * Adds a layout to the list of layouts.
@@ -190,6 +187,7 @@ export class CollectionGridView extends CollectionSubView() {
     getDisplayDoc(layout: Doc, dxf: () => Transform, width: () => number, height: () => number) {
         return (
             <DocumentView
+                // eslint-disable-next-line react/jsx-props-no-spreading
                 {...this._props}
                 NativeWidth={returnZero}
                 NativeHeight={returnZero}
@@ -219,7 +217,7 @@ export class CollectionGridView extends CollectionSubView() {
         if (this.flexGrid) {
             const savedLayouts = this.savedLayoutList;
             this.childLayoutPairs.forEach(({ layout: doc }) => {
-                const gridLayout = savedLayouts.find(gridLayout => gridLayout.i === doc[Id]);
+                const gridLayout = savedLayouts.find(layout => layout.i === doc[Id]);
                 if (gridLayout) Object.assign(gridLayout, layoutArray.find(layout => layout.i === doc[Id]) || gridLayout);
             });
 
@@ -318,7 +316,9 @@ export class CollectionGridView extends CollectionSubView() {
             e,
             returnFalse,
             action(() => {
-                undoBatch(() => (this.Document.gridRowHeight = this._rowHeight))();
+                undoBatch(() => {
+                    this.Document.gridRowHeight = this._rowHeight;
+                })();
                 this._rowHeight = undefined;
             }),
             emptyFunction,
@@ -332,8 +332,20 @@ export class CollectionGridView extends CollectionSubView() {
      */
     onContextMenu = () => {
         const displayOptionsMenu: ContextMenuProps[] = [];
-        displayOptionsMenu.push({ description: 'Toggle Content Display Style', event: () => (this.Document.display = this.Document.display ? undefined : 'contents'), icon: 'copy' });
-        displayOptionsMenu.push({ description: 'Toggle Vertical Centering', event: () => (this.Document.centerY = !this.Document.centerY), icon: 'copy' });
+        displayOptionsMenu.push({
+            description: 'Toggle Content Display Style',
+            event: () => {
+                this.Document.display = this.Document.display ? undefined : 'contents';
+            },
+            icon: 'copy',
+        });
+        displayOptionsMenu.push({
+            description: 'Toggle Vertical Centering',
+            event: () => {
+                this.Document.centerY = !this.Document.centerY;
+            },
+            icon: 'copy',
+        });
         ContextMenu.Instance.addItem({ description: 'Display', subitems: displayOptionsMenu, icon: 'tv' });
     };
 
@@ -347,14 +359,14 @@ export class CollectionGridView extends CollectionSubView() {
                 e,
                 returnFalse,
                 returnFalse,
-                (e: PointerEvent, doubleTap?: boolean) => {
-                    if (doubleTap && !e.button) {
+                (clickEv: PointerEvent, doubleTap?: boolean) => {
+                    if (doubleTap && !clickEv.button) {
                         undoBatch(
                             action(() => {
                                 const text = Docs.Create.TextDocument('', { _width: 150, _height: 50 });
                                 FormattedTextBox.SetSelectOnLoad(text); // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
                                 Doc.AddDocToList(this.Document, this._props.fieldKey, text);
-                                this.setLayoutList(this.addLayoutItem(this.savedLayoutList, this.makeLayoutItem(text, this.screenToCell(e.clientX, e.clientY))));
+                                this.setLayoutList(this.addLayoutItem(this.savedLayoutList, this.makeLayoutItem(text, this.screenToCell(clickEv.clientX, clickEv.clientY))));
                             })
                         )();
                     }
@@ -387,7 +399,7 @@ export class CollectionGridView extends CollectionSubView() {
                         width={this._props.PanelWidth()}
                         nodeList={this.contents.length ? this.contents : null}
                         layout={this.contents.length ? this.renderedLayoutList : undefined}
-                        childrenDraggable={this._props.isSelected() ? true : false}
+                        childrenDraggable={!!this._props.isSelected()}
                         numCols={this.numCols}
                         rowHeight={this.rowHeight}
                         setLayout={this.setLayout}
diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
index 6635ab222..e68ed0e17 100644
--- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
+++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
@@ -15,7 +15,8 @@ import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../
 import { CollectionViewType } from '../../../documents/DocumentTypes';
 import { BranchingTrailManager } from '../../../util/BranchingTrailManager';
 import { DocumentManager } from '../../../util/DocumentManager';
-import { DragManager, dropActionType } from '../../../util/DragManager';
+import { DragManager } from '../../../util/DragManager';
+import { dropActionType } from '../../../util/DropActionTypes';
 import { SettingsManager } from '../../../util/SettingsManager';
 import { Transform } from '../../../util/Transform';
 import { UndoStack } from '../../UndoStack';
diff --git a/src/client/views/collections/collectionLinear/index.ts b/src/client/views/collections/collectionLinear/index.ts
index ff73e14ae..ab3b4b0b5 100644
--- a/src/client/views/collections/collectionLinear/index.ts
+++ b/src/client/views/collections/collectionLinear/index.ts
@@ -1 +1 @@
-export * from "./CollectionLinearView";
\ No newline at end of file
+export * from './CollectionLinearView';
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index 125dd2781..b8509a005 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -1,3 +1,5 @@
+/* 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 { Button, IconButton } from 'browndash-components';
@@ -7,7 +9,7 @@ import * as React from 'react';
 import { FaChevronRight } from 'react-icons/fa';
 import { Doc, DocListCast } from '../../../../fields/Doc';
 import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
-import { DragManager, dropActionType } from '../../../util/DragManager';
+import { DragManager } from '../../../util/DragManager';
 import { SettingsManager } from '../../../util/SettingsManager';
 import { Transform } from '../../../util/Transform';
 import { undoBatch, undoable } from '../../../util/UndoManager';
@@ -16,6 +18,7 @@ import { CollectionSubView } from '../CollectionSubView';
 import './CollectionMulticolumnView.scss';
 import ResizeBar from './MulticolumnResizer';
 import WidthLabel from './MulticolumnWidthLabel';
+import { dropActionType } from '../../../util/DropActionTypes';
 
 interface WidthSpecifier {
     magnitude: number;
@@ -80,7 +83,7 @@ export class CollectionMulticolumnView extends CollectionSubView() {
     private get resolvedLayoutInformation(): LayoutData {
         let starSum = 0;
         const widthSpecifiers: WidthSpecifier[] = [];
-        this.childLayouts.map(layout => {
+        this.childLayouts.forEach(layout => {
             const unit = StrCast(layout._dimUnit, '*');
             const magnitude = NumCast(layout._dimMagnitude, this.minimumDim);
             if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) {
@@ -140,6 +143,7 @@ export class CollectionMulticolumnView extends CollectionSubView() {
         if (layoutInfoLen > 0 && this.totalFixedAllocation !== undefined) {
             return this._props.PanelWidth() - (this.totalFixedAllocation + resizerWidth * (layoutInfoLen - 1)) - 2 * NumCast(this.Document._xMargin);
         }
+        return undefined;
     }
 
     /**
@@ -159,6 +163,7 @@ export class CollectionMulticolumnView extends CollectionSubView() {
         if (this.resolvedLayoutInformation && this.totalRatioAllocation !== undefined) {
             return this.totalRatioAllocation / this.resolvedLayoutInformation.starSum;
         }
+        return undefined;
     }
 
     /**
@@ -175,7 +180,7 @@ export class CollectionMulticolumnView extends CollectionSubView() {
      * or the ratio width evaluated to a pixel value
      */
     private lookupPixels = (layout: Doc): number => {
-        const columnUnitLength = this.columnUnitLength;
+        const { columnUnitLength } = this;
         if (columnUnitLength === undefined) {
             return 0; // we're still waiting on promises to resolve
         }
@@ -193,19 +198,19 @@ export class CollectionMulticolumnView extends CollectionSubView() {
      * documents before the target.
      */
     private lookupIndividualTransform = (layout: Doc) => {
-        const columnUnitLength = this.columnUnitLength;
+        const { columnUnitLength } = this;
         if (columnUnitLength === undefined) {
             return Transform.Identity(); // we're still waiting on promises to resolve
         }
         let offset = 0;
-        var xf = Transform.Identity();
-        this.childLayouts.map(candidate => {
+        // eslint-disable-next-line no-restricted-syntax
+        for (const { layout: candidate } of this.childLayoutPairs) {
             if (candidate === layout) {
-                return (xf = this.ScreenToLocalBoxXf().translate(-offset / (this._props.NativeDimScaling?.() || 1), 0));
+                return this.ScreenToLocalBoxXf().translate(0, -offset / (this._props.NativeDimScaling?.() || 1));
             }
             offset += this.lookupPixels(candidate) + resizerWidth;
-        });
-        return xf;
+        }
+        return Transform.Identity();
     };
 
     @undoBatch
@@ -213,7 +218,9 @@ export class CollectionMulticolumnView extends CollectionSubView() {
         let dropInd = -1;
         if (de.complete.docDragData && this._mainCont) {
             let curInd = -1;
-            de.complete.docDragData?.droppedDocuments.forEach(d => (curInd = this.childDocs.indexOf(d)));
+            de.complete.docDragData?.droppedDocuments.forEach(d => {
+                curInd = this.childDocs.indexOf(d);
+            });
             Array.from(this._mainCont.children).forEach((child, index) => {
                 const brect = child.getBoundingClientRect();
                 if (brect.x < de.x && brect.x + brect.width > de.x) {
@@ -265,7 +272,6 @@ export class CollectionMulticolumnView extends CollectionSubView() {
             this.lookupIndividualTransform(childLayout)
                 .translate(-NumCast(this.layoutDoc._xMargin), -NumCast(this.layoutDoc._yMargin))
                 .scale(this._props.NativeDimScaling?.() || 1);
-        const shouldNotScale = () => this._props.fitContentsToBox?.() || BoolCast(childLayout.freeform_fitContentsToBox);
         return (
             <DocumentView
                 Document={childLayout}
@@ -281,11 +287,11 @@ export class CollectionMulticolumnView extends CollectionSubView() {
                 dragAction={StrCast(this.Document.childDragAction, this._props.childDragAction) as dropActionType}
                 onClickScript={this.onChildClickHandler}
                 onDoubleClickScript={this.onChildDoubleClickHandler}
-                suppressSetHeight={true}
+                suppressSetHeight
                 ScreenToLocalTransform={dxf}
                 isContentActive={this.isChildContentActive}
                 isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive}
-                hideResizeHandles={childLayout.layout_fitWidth || this._props.childHideResizeHandles ? true : false}
+                hideResizeHandles={!!(childLayout.layout_fitWidth || this._props.childHideResizeHandles)}
                 hideDecorationTitle={this._props.childHideDecorationTitle}
                 fitContentsToBox={this._props.fitContentsToBox}
                 focus={this._props.focus}
@@ -312,17 +318,19 @@ export class CollectionMulticolumnView extends CollectionSubView() {
         const collector: JSX.Element[] = [];
         this.childLayouts.forEach((layout, i) => {
             collector.push(
+                // eslint-disable-next-line react/no-array-index-key
                 <Tooltip title={'Tab: ' + StrCast(layout.title)} key={'wrapper' + i}>
                     <div className="document-wrapper" style={{ flexDirection: 'column', width: this.lookupPixels(layout) }}>
                         {this.getDisplayDoc(layout)}
                         {this.layoutDoc._chromeHidden ? null : (
-                            <Button tooltip="Remove document from header bar" icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={undoable(e => this._props.removeDocument?.(layout), 'close doc')} color={SettingsManager.userColor} />
+                            <Button tooltip="Remove document from header bar" icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={undoable(() => this._props.removeDocument?.(layout), 'close doc')} color={SettingsManager.userColor} />
                         )}
                         <WidthLabel layout={layout} collectionDoc={this.Document} />
                     </div>
                 </Tooltip>,
                 <ResizeBar
                     width={resizerWidth}
+                    // eslint-disable-next-line react/no-array-index-key
                     key={'resizer' + i}
                     styleProvider={this._props.styleProvider}
                     isContentActive={this._props.isContentActive}
@@ -353,14 +361,29 @@ export class CollectionMulticolumnView extends CollectionSubView() {
                 {this.contents}
                 {!this._startIndex ? null : (
                     <Tooltip title="scroll back">
-                        <div style={{ position: 'absolute', bottom: 0, left: 0, background: SettingsManager.userVariantColor }} onClick={action(e => (this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown)))}>
-                            <Button tooltip="Scroll back" icon={<FontAwesomeIcon icon="chevron-left" size="lg" />} onClick={action(e => (this._startIndex = Math.max(0, this._startIndex - this.maxShown)))} color={SettingsManager.userColor} />
+                        <div
+                            style={{ position: 'absolute', bottom: 0, left: 0, background: SettingsManager.userVariantColor }}
+                            onClick={action(() => {
+                                this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown);
+                            })}>
+                            <Button
+                                tooltip="Scroll back"
+                                icon={<FontAwesomeIcon icon="chevron-left" size="lg" />}
+                                onClick={action(() => {
+                                    this._startIndex = Math.max(0, this._startIndex - this.maxShown);
+                                })}
+                                color={SettingsManager.userColor}
+                            />
                         </div>
                     </Tooltip>
                 )}
                 {this._startIndex > this.childLayoutPairs.length - 1 || !this.maxShown ? null : (
                     <Tooltip title="scroll forward">
-                        <div style={{ position: 'absolute', bottom: 0, right: 0, background: SettingsManager.userVariantColor }} onClick={action(e => (this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown)))}>
+                        <div
+                            style={{ position: 'absolute', bottom: 0, right: 0, background: SettingsManager.userVariantColor }}
+                            onClick={action(() => {
+                                this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown);
+                            })}>
                             <IconButton icon={<FaChevronRight />} color={SettingsManager.userColor} />
                         </div>
                     </Tooltip>
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 17bf3e50c..3fe3d5343 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -3,7 +3,8 @@ import { observer } from 'mobx-react';
 import * as React from 'react';
 import { Doc, DocListCast } from '../../../../fields/Doc';
 import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
-import { DragManager, dropActionType } from '../../../util/DragManager';
+import { DragManager } from '../../../util/DragManager';
+import { dropActionType } from '../../../util/DropActionTypes';
 import { Transform } from '../../../util/Transform';
 import { undoBatch } from '../../../util/UndoManager';
 import { DocumentView } from '../../nodes/DocumentView';
@@ -11,6 +12,7 @@ import { CollectionSubView } from '../CollectionSubView';
 import './CollectionMultirowView.scss';
 import HeightLabel from './MultirowHeightLabel';
 import ResizeBar from './MultirowResizer';
+
 interface HeightSpecifier {
     magnitude: number;
     unit: string;
@@ -63,7 +65,7 @@ export class CollectionMultirowView extends CollectionSubView() {
     private get resolvedLayoutInformation(): LayoutData {
         let starSum = 0;
         const heightSpecifiers: HeightSpecifier[] = [];
-        this.childLayoutPairs.map(pair => {
+        this.childLayoutPairs.forEach(pair => {
             const unit = StrCast(pair.layout._dimUnit, '*');
             const magnitude = NumCast(pair.layout._dimMagnitude, this.minimumDim);
             if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) {
@@ -123,6 +125,7 @@ export class CollectionMultirowView extends CollectionSubView() {
         if (layoutInfoLen > 0 && this.totalFixedAllocation !== undefined) {
             return this._props.PanelHeight() - (this.totalFixedAllocation + resizerHeight * (layoutInfoLen - 1)) - 2 * NumCast(this.Document._yMargin);
         }
+        return undefined;
     }
 
     /**
@@ -142,6 +145,7 @@ export class CollectionMultirowView extends CollectionSubView() {
         if (this.resolvedLayoutInformation && this.totalRatioAllocation !== undefined) {
             return this.totalRatioAllocation / this.resolvedLayoutInformation.starSum;
         }
+        return undefined;
     }
 
     /**
@@ -158,13 +162,12 @@ export class CollectionMultirowView extends CollectionSubView() {
      * or the ratio width evaluated to a pixel value
      */
     private lookupPixels = (layout: Doc): number => {
-        const rowUnitLength = this.rowUnitLength;
-        if (rowUnitLength === undefined) {
+        if (this.rowUnitLength === undefined) {
             return 0; // we're still waiting on promises to resolve
         }
         let height = NumCast(layout._dimMagnitude, this.minimumDim);
         if (StrCast(layout._dimUnit, '*') === DimUnit.Ratio) {
-            height *= rowUnitLength;
+            height *= this.rowUnitLength;
         }
         return height;
     };
@@ -176,11 +179,11 @@ export class CollectionMultirowView extends CollectionSubView() {
      * documents before the target.
      */
     private lookupIndividualTransform = (layout: Doc) => {
-        const rowUnitLength = this.rowUnitLength;
-        if (rowUnitLength === undefined) {
+        if (this.rowUnitLength === undefined) {
             return Transform.Identity(); // we're still waiting on promises to resolve
         }
         let offset = 0;
+        // eslint-disable-next-line no-restricted-syntax
         for (const { layout: candidate } of this.childLayoutPairs) {
             if (candidate === layout) {
                 return this.ScreenToLocalBoxXf().translate(0, -offset / (this._props.NativeDimScaling?.() || 1));
@@ -195,7 +198,9 @@ export class CollectionMultirowView extends CollectionSubView() {
         let dropInd = -1;
         if (de.complete.docDragData && this._mainCont) {
             let curInd = -1;
-            de.complete.docDragData?.droppedDocuments.forEach(d => (curInd = this.childDocs.indexOf(d)));
+            de.complete.docDragData?.droppedDocuments.forEach(d => {
+                curInd = this.childDocs.indexOf(d);
+            });
             Array.from(this._mainCont.children).forEach((child, index) => {
                 const brect = child.getBoundingClientRect();
                 if (brect.y < de.y && brect.y + brect.height > de.y) {
@@ -247,7 +252,6 @@ export class CollectionMultirowView extends CollectionSubView() {
             this.lookupIndividualTransform(layout)
                 .translate(-NumCast(this.layoutDoc._xMargin), -NumCast(this.layoutDoc._yMargin))
                 .scale(this._props.NativeDimScaling?.() || 1);
-        const shouldNotScale = () => this._props.fitContentsToBox?.() || BoolCast(layout.freeform_fitContentsToBox);
         return (
             <DocumentView
                 Document={layout}
@@ -266,7 +270,7 @@ export class CollectionMultirowView extends CollectionSubView() {
                 ScreenToLocalTransform={dxf}
                 isContentActive={this.isChildContentActive}
                 isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive}
-                hideResizeHandles={layout.layout_fitWidth || this._props.childHideResizeHandles ? true : false}
+                hideResizeHandles={!!(layout.layout_fitWidth || this._props.childHideResizeHandles)}
                 hideDecorationTitle={this._props.childHideDecorationTitle}
                 fitContentsToBox={this._props.fitContentsToBox}
                 focus={this._props.focus}
diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
index d580d9c52..49ba85524 100644
--- a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/require-default-props */
 import { action } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -52,27 +53,6 @@ export default class ResizeBar extends React.Component<ResizerProps> {
         }
     };
 
-    private get isActivated() {
-        const { toLeft, toRight } = this.props;
-        if (toLeft && toRight) {
-            if (StrCast(toLeft._dimUnit, '*') === DimUnit.Pixel && StrCast(toRight._dimUnit, '*') === DimUnit.Pixel) {
-                return false;
-            }
-            return true;
-        } else if (toLeft) {
-            if (StrCast(toLeft._dimUnit, '*') === DimUnit.Pixel) {
-                return false;
-            }
-            return true;
-        } else if (toRight) {
-            if (StrCast(toRight._dimUnit, '*') === DimUnit.Pixel) {
-                return false;
-            }
-            return true;
-        }
-        return false;
-    }
-
     @action
     private onPointerUp = () => {
         window.removeEventListener('pointermove', this.onPointerMove);
@@ -90,7 +70,7 @@ export default class ResizeBar extends React.Component<ResizerProps> {
                     width: this.props.width,
                     backgroundColor: !this.props.isContentActive?.() ? '' : this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor),
                 }}>
-                <div className={'multiColumnResizer-hdl'} onPointerDown={e => this.registerResizing(e)} />
+                <div className="multiColumnResizer-hdl" onPointerDown={e => this.registerResizing(e)} />
             </div>
         );
     }
diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx
index a9579d931..a7a0b3457 100644
--- a/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx
@@ -19,7 +19,7 @@ export default class WidthLabel extends React.Component<WidthLabelProps> {
         const getUnit = () => StrCast(layout.dimUnit);
         const getMagnitude = () => String(+NumCast(layout.dimMagnitude).toFixed(3));
         return (
-            <div className={'label-wrapper'}>
+            <div className="label-wrapper">
                 <EditableView
                     GetValue={getMagnitude}
                     SetValue={value => {
diff --git a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
index 878c7ff3c..66215f109 100644
--- a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/require-default-props */
 import { computed } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -20,7 +21,7 @@ export default class HeightLabel extends React.Component<HeightLabelProps> {
         const getUnit = () => StrCast(layout.dimUnit);
         const getMagnitude = () => String(+NumCast(layout.dimMagnitude).toFixed(decimals ?? 3));
         return (
-            <div className={'label-wrapper'}>
+            <div className="label-wrapper">
                 <EditableView
                     GetValue={getMagnitude}
                     SetValue={value => {
diff --git a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
index 73d08d5ef..ad77c327d 100644
--- a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/require-default-props */
 import { action } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -33,7 +34,7 @@ export default class ResizeBar extends React.Component<ResizerProps> {
     };
 
     private onPointerMove = ({ movementY }: PointerEvent) => {
-        const { toTop: toTop, toBottom: toBottom, columnUnitLength } = this.props;
+        const { toTop, toBottom, columnUnitLength } = this.props;
         const movingDown = movementY > 0;
         const toNarrow = movingDown ? toBottom : toTop;
         const toWiden = movingDown ? toTop : toBottom;
@@ -50,27 +51,6 @@ export default class ResizeBar extends React.Component<ResizerProps> {
         }
     };
 
-    private get isActivated() {
-        const { toTop, toBottom } = this.props;
-        if (toTop && toBottom) {
-            if (StrCast(toTop._dimUnit, '*') === DimUnit.Pixel && StrCast(toBottom._dimUnit, '*') === DimUnit.Pixel) {
-                return false;
-            }
-            return true;
-        } else if (toTop) {
-            if (StrCast(toTop._dimUnit, '*') === DimUnit.Pixel) {
-                return false;
-            }
-            return true;
-        } else if (toBottom) {
-            if (StrCast(toBottom._dimUnit, '*') === DimUnit.Pixel) {
-                return false;
-            }
-            return true;
-        }
-        return false;
-    }
-
     @action
     private onPointerUp = () => {
         window.removeEventListener('pointermove', this.onPointerMove);
@@ -88,7 +68,7 @@ export default class ResizeBar extends React.Component<ResizerProps> {
                     height: this.props.height,
                     backgroundColor: !this.props.isContentActive?.() ? '' : this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor),
                 }}>
-                <div className={'multiRowResizer-hdl'} onPointerDown={e => this.registerResizing(e)} />
+                <div className="multiRowResizer-hdl" onPointerDown={e => this.registerResizing(e)} />
             </div>
         );
     }
diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
index 2823e1936..389fc66b3 100644
--- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
@@ -1,5 +1,6 @@
+/* eslint-disable react/no-unused-prop-types */
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, observable } from 'mobx';
+import { action } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { setupMoveUpEvents } from '../../../../ClientUtils';
@@ -25,8 +26,6 @@ export interface SchemaColumnHeaderProps {
 
 @observer
 export class SchemaColumnHeader extends React.Component<SchemaColumnHeaderProps> {
-    @observable _ref: HTMLDivElement | null = null;
-
     get fieldKey() {
         return this.props.columnKeys[this.props.columnIndex];
     }
@@ -35,9 +34,9 @@ export class SchemaColumnHeader extends React.Component<SchemaColumnHeaderProps>
     sortClicked = (e: React.PointerEvent) => {
         e.stopPropagation();
         e.preventDefault();
-        if (this.props.sortField == this.fieldKey && this.props.sortDesc) {
+        if (this.props.sortField === this.fieldKey && this.props.sortDesc) {
             this.props.setSort(undefined);
-        } else if (this.props.sortField == this.fieldKey) {
+        } else if (this.props.sortField === this.fieldKey) {
             this.props.setSort(this.fieldKey, true);
         } else {
             this.props.setSort(this.fieldKey, false);
@@ -46,7 +45,7 @@ export class SchemaColumnHeader extends React.Component<SchemaColumnHeaderProps>
 
     @action
     onPointerDown = (e: React.PointerEvent) => {
-        this.props.isContentActive(true) && setupMoveUpEvents(this, e, e => this.props.dragColumn(e, this.props.columnIndex), emptyFunction, emptyFunction, false);
+        this.props.isContentActive(true) && setupMoveUpEvents(this, e, moveEv => this.props.dragColumn(moveEv, this.props.columnIndex), emptyFunction, emptyFunction, false);
     };
 
     render() {
@@ -59,19 +58,18 @@ export class SchemaColumnHeader extends React.Component<SchemaColumnHeaderProps>
                 onPointerDown={this.onPointerDown}
                 ref={col => {
                     if (col) {
-                        this._ref = col;
                         this.props.setColRef(this.props.columnIndex, col);
                     }
                 }}>
-                <div className="schema-column-resizer left" onPointerDown={e => this.props.resizeColumn(e, this.props.columnIndex)}></div>
+                <div className="schema-column-resizer left" onPointerDown={e => this.props.resizeColumn(e, this.props.columnIndex)} />
                 <div className="schema-column-title">{this.fieldKey}</div>
 
                 <div className="schema-header-menu">
                     <div className="schema-header-button" onPointerDown={e => this.props.openContextMenu(e.clientX, e.clientY, this.props.columnIndex)}>
                         <FontAwesomeIcon icon="ellipsis-h" />
                     </div>
-                    <div className="schema-sort-button" onPointerDown={this.sortClicked} style={this.props.sortField == this.fieldKey ? { backgroundColor: Colors.MEDIUM_BLUE } : {}}>
-                        <FontAwesomeIcon icon="caret-right" style={this.props.sortField == this.fieldKey ? { transform: `rotate(${this.props.sortDesc ? '270deg' : '90deg'})` } : {}} />
+                    <div className="schema-sort-button" onPointerDown={this.sortClicked} style={this.props.sortField === this.fieldKey ? { backgroundColor: Colors.MEDIUM_BLUE } : {}}>
+                        <FontAwesomeIcon icon="caret-right" style={this.props.sortField === this.fieldKey ? { transform: `rotate(${this.props.sortDesc ? '270deg' : '90deg'})` } : {}} />
                     </div>
                 </div>
             </div>
diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
index 27a4493cb..61afe08cf 100644
--- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
@@ -63,7 +63,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
         }
     };
 
-    onPointerEnter = (e: any) => {
+    onPointerEnter = () => {
         if (SnappingManager.IsDragging && this._props.isContentActive()) {
             document.removeEventListener('pointermove', this.onPointerMove);
             document.addEventListener('pointermove', this.onPointerMove);
@@ -75,7 +75,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
 
         if (this._ref && dragIsRow) {
             const rect = this._ref.getBoundingClientRect();
-            const y = e.clientY - rect.top; //y position within the element.
+            const y = e.clientY - rect.top; // y position within the element.
             const height = this._ref.clientHeight;
             const halfLine = height / 2;
             if (y <= halfLine) {
@@ -90,7 +90,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
         }
     };
 
-    onPointerLeave = (e: any) => {
+    onPointerLeave = () => {
         if (this._ref) {
             this._ref.style.borderTop = '0px';
             this._ref.style.borderBottom = '0px';
@@ -131,15 +131,16 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
                                 e,
                                 returnFalse,
                                 emptyFunction,
-                                undoable(e => {
-                                    e.stopPropagation();
+                                undoable(clickEv => {
+                                    clickEv.stopPropagation();
                                     Doc.toggleLockedPosition(this.Document);
                                 }, 'Delete Row')
                             )
-                        }></IconButton>
+                        }
+                    />
                     <IconButton
                         tooltip="close"
-                        icon={<CgClose size={'16px'} />}
+                        icon={<CgClose size="16px" />}
                         size={Size.XSMALL}
                         onPointerDown={e =>
                             setupMoveUpEvents(
@@ -147,8 +148,8 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
                                 e,
                                 returnFalse,
                                 emptyFunction,
-                                undoable(e => {
-                                    e.stopPropagation();
+                                undoable(clickEv => {
+                                    clickEv.stopPropagation();
                                     this._props.removeDocument?.(this.Document);
                                 }, 'Delete Row')
                             )
@@ -164,8 +165,8 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
                                 e,
                                 returnFalse,
                                 emptyFunction,
-                                undoable(e => {
-                                    e.stopPropagation();
+                                undoable(clickEv => {
+                                    clickEv.stopPropagation();
                                     this._props.addDocTab(this.Document, OpenWhere.addRight);
                                 }, 'Open schema Doc preview')
                             )
diff --git a/src/client/views/global/globalEnums.tsx b/src/client/views/global/globalEnums.tsx
index 610c2b102..2cf9e4162 100644
--- a/src/client/views/global/globalEnums.tsx
+++ b/src/client/views/global/globalEnums.tsx
@@ -1,44 +1,44 @@
 export enum Colors {
-    BLACK = "#000000",
-    DARK_GRAY = "#323232",
-    MEDIUM_GRAY = "#9F9F9F",
-    LIGHT_GRAY = "#DFDFDF",
-    WHITE = "#FFFFFF",
-    MEDIUM_BLUE = "#4476F7",
-    MEDIUM_BLUE_ALT = "#4476f73d", // REDUCED OPACITY
-    LIGHT_BLUE = "#BDDDF5",
-    PINK = "#E0217D",
-    ERROR_RED = "#ff0033",
-    YELLOW = "#F5D747",
-    DROP_SHADOW = "#32323215",
+    BLACK = '#000000',
+    DARK_GRAY = '#323232',
+    MEDIUM_GRAY = '#9F9F9F',
+    LIGHT_GRAY = '#DFDFDF',
+    WHITE = '#FFFFFF',
+    MEDIUM_BLUE = '#4476F7',
+    MEDIUM_BLUE_ALT = '#4476f73d', // REDUCED OPACITY
+    LIGHT_BLUE = '#BDDDF5',
+    PINK = '#E0217D',
+    ERROR_RED = '#ff0033',
+    YELLOW = '#F5D747',
+    DROP_SHADOW = '#32323215',
 }
 
 export enum FontSizes {
-    //Bolded
-    LARGE_HEADER = "16px",
+    // Bolded
+    LARGE_HEADER = '16px',
 
-    //Bolded or unbolded
-    BODY_TEXT = "12px",
+    // Bolded or unbolded
+    BODY_TEXT = '12px',
 
-    //Bolded
-    SMALL_TEXT = "9px",
+    // Bolded
+    SMALL_TEXT = '9px',
 }
 
 export enum Padding {
-    MINIMUM_PADDING = "4px",
-    SMALL_PADDING = "8px",
-    MEDIUM_PADDING = "16px",
-    LARGE_PADDING = "32px",
+    MINIMUM_PADDING = '4px',
+    SMALL_PADDING = '8px',
+    MEDIUM_PADDING = '16px',
+    LARGE_PADDING = '32px',
 }
 
 export enum IconSizes {
-    ICON_SIZE = "28px",
+    ICON_SIZE = '28px',
 }
 
 export enum Borders {
-    STANDARD = "solid 1px #9F9F9F"
+    STANDARD = 'solid 1px #9F9F9F',
 }
 
 export enum Shadows {
-    STANDARD_SHADOW = "0px 3px 4px rgba(0, 0, 0, 0.3)"
-}
\ No newline at end of file
+    STANDARD_SHADOW = '0px 3px 4px rgba(0, 0, 0, 0.3)',
+}
diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx
index 60def5d45..f99a18db2 100644
--- a/src/client/views/linking/LinkMenuGroup.tsx
+++ b/src/client/views/linking/LinkMenuGroup.tsx
@@ -1,14 +1,17 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
+/* eslint-disable react/require-default-props */
+import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
-import { observable, action } from 'mobx';
+import * as React from 'react';
 import { Doc, StrListCast } from '../../../fields/Doc';
 import { Id } from '../../../fields/FieldSymbols';
 import { Cast, DocCast } from '../../../fields/Types';
+import { DocumentType } from '../../documents/DocumentTypes';
 import { LinkManager } from '../../util/LinkManager';
 import { DocumentView } from '../nodes/DocumentView';
 import './LinkMenu.scss';
 import { LinkMenuItem } from './LinkMenuItem';
-import * as React from 'react';
-import { DocumentType } from '../../documents/DocumentTypes';
 
 interface LinkMenuGroupProps {
     sourceDoc: Doc;
@@ -22,25 +25,24 @@ interface LinkMenuGroupProps {
 @observer
 export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
     private _menuRef = React.createRef<HTMLDivElement>();
+    @observable _collapsed = false;
 
     getBackgroundColor = (): string | undefined => {
-        const link_relationshipList = StrListCast(Doc.UserDoc().link_relationshipList);
+        const linkRelationshipList = StrListCast(Doc.UserDoc().link_relationshipList);
         const linkColorList = StrListCast(Doc.UserDoc().link_ColorList);
         let color: string | undefined;
         // if this link's relationship property is not default "link", set its color
-        if (link_relationshipList) {
-            const relationshipIndex = link_relationshipList.indexOf(this.props.groupType);
+        if (linkRelationshipList) {
+            const relationshipIndex = linkRelationshipList.indexOf(this.props.groupType);
             const RGBcolor: string = linkColorList[relationshipIndex];
             if (RGBcolor) {
-                //set opacity to 0.25 by modifiying the rgb string
+                // set opacity to 0.25 by modifiying the rgb string
                 color = RGBcolor.slice(0, RGBcolor.length - 1) + ', 0.25)';
             }
         }
         return color;
     };
 
-    @observable _collapsed = false;
-
     render() {
         const set = new Set<Doc>(this.props.group);
         const groupItems = Array.from(set.keys()).map(linkDoc => {
@@ -76,7 +78,12 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
 
         return (
             <div className="linkMenu-group" ref={this._menuRef}>
-                <div className="linkMenu-group-name" onClick={action(() => (this._collapsed = !this._collapsed))} style={{ background: this.getBackgroundColor() }}>
+                <div
+                    className="linkMenu-group-name"
+                    onClick={action(() => {
+                        this._collapsed = !this._collapsed;
+                    })}
+                    style={{ background: this.getBackgroundColor() }}>
                     <p className={this.props.groupType === '*' || this.props.groupType === '' ? '' : 'expand-one'}> {this.props.groupType}:</p>
                 </div>
                 {this._collapsed ? null : <div className="linkMenu-group-wrapper">{groupItems}</div>}
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index 9be78a6cb..303ff4b98 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -92,10 +92,10 @@ export class LinkMenuItem extends ObservableReactComponent<LinkMenuItemProps> {
         setupMoveUpEvents(
             this,
             e,
-            e => {
+            moveEv => {
                 const dragData = new DragManager.DocumentDragData([this._props.linkDoc], dropActionType.embed);
                 dragData.dropPropertiesToRemove = ['hidden'];
-                DragManager.StartDocumentDrag([this._editRef.current!], dragData, e.x, e.y);
+                DragManager.StartDocumentDrag([this._editRef.current!], dragData, moveEv.x, moveEv.y);
                 return true;
             },
             emptyFunction,
@@ -125,10 +125,10 @@ export class LinkMenuItem extends ObservableReactComponent<LinkMenuItemProps> {
         setupMoveUpEvents(
             this,
             e,
-            e => {
+            moveEv => {
                 const eleClone: any = this._drag.current!.cloneNode(true);
-                eleClone.style.transform = `translate(${e.x}px, ${e.y}px)`;
-                StartLinkTargetsDrag(eleClone, this._props.docView, e.x, e.y, this._props.sourceDoc, [this._props.linkDoc]);
+                eleClone.style.transform = `translate(${moveEv.x}px, ${moveEv.y}px)`;
+                StartLinkTargetsDrag(eleClone, this._props.docView, moveEv.x, moveEv.y, this._props.sourceDoc, [this._props.linkDoc]);
                 this._props.clearLinkEditor?.();
                 return true;
             },
diff --git a/src/client/views/linking/LinkRelationshipSearch.tsx b/src/client/views/linking/LinkRelationshipSearch.tsx
deleted file mode 100644
index 0902d53b2..000000000
--- a/src/client/views/linking/LinkRelationshipSearch.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-import { observer } from 'mobx-react';
-import * as React from 'react';
-import './LinkEditor.scss';
-
-interface link_relationshipSearchProps {
-    results: string[] | undefined;
-    display: string;
-    //callback fn to set rel + hide dropdown upon setting
-    handleRelationshipSearchChange: (result: string) => void;
-    toggleSearch: () => void;
-}
-@observer
-export class link_relationshipSearch extends React.Component<link_relationshipSearchProps> {
-    handleResultClick = (e: React.MouseEvent) => {
-        const relationship = (e.target as HTMLParagraphElement).textContent;
-        if (relationship) {
-            this.props.handleRelationshipSearchChange(relationship);
-        }
-    };
-
-    handleMouseEnter = () => {
-        this.props.toggleSearch();
-    };
-
-    handleMouseLeave = () => {
-        this.props.toggleSearch();
-    };
-
-    /**
-     * Render an empty div to increase the height of LinkEditor to accommodate 2+ results
-     */
-    emptyDiv = () => {
-        if (this.props.results && this.props.results.length > 2 && this.props.display === 'block') {
-            return <div style={{ height: '50px' }} />;
-        }
-    };
-
-    render() {
-        return (
-            <div className="linkEditor-relationship-dropdown-container">
-                <div className="linkEditor-relationship-dropdown" style={{ display: this.props.display }} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
-                    {
-                        // return a dropdown of relationship results if there exist results
-                        this.props.results ? (
-                            this.props.results.map(result => {
-                                return (
-                                    <p key={result} onClick={this.handleResultClick}>
-                                        {result}
-                                    </p>
-                                );
-                            })
-                        ) : (
-                            <p>No matching relationships</p>
-                        )
-                    }
-                </div>
-
-                {/*Render an empty div to increase the height of LinkEditor to accommodate 2+ results */}
-                {this.emptyDiv()}
-            </div>
-        );
-    }
-}
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index c37466914..9251dca6d 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -532,7 +532,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
                 e,
                 returnFalse,
                 returnFalse,
-                action((e: PointerEvent, doubleTap?: boolean) => {
+                action((moveEv: PointerEvent, doubleTap?: boolean) => {
                     if (doubleTap) {
                         this.startTrim(TrimScope.All);
                     } else if (this.timeline) {
@@ -572,14 +572,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     setupTimelineDrop = (r: HTMLDivElement | null) => {
         if (r && this.timeline) {
             this._dropDisposer?.();
-            this._dropDisposer = DragManager.MakeDropTarget(
-                r,
-                (e, de) => {
-                    const [xp] = this.ScreenToLocalBoxXf().transformPoint(de.x, de.y);
-                    de.complete.docDragData && this.timeline?.internalDocDrop(e, de, de.complete.docDragData, xp);
-                },
-                this.layoutDoc
-            );
+            this._dropDisposer = DragManager.MakeDropTarget(r, (e, de) => de.complete.docDragData && this.timeline?.internalDocDrop(e, de, de.complete.docDragData), this.layoutDoc);
         }
     };
 
diff --git a/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx b/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx
index 0084d7394..60bc8df18 100644
--- a/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx
+++ b/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx
@@ -1,3 +1,5 @@
+/* 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';
@@ -15,56 +17,52 @@ interface SchemaCSVPopUpProps {}
 
 @observer
 export class SchemaCSVPopUp extends React.Component<SchemaCSVPopUpProps> {
+    // eslint-disable-next-line no-use-before-define
     static Instance: SchemaCSVPopUp;
 
-    @observable
-    public dataVizDoc: Doc | undefined = undefined;
+    @observable public dataVizDoc: Doc | undefined = undefined;
+    @observable public view: DocumentView | undefined = undefined;
+    @observable public target: Doc | undefined = undefined;
+    @observable public visible: boolean = false;
+
+    constructor(props: SchemaCSVPopUpProps) {
+        super(props);
+        makeObservable(this);
+        SchemaCSVPopUp.Instance = this;
+    }
+
     @action
     public setDataVizDoc = (doc: Doc) => {
         this.dataVizDoc = doc;
     };
 
-    @observable
-    public view: DocumentView | undefined = undefined;
     @action
     public setView = (docView: DocumentView) => {
         this.view = docView;
     };
 
-    @observable
-    public target: Doc | undefined = undefined;
     @action
     public setTarget = (doc: Doc) => {
         this.target = doc;
     };
 
-    @observable
-    public visible: boolean = false;
     @action
     public setVisible = (vis: boolean) => {
         this.visible = vis;
     };
 
-    constructor(props: SchemaCSVPopUpProps) {
-        super(props);
-        makeObservable(this);
-        SchemaCSVPopUp.Instance = this;
-    }
-
-    dataBox = () => {
-        return (
-            <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
-                {this.heading('Schema Table as Data Visualization Doc')}
-                <div className="image-content-wrapper">
-                    <div className="img-wrapper">
-                        <div className="img-container" onPointerDown={e => this.drag(e)}>
-                            <img width={150} height={150} src={'/assets/dataVizBox.png'} />
-                        </div>
+    dataBox = () => (
+        <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
+            {this.heading('Schema Table as Data Visualization Doc')}
+            <div className="image-content-wrapper">
+                <div className="img-wrapper">
+                    <div className="img-container" onPointerDown={e => this.drag(e)}>
+                        <img width={150} height={150} src="/assets/dataVizBox.png" />
                     </div>
                 </div>
             </div>
-        );
-    };
+        </div>
+    );
 
     heading = (headingText: string) => (
         <div className="summary-heading">
@@ -79,24 +77,22 @@ export class SchemaCSVPopUp extends React.Component<SchemaCSVPopUpProps> {
         setupMoveUpEvents(
             {},
             e,
-            e => {
+            moveEv => {
                 const sourceAnchorCreator = () => this.dataVizDoc!;
-                const targetCreator = (annotationOn: Doc | undefined) => {
+                const targetCreator = () => {
                     const embedding = Doc.MakeEmbedding(this.dataVizDoc!);
                     return embedding;
                 };
-                if (this.view && sourceAnchorCreator && !ClientUtils.isClick(e.clientX, e.clientY, downX, downY, Date.now())) {
-                    DragManager.StartAnchorAnnoDrag(e.target instanceof HTMLElement ? [e.target] : [], new DragManager.AnchorAnnoDragData(this.view, sourceAnchorCreator, targetCreator), downX, downY, {
-                        dragComplete: e => {
-                            this.setVisible(false);
-                        },
+                if (this.view && sourceAnchorCreator && !ClientUtils.isClick(moveEv.clientX, moveEv.clientY, downX, downY, Date.now())) {
+                    DragManager.StartAnchorAnnoDrag(moveEv.target instanceof HTMLElement ? [moveEv.target] : [], new DragManager.AnchorAnnoDragData(this.view, sourceAnchorCreator, targetCreator), downX, downY, {
+                        dragComplete: () => this.setVisible(false),
                     });
                     return true;
                 }
                 return false;
             },
             emptyFunction,
-            action(e => {})
+            action(() => {})
         );
     };
 
diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
index 2735a40d5..910504e7c 100644
--- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
@@ -75,8 +75,8 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
     }
 
     @computed get defaultGraphTitle() {
-        var ax0 = this._props.axes[0];
-        var ax1 = this._props.axes.length > 1 ? this._props.axes[1] : undefined;
+        const ax0 = this._props.axes[0];
+        const ax1 = this._props.axes.length > 1 ? this._props.axes[1] : undefined;
         if (this._props.axes.length < 2 || !/\d/.test(this._props.records[0][ax0]) || !ax1) {
             return ax0 + ' Pie Chart';
         }
@@ -101,8 +101,6 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
         );
     }
 
-    @action
-    restoreView = (data: Doc) => {};
     // create a document anchor that stores whatever is needed to reconstruct the viewing state (selection,zoom,etc)
     getAnchor = (pinProps?: PinProps) => {
         const anchor = Docs.Create.ConfigDocument({
@@ -130,23 +128,23 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
             : validData.map((d: { [x: string]: any }) =>
                   this.byCategory
                       ? d[field] //
-                      : +d[field].replace(/\$/g, '').replace(/\%/g, '').replace(/\#/g, '').replace(/\</g, '')
+                      : +d[field].replace(/\$/g, '').replace(/%/g, '').replace(/#/g, '').replace(/</g, '')
               );
     };
 
     // outlines the slice selected / hovered over
     highlightSelectedSlice = (changeSelectedVariables: boolean, svg: any, arc: any, radius: any, pointer: any, pieDataSet: any) => {
-        var index = -1;
-        var sameAsCurrent: boolean;
+        let index = -1;
+        let sameAsCurrent: boolean;
         const selected = svg.selectAll('.slice').filter((d: any) => {
             index++;
-            var p1 = [0, 0]; // center of pie
-            var p3 = [arc.centroid(d)[0] * 2, arc.centroid(d)[1] * 2]; // outward peak of arc
-            var p2 = [radius * Math.sin(d.startAngle), -radius * Math.cos(d.startAngle)]; // start of arc
-            var p4 = [radius * Math.sin(d.endAngle), -radius * Math.cos(d.endAngle)]; // end of arc
+            const p1 = [0, 0]; // center of pie
+            const p3 = [arc.centroid(d)[0] * 2, arc.centroid(d)[1] * 2]; // outward peak of arc
+            const p2 = [radius * Math.sin(d.startAngle), -radius * Math.cos(d.startAngle)]; // start of arc
+            const p4 = [radius * Math.sin(d.endAngle), -radius * Math.cos(d.endAngle)]; // end of arc
 
             // draw an imaginary horizontal line from the pointer to see how many times it crosses a slice edge
-            var lineCrossCount = 0;
+            let lineCrossCount = 0;
             // if for all 4 lines
             if (Math.min(p1[1], p2[1]) <= pointer[1] && pointer[1] <= Math.max(p1[1], p2[1])) {
                 // within y bounds
@@ -161,13 +159,13 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
             if (Math.min(p4[1], p1[1]) <= pointer[1] && pointer[1] <= Math.max(p4[1], p1[1])) {
                 if (pointer[0] <= ((pointer[1] - p4[1]) * (p1[0] - p4[0])) / (p1[1] - p4[1]) + p4[0]) lineCrossCount++;
             }
-            if (lineCrossCount % 2 != 0) {
+            if (lineCrossCount % 2 !== 0) {
                 // inside the slice of it crosses an odd number of edges
-                var showSelected = this.byCategory ? pieDataSet[index] : this._pieChartData[index];
+                const showSelected = this.byCategory ? pieDataSet[index] : this._pieChartData[index];
                 if (changeSelectedVariables) {
                     // for when a bar is selected - not just hovered over
                     sameAsCurrent = this._currSelected
-                        ? showSelected[Object.keys(showSelected)[0]] == this._currSelected![Object.keys(showSelected)[0]] && showSelected[Object.keys(showSelected)[1]] == this._currSelected![Object.keys(showSelected)[1]]
+                        ? showSelected[Object.keys(showSelected)[0]] === this._currSelected![Object.keys(showSelected)[0]] && showSelected[Object.keys(showSelected)[1]] === this._currSelected![Object.keys(showSelected)[1]]
                         : this._currSelected === showSelected;
                     this._currSelected = sameAsCurrent ? undefined : showSelected;
                     this.selectedData = sameAsCurrent ? undefined : d;
@@ -187,104 +185,100 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
         d3.select(this._piechartRef.current).select('svg').remove();
         d3.select(this._piechartRef.current).select('.tooltip').remove();
 
-        var percentField = Object.keys(dataSet[0])[0];
-        var descriptionField = Object.keys(dataSet[0])[1]!;
-        var radius = Math.min(width, height - this._props.margin.top - this._props.margin.bottom) / 2;
+        let percentField = Object.keys(dataSet[0])[0];
+        let descriptionField = Object.keys(dataSet[0])[1]!;
+        const radius = Math.min(width, height - this._props.margin.top - this._props.margin.bottom) / 2;
 
         // converts data into Objects
-        var data = this.data(dataSet);
-        var pieDataSet = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key] || isNaN(d[key])));
+        let data = this.data(dataSet);
+        let pieDataSet = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key] || isNaN(d[key])));
         if (this.byCategory) {
-            let uniqueCategories = [...new Set(data)];
-            var pieStringDataSet: { frequency: number }[] = [];
+            const uniqueCategories = [...new Set(data)];
+            const pieStringDataSet: { frequency: number }[] = [];
             for (let i = 0; i < uniqueCategories.length; i++) {
                 pieStringDataSet.push({ frequency: 0, [percentField]: uniqueCategories[i] });
             }
             for (let i = 0; i < data.length; i++) {
-                let sliceData = pieStringDataSet.filter((each: any) => each[percentField] == data[i]);
-                sliceData[0].frequency = sliceData[0].frequency + 1;
+                // eslint-disable-next-line no-loop-func
+                const sliceData = pieStringDataSet.filter((each: any) => each[percentField] === data[i]);
+                sliceData[0].frequency += 1;
             }
             pieDataSet = pieStringDataSet;
-            percentField = Object.keys(pieDataSet[0])[0];
-            descriptionField = Object.keys(pieDataSet[0])[1]!;
+            [percentField, descriptionField] = Object.keys(pieDataSet[0]);
             data = this.data(pieStringDataSet);
         }
-        var trackDuplicates: { [key: string]: any } = {};
-        data.forEach((eachData: any) => (!trackDuplicates[eachData] ? (trackDuplicates[eachData] = 0) : null));
+        let trackDuplicates: { [key: string]: any } = {};
+        data.forEach((eachData: any) => {
+            !trackDuplicates[eachData] ? (trackDuplicates[eachData] = 0) : null;
+        });
 
         // initial chart
-        var svg = (this._piechartSvg = d3
+        const svg = (this._piechartSvg = d3
             .select(this._piechartRef.current)
             .append('svg')
             .attr('class', 'graph')
             .attr('width', width + this._props.margin.right + this._props.margin.left)
             .attr('height', height + this._props.margin.top + this._props.margin.bottom)
             .append('g'));
-        let g = svg.append('g').attr('transform', 'translate(' + (width / 2 + this._props.margin.left) + ',' + height / 2 + ')');
-        var pie = d3.pie();
-        var arc = d3.arc().innerRadius(0).outerRadius(radius);
+        const g = svg.append('g').attr('transform', 'translate(' + (width / 2 + this._props.margin.left) + ',' + height / 2 + ')');
+        const pie = d3.pie();
+        const arc = d3.arc().innerRadius(0).outerRadius(radius);
 
+        const updateHighlights = () => {
+            const hoverOverSlice = this.hoverOverData;
+            const { selectedData } = this;
+            svg.selectAll('path').attr('class', (d: any) =>
+                (selectedData && d.startAngle === selectedData.startAngle && d.endAngle === selectedData.endAngle) || (hoverOverSlice && d.startAngle === hoverOverSlice.startAngle && d.endAngle === hoverOverSlice.endAngle) ? 'slice hover' : 'slice'
+            );
+        };
         // click/hover
         const onPointClick = action((e: any) => this.highlightSelectedSlice(true, svg, arc, radius, d3.pointer(e), pieDataSet));
         const onHover = action((e: any) => {
             this.highlightSelectedSlice(false, svg, arc, radius, d3.pointer(e), pieDataSet);
             updateHighlights();
         });
-        const mouseOut = action((e: any) => {
+        const mouseOut = action(() => {
             this.hoverOverData = undefined;
             updateHighlights();
         });
-        const updateHighlights = () => {
-            const hoverOverSlice = this.hoverOverData;
-            const selectedData = this.selectedData;
-            svg.selectAll('path').attr('class', function (d: any) {
-                return (selectedData && d.startAngle == selectedData.startAngle && d.endAngle == selectedData.endAngle) || (hoverOverSlice && d.startAngle == hoverOverSlice.startAngle && d.endAngle == hoverOverSlice.endAngle)
-                    ? 'slice hover'
-                    : 'slice';
-            });
-        };
 
         // drawing the slices
-        var selected = this.selectedData;
-        var arcs = g.selectAll('arc').data(pie(data)).enter().append('g');
+        const selected = this.selectedData;
+        const arcs = g.selectAll('arc').data(pie(data)).enter().append('g');
         const possibleDataPointVals: { [x: string]: any }[] = [];
         pieDataSet.forEach((each: { [x: string]: any | { valueOf(): number } }) => {
-            var dataPointVal: { [x: string]: any } = {};
+            const dataPointVal: { [x: string]: any } = {};
             dataPointVal[percentField] = each[percentField];
             if (descriptionField) dataPointVal[descriptionField] = each[descriptionField];
             try {
-                dataPointVal[percentField] = Number(dataPointVal[percentField].replace(/\$/g, '').replace(/\%/g, '').replace(/\#/g, '').replace(/\</g, ''));
-            } catch (error) {}
+                dataPointVal[percentField] = Number(dataPointVal[percentField].replace(/\$/g, '').replace(/%/g, '').replace(/#/g, '').replace(/</g, ''));
+            } catch (error) {
+                /* empty */
+            }
             possibleDataPointVals.push(dataPointVal);
         });
         const sliceColors = StrListCast(this._props.layoutDoc.dataViz_pie_sliceColors).map(each => each.split('::'));
         arcs.append('path')
             .attr('fill', (d, i) => {
-                var dataPoint;
+                let dataPoint;
                 const possibleDataPoints = possibleDataPointVals.filter((pval: any) => pval[percentField] === Number(d.data));
-                if (possibleDataPoints.length == 1) dataPoint = possibleDataPoints[0];
+                if (possibleDataPoints.length === 1) [dataPoint] = possibleDataPoints;
                 else {
                     dataPoint = possibleDataPoints[trackDuplicates[d.data.toString()]];
                     trackDuplicates[d.data.toString()] = trackDuplicates[d.data.toString()] + 1;
                 }
-                var sliceColor;
+                let sliceColor;
                 if (dataPoint) {
                     const sliceTitle = dataPoint[this._props.axes[0]];
-                    const accessByName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/\%/g, '').replace(/\#/g, '').replace(/\</g, '') : sliceTitle;
-                    sliceColors.forEach(each => each[0] == accessByName && (sliceColor = each[1]));
+                    const accessByName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/%/g, '').replace(/#/g, '').replace(/</g, '') : sliceTitle;
+                    sliceColors.forEach(each => {
+                        // eslint-disable-next-line prefer-destructuring
+                        each[0] === accessByName && (sliceColor = each[1]);
+                    });
                 }
                 return sliceColor ? StrCast(sliceColor) : d3.schemeSet3[i] ? d3.schemeSet3[i] : d3.schemeSet3[i % d3.schemeSet3.length];
             })
-            .attr(
-                'class',
-                selected
-                    ? function (d) {
-                          return selected && d.startAngle == selected.startAngle && d.endAngle == selected.endAngle ? 'slice hover' : 'slice';
-                      }
-                    : function (d) {
-                          return 'slice';
-                      }
-            )
+            .attr('class', selected ? d => (selected && d.startAngle === selected.startAngle && d.endAngle === selected.endAngle ? 'slice hover' : 'slice') : () => 'slice')
             // @ts-ignore
             .attr('d', arc)
             .on('click', onPointClick)
@@ -293,20 +287,22 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
 
         // adding labels
         trackDuplicates = {};
-        data.forEach((eachData: any) => (!trackDuplicates[eachData] ? (trackDuplicates[eachData] = 0) : null));
+        data.forEach((eachData: any) => {
+            !trackDuplicates[eachData] ? (trackDuplicates[eachData] = 0) : null;
+        });
         arcs.size() < 100 &&
             arcs
                 .append('text')
-                .attr('transform', function (d) {
-                    var centroid = arc.centroid(d as unknown as d3.DefaultArcObject);
-                    var heightOffset = (centroid[1] / radius) * Math.abs(centroid[1]);
+                .attr('transform', d => {
+                    const centroid = arc.centroid(d as unknown as d3.DefaultArcObject);
+                    const heightOffset = (centroid[1] / radius) * Math.abs(centroid[1]);
                     return 'translate(' + (centroid[0] + centroid[0] / (radius * 0.02)) + ',' + (centroid[1] + heightOffset) + ')';
                 })
                 .attr('text-anchor', 'middle')
-                .text(function (d) {
-                    var dataPoint;
+                .text(d => {
+                    let dataPoint;
                     const possibleDataPoints = possibleDataPointVals.filter((pval: any) => pval[percentField] === Number(d.data));
-                    if (possibleDataPoints.length == 1) dataPoint = pieDataSet[possibleDataPointVals.indexOf(possibleDataPoints[0])];
+                    if (possibleDataPoints.length === 1) dataPoint = pieDataSet[possibleDataPointVals.indexOf(possibleDataPoints[0])];
                     else {
                         dataPoint = pieDataSet[possibleDataPointVals.indexOf(possibleDataPoints[trackDuplicates[d.data.toString()]])];
                         trackDuplicates[d.data.toString()] = trackDuplicates[d.data.toString()] + 1;
@@ -318,11 +314,11 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
     @action changeSelectedColor = (color: string) => {
         this.curSliceSelected.attr('fill', color);
         const sliceTitle = this._currSelected[this._props.axes[0]];
-        const sliceName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/\%/g, '').replace(/\#/g, '').replace(/\</g, '') : sliceTitle;
+        const sliceName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/%/g, '').replace(/#/g, '').replace(/</g, '') : sliceTitle;
 
         const sliceColors = Cast(this._props.layoutDoc.dataViz_pie_sliceColors, listSpec('string'), null);
-        sliceColors.map(each => {
-            if (each.split('::')[0] == sliceName) sliceColors.splice(sliceColors.indexOf(each), 1);
+        sliceColors.forEach(each => {
+            if (each.split('::')[0] === sliceName) sliceColors.splice(sliceColors.indexOf(each), 1);
         });
         sliceColors.push(StrCast(sliceName + '::' + color));
     };
@@ -333,38 +329,39 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
     };
 
     render() {
-        var titleAccessor: any = 'dataViz_pie_title';
-        if (this._props.axes.length == 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1];
-        else if (this._props.axes.length > 0) titleAccessor = titleAccessor + this._props.axes[0];
+        let titleAccessor: any = 'dataViz_pie_title';
+        if (this._props.axes.length === 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1];
+        else if (this._props.axes.length > 0) titleAccessor += this._props.axes[0];
         if (!this._props.layoutDoc[titleAccessor]) this._props.layoutDoc[titleAccessor] = this.defaultGraphTitle;
         if (!this._props.layoutDoc.dataViz_pie_sliceColors) this._props.layoutDoc.dataViz_pie_sliceColors = new List<string>();
-        var selected: string;
-        var curSelectedSliceName = '';
+        let selected: string;
+        let curSelectedSliceName = '';
         if (this._currSelected) {
             selected = '{ ';
             const sliceTitle = this._currSelected[this._props.axes[0]];
-            curSelectedSliceName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/\%/g, '').replace(/\#/g, '').replace(/\</g, '') : sliceTitle;
-            Object.keys(this._currSelected).map(key => {
-                key != '' ? (selected += key + ': ' + this._currSelected[key] + ', ') : '';
+            curSelectedSliceName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/%/g, '').replace(/#/g, '').replace(/</g, '') : sliceTitle;
+            Object.keys(this._currSelected).forEach(key => {
+                key !== '' ? (selected += key + ': ' + this._currSelected[key] + ', ') : '';
             });
             selected = selected.substring(0, selected.length - 2);
             selected += ' }';
-            if (this._props.titleCol != '' && (!this._currSelected['frequency'] || this._currSelected['frequency'] < 10)) {
+            if (this._props.titleCol !== '' && (!this._currSelected.frequency || this._currSelected.frequency < 10)) {
                 selected += '\n' + this._props.titleCol + ': ';
                 this._tableData.forEach(each => {
-                    if (this._currSelected[this._props.axes[0]] == each[this._props.axes[0]]) {
+                    if (this._currSelected[this._props.axes[0]] === each[this._props.axes[0]]) {
                         if (this._props.axes[1]) {
-                            if (this._currSelected[this._props.axes[1]] == each[this._props.axes[1]]) selected += each[this._props.titleCol] + ', ';
+                            if (this._currSelected[this._props.axes[1]] === each[this._props.axes[1]]) selected += each[this._props.titleCol] + ', ';
                         } else selected += each[this._props.titleCol] + ', ';
                     }
                 });
                 selected = selected.slice(0, -1).slice(0, -1);
             }
         } else selected = 'none';
-        var selectedSliceColor;
-        var sliceColors = StrListCast(this._props.layoutDoc.dataViz_pie_sliceColors).map(each => each.split('::'));
+        let selectedSliceColor;
+        const sliceColors = StrListCast(this._props.layoutDoc.dataViz_pie_sliceColors).map(each => each.split('::'));
         sliceColors.forEach(each => {
-            if (each[0] == curSelectedSliceName!) selectedSliceColor = each[1];
+            // eslint-disable-next-line prefer-destructuring
+            if (each[0] === curSelectedSliceName!) selectedSliceColor = each[1];
         });
 
         if (this._pieChartData.length > 0 || !this.parentViz) {
@@ -374,30 +371,32 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
                         <EditableText
                             val={StrCast(this._props.layoutDoc[titleAccessor])}
                             setVal={undoable(
-                                action(val => (this._props.layoutDoc[titleAccessor] = val as string)),
+                                action(val => {
+                                    this._props.layoutDoc[titleAccessor] = val as string;
+                                }),
                                 'Change Graph Title'
                             )}
-                            color={'black'}
+                            color="black"
                             size={Size.LARGE}
                             fillWidth
                         />
                     </div>
                     {this._props.axes.length === 1 && /\d/.test(this._props.records[0][this._props.axes[0]]) ? (
-                        <div className={'asHistogram-checkBox'} style={{ width: this._props.width }}>
+                        <div className="asHistogram-checkBox" style={{ width: this._props.width }}>
                             <Checkbox color="primary" onChange={this.changeHistogramCheckBox} checked={this._props.layoutDoc.dataViz_pie_asHistogram as boolean} />
                             Organize data as histogram
                         </div>
                     ) : null}
                     <div ref={this._piechartRef} />
-                    {selected != 'none' ? (
-                        <div className={'selected-data'}>
+                    {selected !== 'none' ? (
+                        <div className="selected-data">
                             Selected: {selected}
                             &nbsp; &nbsp;
                             <ColorPicker
-                                tooltip={'Change Slice Color'}
+                                tooltip="Change Slice Color"
                                 type={Type.SEC}
                                 icon={<FaFillDrip />}
-                                selectedColor={selectedSliceColor ? selectedSliceColor : this.curSliceSelected.attr('fill')}
+                                selectedColor={selectedSliceColor || this.curSliceSelected.attr('fill')}
                                 setFinalColor={undoable(color => this.changeSelectedColor(color), 'Change Selected Slice Color')}
                                 setSelectedColor={undoable(color => this.changeSelectedColor(color), 'Change Selected Slice Color')}
                                 size={Size.XSMALL}
@@ -406,12 +405,12 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
                     ) : null}
                 </div>
             ) : (
-                <span className="chart-container"> {'first use table view to select a column to graph'}</span>
-            );
-        } else
-            return (
-                // when it is a brushed table and the incoming table doesn't have any rows selected
-                <div className="chart-container">Selected rows of data from the incoming DataVizBox to display.</div>
+                <span className="chart-container"> first use table view to select a column to graph</span>
             );
+        }
+        return (
+            // when it is a brushed table and the incoming table doesn't have any rows selected
+            <div className="chart-container">Selected rows of data from the incoming DataVizBox to display.</div>
+        );
     }
 }
diff --git a/src/client/views/nodes/DataVizBox/utils/D3Utils.ts b/src/client/views/nodes/DataVizBox/utils/D3Utils.ts
index 336935d23..be05c3529 100644
--- a/src/client/views/nodes/DataVizBox/utils/D3Utils.ts
+++ b/src/client/views/nodes/DataVizBox/utils/D3Utils.ts
@@ -5,11 +5,11 @@ import { DataPoint } from '../components/LineChart';
 
 export const minMaxRange = (dataPts: DataPoint[][]) => {
     // find the max and min of all the data points
-    const yMin = d3.min(dataPts, d => d3.min(d, d => Number(d.y)));
-    const yMax = d3.max(dataPts, d => d3.max(d, d => Number(d.y)));
+    const yMin = d3.min(dataPts, d => d3.min(d, m => Number(m.y)));
+    const yMax = d3.max(dataPts, d => d3.max(d, m => Number(m.y)));
 
-    const xMin = d3.min(dataPts, d => d3.min(d, d => Number(d.x)));
-    const xMax = d3.max(dataPts, d => d3.max(d, d => Number(d.x)));
+    const xMin = d3.min(dataPts, d => d3.min(d, m => Number(m.x)));
+    const xMax = d3.max(dataPts, d => d3.max(d, m => Number(m.x)));
 
     return { xMin, xMax, yMin, yMax };
 };
@@ -20,18 +20,15 @@ export const scaleCreatorCategorical = (labels: string[], range: number[]) => {
     return scale;
 };
 
-export const scaleCreatorNumerical = (domA: number, domB: number, rangeA: number, rangeB: number) => {
-    return d3.scaleLinear().domain([domA, domB]).range([rangeA, rangeB]);
-};
+export const scaleCreatorNumerical = (domA: number, domB: number, rangeA: number, rangeB: number) => d3.scaleLinear().domain([domA, domB]).range([rangeA, rangeB]);
 
-export const createLineGenerator = (xScale: d3.ScaleLinear<number, number, never>, yScale: d3.ScaleLinear<number, number, never>) => {
+export const createLineGenerator = (xScale: d3.ScaleLinear<number, number, never>, yScale: d3.ScaleLinear<number, number, never>) =>
     // TODO: nda - look into the different types of curves
-    return d3
+    d3
         .line<DataPoint>()
         .x(d => xScale(d.x))
         .y(d => yScale(d.y))
         .curve(d3.curveMonotoneX);
-};
 
 export const xAxisCreator = (g: d3.Selection<SVGGElement, unknown, null, undefined>, height: number, xScale: d3.ScaleLinear<number, number, never>) => {
     g.attr('class', 'x-axis').attr('transform', `translate(0,${height})`).call(d3.axisBottom(xScale).tickSize(15));
@@ -48,7 +45,7 @@ export const xGrid = (g: d3.Selection<SVGGElement, unknown, null, undefined>, he
             d3
                 .axisBottom(scale)
                 .tickSize(-height)
-                .tickFormat((a, b) => '')
+                .tickFormat((/* a, b */) => '')
         );
 };
 
@@ -57,10 +54,16 @@ export const yGrid = (g: d3.Selection<SVGGElement, unknown, null, undefined>, wi
         d3
             .axisLeft(scale)
             .tickSize(-width)
-            .tickFormat((a, b) => '')
+            .tickFormat((/* a, b */) => '')
     );
 };
 
 export const drawLine = (p: d3.Selection<SVGPathElement, unknown, null, undefined>, dataPts: DataPoint[], lineGen: d3.Line<DataPoint>, extra: boolean) => {
-    p.datum(dataPts).attr('fill', 'none').attr('stroke', 'rgba(53, 162, 235, 0.5)').attr('stroke-width', 2).attr('stroke', extra? 'blue' : 'black').attr('class', 'line').attr('d', lineGen);
+    p.datum(dataPts)
+        .attr('fill', 'none')
+        .attr('stroke', 'rgba(53, 162, 235, 0.5)')
+        .attr('stroke-width', 2)
+        .attr('stroke', extra ? 'blue' : 'black')
+        .attr('class', 'line')
+        .attr('d', lineGen);
 };
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index a029b3761..9b4e36509 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -92,7 +92,7 @@ export class DocumentLinksButton extends ObservableReactComponent<DocumentLinksB
             e,
             this.onLinkButtonMoved,
             emptyFunction,
-            action((e, doubleTap) => {
+            action((clickEv, doubleTap) => {
                 doubleTap && DocumentView.showBackLinks(this._props.View.Document);
             }),
             undefined,
@@ -109,7 +109,7 @@ export class DocumentLinksButton extends ObservableReactComponent<DocumentLinksB
             e,
             this.onLinkButtonMoved,
             emptyFunction,
-            action((e, doubleTap) => {
+            action((clickEv, doubleTap) => {
                 if (doubleTap && this._props.InMenu && this._props.StartLink) {
                     // action(() => Doc.BrushDoc(this._props.View.Document));
                     if (DocumentLinksButton.StartLink === this._props.View.Document) {
@@ -146,7 +146,7 @@ export class DocumentLinksButton extends ObservableReactComponent<DocumentLinksB
             e,
             returnFalse,
             emptyFunction,
-            action(e => DocumentLinksButton.finishLinkClick(e.clientX, e.clientY, DocumentLinksButton.StartLink, this._props.View.Document, true, this._props.View))
+            action(clickEv => DocumentLinksButton.finishLinkClick(clickEv.clientX, clickEv.clientY, DocumentLinksButton.StartLink, this._props.View.Document, true, this._props.View))
         );
     };
 
diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx
index 9be66ba4a..9c216cba4 100644
--- a/src/client/views/nodes/EquationBox.tsx
+++ b/src/client/views/nodes/EquationBox.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
 import { action, makeObservable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -42,7 +43,7 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
                     this._ref.current!.mathField.latex(text);
                 }
             }
-            //{ fireImmediately: true }
+            // { fireImmediately: true }
         );
         reaction(
             () => this._props.isSelected(),
@@ -88,7 +89,9 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
         if (e.key === 'Backspace' && !this.dataDoc.text) this._props.removeDocument?.(this.Document);
     };
     @undoBatch
-    onChange = (str: string) => (this.dataDoc.text = str);
+    onChange = (str: string) => {
+        this.dataDoc.text = str;
+    };
 
     updateSize = () => {
         const style = this._ref.current && getComputedStyle(this._ref.current.element.current);
@@ -111,7 +114,7 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
         const scale = (this._props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._freeform_scale, 1);
         return (
             <div
-                ref={r => this.updateSize()}
+                ref={() => this.updateSize()}
                 className="equationBox-cont"
                 onPointerDown={e => !e.ctrlKey && e.stopPropagation()}
                 style={{
@@ -122,7 +125,7 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
                     fontSize: StrCast(this.layoutDoc._text_fontSize),
                 }}
                 onKeyDown={e => e.stopPropagation()}>
-                <EquationEditor ref={this._ref} value={StrCast(this.dataDoc.text, 'x')} spaceBehavesLikeTab={true} onChange={this.onChange} autoCommands="pi theta sqrt sum prod alpha beta gamma rho" autoOperatorNames="sin cos tan" />
+                <EquationEditor ref={this._ref} value={StrCast(this.dataDoc.text, 'x')} spaceBehavesLikeTab onChange={this.onChange} autoCommands="pi theta sqrt sum prod alpha beta gamma rho" autoOperatorNames="sin cos tan" />
             </div>
         );
     }
diff --git a/src/client/views/nodes/FaceRectangle.tsx b/src/client/views/nodes/FaceRectangle.tsx
index 46bc6eb03..2b66b83fe 100644
--- a/src/client/views/nodes/FaceRectangle.tsx
+++ b/src/client/views/nodes/FaceRectangle.tsx
@@ -8,11 +8,17 @@ export default class FaceRectangle extends React.Component<{ rectangle: Rectangl
     @observable private opacity = 0;
 
     componentDidMount() {
-        setTimeout(() => runInAction(() => (this.opacity = 1)), 500);
+        setTimeout(
+            () =>
+                runInAction(() => {
+                    this.opacity = 1;
+                }),
+            500
+        );
     }
 
     render() {
-        const rectangle = this.props.rectangle;
+        const { rectangle } = this.props;
         return (
             <div
                 style={{
diff --git a/src/client/views/nodes/FontIconBox/ButtonInterface.ts b/src/client/views/nodes/FontIconBox/ButtonInterface.ts
index 1c034bfbe..0d0d7b1c3 100644
--- a/src/client/views/nodes/FontIconBox/ButtonInterface.ts
+++ b/src/client/views/nodes/FontIconBox/ButtonInterface.ts
@@ -1,5 +1,5 @@
-import { Doc } from '../../../../fields/Doc';
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
+import { Doc } from '../../../../fields/Doc';
 import { ButtonType } from './FontIconBox';
 
 export interface IButtonProps {
diff --git a/src/client/views/nodes/FontIconBox/TrailsIcon.tsx b/src/client/views/nodes/FontIconBox/TrailsIcon.tsx
index 09fd6e3ae..76f00b2f4 100644
--- a/src/client/views/nodes/FontIconBox/TrailsIcon.tsx
+++ b/src/client/views/nodes/FontIconBox/TrailsIcon.tsx
@@ -1,10 +1,11 @@
 import * as React from 'react';
 
-const TrailsIcon = (fill: string) => (
-    <svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 1080.000000 1080.000000" preserveAspectRatio="xMidYMid meet">
-        <g transform="translate(0.000000,1080.000000) scale(0.100000,-0.100000)" fill={fill} stroke="none">
-            <path
-                d="M665 9253 c-74 -10 -157 -38 -240 -81 -74 -37 -107 -63 -186 -141
+function TrailsIcon(fill: string) {
+    return (
+        <svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 1080.000000 1080.000000" preserveAspectRatio="xMidYMid meet">
+            <g transform="translate(0.000000,1080.000000) scale(0.100000,-0.100000)" fill={fill} stroke="none">
+                <path
+                    d="M665 9253 c-74 -10 -157 -38 -240 -81 -74 -37 -107 -63 -186 -141
 -104 -104 -156 -191 -201 -334 l-23 -72 0 -3215 c0 -3072 1 -3218 18 -3280 10
 -36 39 -108 64 -160 40 -82 59 -107 142 -190 81 -81 111 -103 191 -143 52 -26
 122 -55 155 -65 57 -16 322 -17 4775 -20 3250 -2 4736 1 4784 8 256 39 486
@@ -14,68 +15,69 @@ const TrailsIcon = (fill: string) => (
 -62 -101 -108 -126 l-42 -22 -4435 -3 c-3954 -2 -4440 0 -4481 13 -26 9 -63
 33 -87 56 -79 79 -72 -205 -72 3012 0 2156 3 2889 12 2918 20 70 91 136 168
 160 14 4 2010 8 4436 8 3710 1 4418 -1 4456 -13z"
-            />
-            <path
-                d="M7692 7839 c-46 -14 -109 -80 -122 -128 -7 -27 -9 -472 -8 -1443 l3
+                />
+                <path
+                    d="M7692 7839 c-46 -14 -109 -80 -122 -128 -7 -27 -9 -472 -8 -1443 l3
 -1403 24 -38 c13 -21 42 -50 64 -65 l41 -27 816 0 816 0 41 27 c22 15 51 44
 64 65 l24 38 0 1425 0 1425 -24 38 c-13 21 -42 50 -64 65 l-41 27 -800 2
 c-488 1 -814 -2 -834 -8z"
-            />
-            <path
-                d="M1982 7699 c-46 -14 -109 -80 -122 -128 -7 -27 -10 -308 -8 -893 l3
+                />
+                <path
+                    d="M1982 7699 c-46 -14 -109 -80 -122 -128 -7 -27 -10 -308 -8 -893 l3
 -853 24 -38 c13 -21 42 -50 64 -65 l41 -27 1386 0 1386 0 41 27 c22 15 51 44
 64 65 l24 38 0 876 0 875 -27 41 c-15 22 -44 51 -65 64 l-38 24 -1370 2 c-847
 1 -1383 -2 -1403 -8z"
-            />
-            <path
-                d="M6413 7093 c-13 -2 -23 -9 -23 -15 0 -24 21 -307 26 -343 l5 -40 182
+                />
+                <path
+                    d="M6413 7093 c-13 -2 -23 -9 -23 -15 0 -24 21 -307 26 -343 l5 -40 182
 -1 c200 -1 307 -15 484 -65 57 -16 107 -29 112 -29 5 0 36 75 69 168 33 92 63
 175 67 184 6 14 -10 22 -92 48 -126 39 -308 76 -447 89 -106 11 -337 13 -383
 4z"
-            />
-            <path
-                d="M5840 7033 c-63 -8 -238 -29 -388 -47 -150 -18 -274 -35 -276 -37 -2
+                />
+                <path
+                    d="M5840 7033 c-63 -8 -238 -29 -388 -47 -150 -18 -274 -35 -276 -37 -2
 -2 8 -89 23 -194 22 -163 29 -190 44 -193 10 -2 91 6 180 17 89 12 258 32 376
 46 118 14 216 27 218 28 7 8 -43 391 -52 392 -5 1 -62 -4 -125 -12z"
-            />
-            <path
-                d="M4762 4789 c-46 -14 -109 -80 -122 -128 -7 -27 -10 -323 -8 -943 l3
+                />
+                <path
+                    d="M4762 4789 c-46 -14 -109 -80 -122 -128 -7 -27 -10 -323 -8 -943 l3
 -903 24 -38 c13 -21 42 -50 64 -65 l41 -27 926 0 926 0 41 27 c22 15 51 44 64
 65 l24 38 0 926 0 925 -27 41 c-15 22 -44 51 -65 64 l-38 24 -910 2 c-557 1
 -923 -2 -943 -8z"
-            />
-            <path
-                d="M8487 4297 c-26 -215 -161 -474 -307 -585 -27 -20 -49 -40 -49 -44
+                />
+                <path
+                    d="M8487 4297 c-26 -215 -161 -474 -307 -585 -27 -20 -49 -40 -49 -44
 -1 -3 49 -79 110 -167 l110 -161 44 31 c176 126 333 350 418 594 30 86 77 282
 77 320 0 8 -57 19 -167 34 -93 13 -182 25 -199 28 -31 5 -31 5 -37 -50z"
-            />
-            <path
-                d="M3965 4233 c-106 -9 -348 -36 -415 -47 -55 -8 -75 -15 -74 -26 1 -20
+                />
+                <path
+                    d="M3965 4233 c-106 -9 -348 -36 -415 -47 -55 -8 -75 -15 -74 -26 1 -20
 56 -374 59 -377 1 -2 46 4 101 12 159 24 409 45 526 45 l108 0 0 200 0 200
 -132 -2 c-73 -1 -151 -3 -173 -5z"
-            />
-            <path
-                d="M3020 4079 c-85 -23 -292 -94 -368 -125 -97 -40 -298 -140 -305 -151
+                />
+                <path
+                    d="M3020 4079 c-85 -23 -292 -94 -368 -125 -97 -40 -298 -140 -305 -151
 -5 -7 172 -315 192 -336 4 -4 41 10 82 32 103 55 272 123 414 165 66 20 125
 38 132 41 11 4 -4 70 -78 348 -10 39 -14 41 -69 26z"
-            />
-            <path
-                d="M6955 3538 c-21 -91 -74 -362 -72 -364 7 -7 260 -44 367 -54 146 -13
+                />
+                <path
+                    d="M6955 3538 c-21 -91 -74 -362 -72 -364 7 -7 260 -44 367 -54 146 -13
 359 -13 475 0 49 6 90 12 91 13 2 1 -12 90 -29 197 -26 155 -36 194 -47 192
 -8 -2 -85 -6 -170 -9 -160 -6 -357 7 -505 33 -103 18 -104 18 -110 -8z"
-            />
-            <path
-                d="M1993 3513 c-52 -67 -71 -106 -98 -198 -35 -122 -44 -284 -21 -415 9
+                />
+                <path
+                    d="M1993 3513 c-52 -67 -71 -106 -98 -198 -35 -122 -44 -284 -21 -415 9
 -51 18 -96 21 -98 4 -5 360 79 375 88 7 4 7 24 0 60 -21 109 -7 244 31 307
 l20 31 -146 131 c-80 72 -147 131 -149 131 -2 0 -17 -17 -33 -37z"
-            />
-            <path
-                d="M2210 2519 c-91 -50 -166 -92 -168 -94 -2 -1 11 -26 28 -54 l32 -51
+                />
+                <path
+                    d="M2210 2519 c-91 -50 -166 -92 -168 -94 -2 -1 11 -26 28 -54 l32 -51
 244 0 c134 0 244 2 244 5 0 3 -23 33 -51 67 -28 35 -72 98 -97 140 -26 43 -51
 77 -57 77 -5 0 -84 -41 -175 -90z"
-            />
-        </g>
-    </svg>
-);
+                />
+            </g>
+        </svg>
+    );
+}
 
 export default TrailsIcon;
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx
index bff6d53da..d43241de0 100644
--- a/src/client/views/nodes/LinkAnchorBox.tsx
+++ b/src/client/views/nodes/LinkAnchorBox.tsx
@@ -45,7 +45,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() {
     onPointerDown = (e: React.PointerEvent) => {
         const { linkSource } = this;
         linkSource &&
-            setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, (e, doubleTap) => {
+            setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, (clickEv, doubleTap) => {
                 if (doubleTap) LinkFollower.FollowLink(this.Document, linkSource, false);
                 else this._props.select(false);
             });
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 2593491cc..f01905ee1 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-unused-vars */
 import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -50,15 +51,19 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
         this._props.setContentViewBox?.(this);
         this._disposers.deleting = reaction(
             () => !this.anchor1 && !this.anchor2 && this.DocumentView?.() && (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView!())),
-            empty => empty && ((this._hackToSeeIfDeleted = setTimeout(() => 
-                (!this.anchor1 && !this.anchor2) && this._props.removeDocument?.(this.Document)
-            )), 1000) // prettier-ignore
+            empty => {
+                if (empty) {
+                    this._hackToSeeIfDeleted = setTimeout(() => {
+                        !this.anchor1 && !this.anchor2 && this._props.removeDocument?.(this.Document);
+                    }, 1000);
+                }
+            }
         );
         this._disposers.dragging = reaction(
             () => SnappingManager.IsDragging,
             () => setTimeout( action(() => {// need to wait for drag manager to set 'hidden' flag on dragged DOM elements
-                const a = this.anchor1,
-                      b = this.anchor2;
+                const a = this.anchor1;
+                const b = this.anchor2;
                 let a1 = a && document.getElementById(a.ViewGuid);
                 let a2 = b && document.getElementById(b.ViewGuid);
                 // test whether the anchors themselves are hidden,...
@@ -67,7 +72,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
                     // .. or whether any of their DOM parents are hidden
                     for (; a1 && !a1.hidden; a1 = a1.parentElement);
                     for (; a2 && !a2.hidden; a2 = a2.parentElement);
-                    this._hide = a1 || a2 ? true : false;
+                    this._hide = !!(a1 || a2);
                 }
             })) // prettier-ignore
         );
@@ -92,24 +97,25 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
             a.Document[DocCss];
             b.Document[DocCss];
 
+            // eslint-disable-next-line @typescript-eslint/no-unused-vars
             const axf = a.screenToViewTransform(); // these force re-render when a or b moves (so do NOT remove)
             const bxf = b.screenToViewTransform();
             const scale = docView?.screenToViewTransform().Scale ?? 1;
             const at = a.getBounds?.transition; // these force re-render when a or b change size and at the end of an animated transition
             const bt = b.getBounds?.transition; //    inquring getBounds() also causes text anchors to update whether or not they reflow (any size change triggers an invalidation)
 
-            var foundParent = false;
+            let foundParent = false;
             const getAnchor = (field: FieldResult): Element[] => {
                 const docField = DocCast(field);
                 const doc = docField?.layout_unrendered ? DocCast(docField.annotationOn, docField) : docField;
                 const ele = document.getElementById(DocumentView.UniquifyId(LightboxView.Contains(this.DocumentView?.()), doc[Id]));
                 if (ele?.className === 'linkBox-label') foundParent = true;
                 if (ele?.getBoundingClientRect().width) return [ele];
-                const eles = Array.from(document.getElementsByClassName(doc[Id])).filter(ele => ele?.getBoundingClientRect().width);
+                const eles = Array.from(document.getElementsByClassName(doc[Id])).filter(el => el?.getBoundingClientRect().width);
                 const annoOn = DocCast(doc.annotationOn);
                 if (eles.length || !annoOn) return eles;
                 const pareles = getAnchor(annoOn);
-                foundParent = pareles.length ? true : false;
+                foundParent = !!pareles.length;
                 return pareles;
             };
             //   if there's an element in the DOM with a classname containing a link anchor's id (eg a hypertext <a>),
@@ -122,26 +128,38 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
             const aid = targetAhyperlinks?.find(alink => container?.contains(alink))?.id ?? targetAhyperlinks?.lastElement()?.id;
             const bid = targetBhyperlinks?.find(blink => container?.contains(blink))?.id ?? targetBhyperlinks?.lastElement()?.id;
             if (!aid || !bid) {
-                setTimeout(action(() => (this._forceAnimate = this._forceAnimate + 0.01)));
+                setTimeout(
+                    action(() => {
+                        this._forceAnimate += 0.01;
+                    })
+                );
                 return null;
             }
             if (foundParent) {
                 setTimeout(
-                    action(() => (this._forceAnimate = this._forceAnimate + 0.01)),
+                    action(() => {
+                        this._forceAnimate += 0.01;
+                    }),
                     1
                 );
             }
 
-            if (at || bt) setTimeout(action(() => (this._forceAnimate = this._forceAnimate + 0.01))); // this forces an update during a transition animation
+            if (at || bt)
+                setTimeout(
+                    action(() => {
+                        this._forceAnimate += 0.01;
+                    })
+                ); // this forces an update during a transition animation
             const highlight = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Highlighting);
             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 fontColor = (c => (c !== 'transparent' ? c : undefined))(StrCast(this.layoutDoc.link_fontColor));
-            const { stroke_markerScale, stroke_width, stroke_startMarker, stroke_endMarker, stroke_dash } = this.Document;
+            // eslint-disable-next-line camelcase
+            const { stroke_markerScale: strokeMarkerScale, stroke_width: strokeRawWidth, stroke_startMarker: strokeStartMarker, stroke_endMarker: strokeEndMarker, stroke_dash: strokeDash } = this.Document;
 
-            const strokeWidth = NumCast(stroke_width, 4);
+            const strokeWidth = NumCast(strokeRawWidth, 4);
             const linkDesc = StrCast(this.dataDoc.link_description) || ' ';
             const labelText = linkDesc.substring(0, 50) + (linkDesc.length > 50 ? '...' : '');
             return (
@@ -152,12 +170,12 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
                             start={aid}
                             end={bid} //
                             strokeWidth={strokeWidth + Math.max(2, strokeWidth * 0.1)}
-                            showHead={stroke_startMarker ? true : false}
-                            showTail={stroke_endMarker ? true : false}
-                            headSize={NumCast(stroke_markerScale, 3)}
-                            tailSize={NumCast(stroke_markerScale, 3)}
-                            tailShape={stroke_endMarker === 'dot' ? 'circle' : 'arrow1'}
-                            headShape={stroke_startMarker === 'dot' ? 'circle' : 'arrow1'}
+                            showHead={!!strokeStartMarker}
+                            showTail={!!strokeEndMarker}
+                            headSize={NumCast(strokeMarkerScale, 3)}
+                            tailSize={NumCast(strokeMarkerScale, 3)}
+                            tailShape={strokeEndMarker === 'dot' ? 'circle' : 'arrow1'}
+                            headShape={strokeStartMarker === 'dot' ? 'circle' : 'arrow1'}
                             color={highlightColor}
                         />
                     )}
@@ -166,23 +184,23 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
                         start={aid}
                         end={bid} //
                         strokeWidth={strokeWidth}
-                        dashness={Number(stroke_dash) ? true : false}
-                        showHead={stroke_startMarker ? true : false}
-                        showTail={stroke_endMarker ? true : false}
-                        headSize={NumCast(stroke_markerScale, 3)}
-                        tailSize={NumCast(stroke_markerScale, 3)}
-                        tailShape={stroke_endMarker === 'dot' ? 'circle' : 'arrow1'}
-                        headShape={stroke_startMarker === 'dot' ? 'circle' : 'arrow1'}
+                        dashness={!!Number(strokeDash)}
+                        showHead={!!strokeStartMarker}
+                        showTail={!!strokeEndMarker}
+                        headSize={NumCast(strokeMarkerScale, 3)}
+                        tailSize={NumCast(strokeMarkerScale, 3)}
+                        tailShape={strokeEndMarker === 'dot' ? 'circle' : 'arrow1'}
+                        headShape={strokeStartMarker === 'dot' ? 'circle' : 'arrow1'}
                         color={color}
                         labels={
                             <div
                                 id={this.DocumentView?.().DocUniqueId}
-                                className={'linkBox-label'}
+                                className="linkBox-label"
                                 style={{
                                     borderRadius: '8px',
                                     pointerEvents: this._props.isDocumentActive?.() ? 'all' : undefined,
                                     fontSize,
-                                    fontFamily /*, fontStyle: 'italic'*/,
+                                    fontFamily /* , fontStyle: 'italic' */,
                                     color: fontColor || lightOrDark(DashColor(color).fade(0.5).toString()),
                                     paddingLeft: 4,
                                     paddingRight: 4,
@@ -223,16 +241,19 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
         }
 
         setTimeout(
-            action(() => (this._forceAnimate = this._forceAnimate + 1)),
+            action(() => {
+                this._forceAnimate += 1;
+            }),
             2
         );
         return (
             <div className={`linkBox-container${this._props.isContentActive() ? '-interactive' : ''}`} style={{ background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) }}>
                 <ComparisonBox
+                    // eslint-disable-next-line react/jsx-props-no-spreading
                     {...this.props} //
                     fieldKey="link_anchor"
                     setHeight={emptyFunction}
-                    dontRegisterView={true}
+                    dontRegisterView
                     renderDepth={this._props.renderDepth + 1}
                     addDocument={returnFalse}
                     removeDocument={returnFalse}
diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx
index 2a96ce458..23cb25962 100644
--- a/src/client/views/nodes/LinkDescriptionPopup.tsx
+++ b/src/client/views/nodes/LinkDescriptionPopup.tsx
@@ -9,6 +9,7 @@ import { StrCast } from '../../../fields/Types';
 
 @observer
 export class LinkDescriptionPopup extends React.Component<{}> {
+    // eslint-disable-next-line no-use-before-define
     public static Instance: LinkDescriptionPopup;
     @observable public display: boolean = false;
     @observable public showDescriptions: string = 'ON';
@@ -23,6 +24,20 @@ export class LinkDescriptionPopup extends React.Component<{}> {
         LinkDescriptionPopup.Instance = this;
     }
 
+    componentDidMount() {
+        document.addEventListener('pointerdown', this.onClick, true);
+        reaction(
+            () => this.display,
+            display => {
+                display && (this.description = StrCast(LinkManager.Instance.currentLink?.link_description));
+            }
+        );
+    }
+
+    componentWillUnmount() {
+        document.removeEventListener('pointerdown', this.onClick, true);
+    }
+
     @action
     descriptionChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
         this.description = e.currentTarget.value;
@@ -39,25 +54,13 @@ export class LinkDescriptionPopup extends React.Component<{}> {
 
     @action
     onClick = (e: PointerEvent) => {
-        if (this.popupRef && !!!this.popupRef.current?.contains(e.target as any)) {
+        if (this.popupRef && !this.popupRef.current?.contains(e.target as any)) {
             this.display = false;
             this.description = '';
             TaskCompletionBox.taskCompleted = false;
         }
     };
 
-    componentDidMount() {
-        document.addEventListener('pointerdown', this.onClick, true);
-        reaction(
-            () => this.display,
-            display => display && (this.description = StrCast(LinkManager.Instance.currentLink?.link_description))
-        );
-    }
-
-    componentWillUnmount() {
-        document.removeEventListener('pointerdown', this.onClick, true);
-    }
-
     render() {
         return !this.display ? null : (
             <div
@@ -78,11 +81,11 @@ export class LinkDescriptionPopup extends React.Component<{}> {
                     onChange={e => this.descriptionChanged(e)}
                 />
                 <div className="linkDescriptionPopup-btn">
-                    <div className="linkDescriptionPopup-btn-dismiss" onPointerDown={e => this.onDismiss(false)}>
+                    <div className="linkDescriptionPopup-btn-dismiss" onPointerDown={() => this.onDismiss(false)}>
                         {' '}
                         Dismiss{' '}
                     </div>
-                    <div className="linkDescriptionPopup-btn-add" onPointerDown={e => this.onDismiss(true)}>
+                    <div className="linkDescriptionPopup-btn-add" onPointerDown={() => this.onDismiss(true)}>
                         {' '}
                         Add{' '}
                     </div>
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 539daf0bd..a9cfe6c0e 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -23,35 +23,41 @@ import { DocumentView, OpenWhere } from './DocumentView';
 import { StyleProviderFuncType } from './FieldView';
 import './LinkDocPreview.scss';
 
+interface LinkDocPreviewProps {
+    linkDoc?: Doc;
+    linkSrc?: Doc;
+    DocumentView?: () => DocumentView;
+    styleProvider?: StyleProviderFuncType;
+    location: number[];
+    hrefs?: string[];
+    showHeader?: boolean;
+    noPreview?: boolean;
+}
 export class LinkInfo {
+    // eslint-disable-next-line no-use-before-define
     private static _instance: Opt<LinkInfo>;
     constructor() {
         LinkInfo._instance = this;
         makeObservable(this);
     }
+    // eslint-disable-next-line no-use-before-define
     @observable public LinkInfo: Opt<LinkDocPreviewProps> = undefined;
 
     public static get Instance() {
         return LinkInfo._instance ?? new LinkInfo();
     }
     public static Clear() {
-        runInAction(() => LinkInfo.Instance && (LinkInfo.Instance.LinkInfo = undefined));
+        runInAction(() => {
+            LinkInfo.Instance && (LinkInfo.Instance.LinkInfo = undefined);
+        });
     }
     public static SetLinkInfo(info?: LinkDocPreviewProps) {
-        runInAction(() => LinkInfo.Instance && (LinkInfo.Instance.LinkInfo = info));
+        runInAction(() => {
+            LinkInfo.Instance && (LinkInfo.Instance.LinkInfo = info);
+        });
     }
 }
 
-interface LinkDocPreviewProps {
-    linkDoc?: Doc;
-    linkSrc?: Doc;
-    DocumentView?: () => DocumentView;
-    styleProvider?: StyleProviderFuncType;
-    location: number[];
-    hrefs?: string[];
-    showHeader?: boolean;
-    noPreview?: boolean;
-}
 @observer
 export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps> {
     _infoRef = React.createRef<HTMLDivElement>();
@@ -69,13 +75,13 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
 
     @action
     init() {
-        var linkTarget = this._props.linkDoc;
+        let linkTarget = this._props.linkDoc;
         this._linkSrc = this._props.linkSrc;
         this._linkDoc = this._props.linkDoc;
-        const link_anchor_1 = DocCast(this._linkDoc?.link_anchor_1);
-        const link_anchor_2 = DocCast(this._linkDoc?.link_anchor_2);
-        if (link_anchor_1 && link_anchor_2) {
-            linkTarget = Doc.AreProtosEqual(link_anchor_1, this._linkSrc) || Doc.AreProtosEqual(link_anchor_1?.annotationOn as Doc, this._linkSrc) ? link_anchor_2 : link_anchor_1;
+        const linkAnchor1 = DocCast(this._linkDoc?.link_anchor_1);
+        const linkAnchor2 = DocCast(this._linkDoc?.link_anchor_2);
+        if (linkAnchor1 && linkAnchor2) {
+            linkTarget = Doc.AreProtosEqual(linkAnchor1, this._linkSrc) || Doc.AreProtosEqual(linkAnchor1?.annotationOn as Doc, this._linkSrc) ? linkAnchor2 : linkAnchor1;
         }
         if (linkTarget?.annotationOn && linkTarget?.type !== DocumentType.RTF) {
             linkTarget = DocCast(linkTarget.annotationOn); // want to show annotation embedContainer document if annotation is not text
@@ -111,7 +117,13 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
                 if (href.startsWith('https://en.wikipedia.org/wiki/')) {
                     wiki()
                         .page(href.replace('https://en.wikipedia.org/wiki/', ''))
-                        .then(page => page.summary().then(action(summary => (this._toolTipText = summary.substring(0, 500)))));
+                        .then(page =>
+                            page.summary().then(
+                                action(summary => {
+                                    this._toolTipText = summary.substring(0, 500);
+                                })
+                            )
+                        );
                 } else {
                     this._toolTipText = 'url => ' + href;
                 }
@@ -133,7 +145,7 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
                                 this._linkSrc = anchor;
                                 const linkTarget = LinkManager.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();
                         }
@@ -194,7 +206,7 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
                 willPan: true,
                 zoomTime: 500,
             });
-            //this._props.docProps?.addDocTab(webDoc, OpenWhere.lightbox);
+            // this._props.docProps?.addDocTab(webDoc, OpenWhere.lightbox);
         }
     };
 
@@ -249,9 +261,9 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
                         setupMoveUpEvents(
                             this,
                             e,
-                            (e, down, delta) => {
-                                if (Math.abs(e.clientX - down[0]) + Math.abs(e.clientY - down[1]) > 100) {
-                                    DragManager.StartDocumentDrag([this._infoRef.current!], new DragManager.DocumentDragData([this._targetDoc!]), e.pageX, e.pageY);
+                            (moveEv, down) => {
+                                if (Math.abs(moveEv.clientX - down[0]) + Math.abs(moveEv.clientY - down[1]) > 100) {
+                                    DragManager.StartDocumentDrag([this._infoRef.current!], new DragManager.DocumentDragData([this._targetDoc!]), moveEv.pageX, moveEv.pageY);
                                     LinkInfo.Clear();
                                     return true;
                                 }
@@ -284,18 +296,18 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
                             removeDocument={returnFalse}
                             addDocTab={returnFalse}
                             pinToPres={returnFalse}
-                            dontRegisterView={true}
+                            dontRegisterView
                             childFilters={returnEmptyFilter}
                             childFiltersByRanges={returnEmptyFilter}
                             searchFilterDocs={returnEmptyDoclist}
                             renderDepth={0}
-                            suppressSetHeight={true}
+                            suppressSetHeight
                             PanelWidth={this.width}
                             PanelHeight={this.height}
                             pointerEvents={returnNone}
                             focus={emptyFunction}
                             whenChildContentsActiveChanged={returnFalse}
-                            ignoreAutoHeight={true} // need to ignore layout_autoHeight otherwise layout_autoHeight text boxes will expand beyond the preview panel size.
+                            ignoreAutoHeight // need to ignore layout_autoHeight otherwise layout_autoHeight text boxes will expand beyond the preview panel size.
                             NativeWidth={Doc.NativeWidth(this._targetDoc) ? () => Doc.NativeWidth(this._targetDoc) : undefined}
                             NativeHeight={Doc.NativeHeight(this._targetDoc) ? () => Doc.NativeHeight(this._targetDoc) : undefined}
                         />
diff --git a/src/client/views/nodes/LoadingBox.tsx b/src/client/views/nodes/LoadingBox.tsx
index adccc9db6..501831bca 100644
--- a/src/client/views/nodes/LoadingBox.tsx
+++ b/src/client/views/nodes/LoadingBox.tsx
@@ -60,7 +60,9 @@ export class LoadingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
         } else {
             const updateFunc = async () => {
                 const result = await Networking.QueryYoutubeProgress(StrCast(this.Document[Id])); // We use the guid of the overwriteDoc to track file uploads.
-                runInAction(() => (this.progress = result.progress));
+                runInAction(() => {
+                    this.progress = result.progress;
+                });
                 !this.Document.loadingError && this._timer && (this._timer = setTimeout(updateFunc, 1000));
             };
             this._timer = setTimeout(updateFunc, 1000);
diff --git a/src/client/views/nodes/MapBox/AnimationSpeedIcons.tsx b/src/client/views/nodes/MapBox/AnimationSpeedIcons.tsx
index d54a175b2..f4ece627f 100644
--- a/src/client/views/nodes/MapBox/AnimationSpeedIcons.tsx
+++ b/src/client/views/nodes/MapBox/AnimationSpeedIcons.tsx
@@ -1,35 +1,44 @@
-import * as React from "react";
+import * as React from 'react';
 
 export const slowSpeedIcon: JSX.Element = (
     <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 435.62">
         <defs>
-        <style type="text/css">
-            {`
+            <style type="text/css">
+                {`
                 .fil0 { fill: black; fill-rule: nonzero; }
                 .fil1 { fill: #FE0000; fill-rule: nonzero; }
             `}
-        </style>
+            </style>
         </defs>
-        <path className="fil0" d="M174.84 343.06c-7.31,-13.12 -13.03,-27.28 -16.89,-42.18 -3.76,-14.56 -5.77,-29.71 -5.77,-45.17 0,-11.94 1.19,-23.66 3.43,-35.03 2.29,-11.57 5.74,-22.83 10.2,-33.63 13.7,-33.14 37.01,-61.29 66.42,-80.96 25.38,-16.96 55.28,-27.66 87.45,-29.87l0 -30.17c0,-0.46 0.02,-0.92 0.06,-1.37l-33.7 0c-5.53,0 -10.05,-4.52 -10.05,-10.04l0 -24.59c0,-5.53 4.52,-10.05 10.05,-10.05l101.27 0c5.53,0 10.05,4.52 10.05,10.05l0 24.59c0,5.52 -4.52,10.04 -10.05,10.04l-33.69 0c0.03,0.45 0.05,0.91 0.05,1.37l0 31.03 -0.1 0c41.1,4.89 77.94,23.63 105.73,51.42 32.56,32.55 52.7,77.54 52.7,127.21 0,49.67 -20.14,94.66 -52.7,127.21 -32.55,32.55 -77.54,52.7 -127.21,52.7 -33.16,0 -64.29,-9.04 -91.05,-24.78 -27.66,-16.27 -50.59,-39.73 -66.2,-67.78zm148.42 -36.62l-80.33 0 0 -25.71 28.6 0 0 -42.57 -28.6 1.93 0 -25.71 36.95 -8.35 25.38 0 0 74.7 18 0 0 25.71zm44.34 -100.41l11.08 26.83 1.61 0 11.09 -26.83 34.86 0 -22.33 48.52 22.33 51.89 -35.67 0 -12.05 -28.92 -1.44 0 -11.89 28.92 -34.06 0 21.85 -50.93 -21.85 -49.48 36.47 0zm126.08 -74.6c6.98,-16.66 6.15,-34.13 -3.84,-45.82 -12,-14.03 -33.67,-15.64 -53.8,-5.77 21.32,14.62 40.68,31.63 57.64,51.59zm-323.17 0c-6.98,-16.66 -6.16,-34.13 3.84,-45.82 11.99,-14.03 33.67,-15.64 53.79,-5.77 -21.32,14.62 -40.68,31.63 -57.63,51.59zm15.31 162.23c3.23,12.5 8.04,24.39 14.18,35.42 13.13,23.58 32.39,43.29 55.6,56.94 22.37,13.16 48.52,20.71 76.49,20.71 41.71,0 79.47,-16.9 106.8,-44.23 27.32,-27.32 44.23,-65.08 44.23,-106.79 0,-41.71 -16.91,-79.47 -44.23,-106.8 -27.33,-27.32 -65.09,-44.23 -106.8,-44.23 -31.07,0 -59.91,9.34 -83.84,25.33 -24.74,16.54 -44.33,40.19 -55.82,67.98 -3.68,8.91 -6.56,18.35 -8.5,28.22 -1.87,9.49 -2.86,19.36 -2.86,29.5 0,13.24 1.65,25.96 4.75,37.95z"/>
-        <path className="fil1" d="M55.23 188.52c-7.98,0 -14.45,-6.47 -14.45,-14.44 0,-7.98 6.47,-14.45 14.45,-14.45l63.94 0c7.98,0 14.45,6.47 14.45,14.45 0,7.97 -6.47,14.44 -14.45,14.44l-63.94 0zm0.72 167.68c-7.97,0 -14.44,-6.47 -14.44,-14.45 0,-7.97 6.47,-14.45 14.44,-14.45l64.58 0c7.97,0 14.45,6.48 14.45,14.45 0,7.98 -6.48,14.45 -14.45,14.45l-64.58 0zm-41.5 -84.94c-7.98,0 -14.45,-6.47 -14.45,-14.45 0,-7.97 6.47,-14.44 14.45,-14.44l89.12 0c7.98,0 14.45,6.47 14.45,14.44 0,7.98 -6.47,14.45 -14.45,14.45l-89.12 0z"/>
+        <path
+            className="fil0"
+            d="M174.84 343.06c-7.31,-13.12 -13.03,-27.28 -16.89,-42.18 -3.76,-14.56 -5.77,-29.71 -5.77,-45.17 0,-11.94 1.19,-23.66 3.43,-35.03 2.29,-11.57 5.74,-22.83 10.2,-33.63 13.7,-33.14 37.01,-61.29 66.42,-80.96 25.38,-16.96 55.28,-27.66 87.45,-29.87l0 -30.17c0,-0.46 0.02,-0.92 0.06,-1.37l-33.7 0c-5.53,0 -10.05,-4.52 -10.05,-10.04l0 -24.59c0,-5.53 4.52,-10.05 10.05,-10.05l101.27 0c5.53,0 10.05,4.52 10.05,10.05l0 24.59c0,5.52 -4.52,10.04 -10.05,10.04l-33.69 0c0.03,0.45 0.05,0.91 0.05,1.37l0 31.03 -0.1 0c41.1,4.89 77.94,23.63 105.73,51.42 32.56,32.55 52.7,77.54 52.7,127.21 0,49.67 -20.14,94.66 -52.7,127.21 -32.55,32.55 -77.54,52.7 -127.21,52.7 -33.16,0 -64.29,-9.04 -91.05,-24.78 -27.66,-16.27 -50.59,-39.73 -66.2,-67.78zm148.42 -36.62l-80.33 0 0 -25.71 28.6 0 0 -42.57 -28.6 1.93 0 -25.71 36.95 -8.35 25.38 0 0 74.7 18 0 0 25.71zm44.34 -100.41l11.08 26.83 1.61 0 11.09 -26.83 34.86 0 -22.33 48.52 22.33 51.89 -35.67 0 -12.05 -28.92 -1.44 0 -11.89 28.92 -34.06 0 21.85 -50.93 -21.85 -49.48 36.47 0zm126.08 -74.6c6.98,-16.66 6.15,-34.13 -3.84,-45.82 -12,-14.03 -33.67,-15.64 -53.8,-5.77 21.32,14.62 40.68,31.63 57.64,51.59zm-323.17 0c-6.98,-16.66 -6.16,-34.13 3.84,-45.82 11.99,-14.03 33.67,-15.64 53.79,-5.77 -21.32,14.62 -40.68,31.63 -57.63,51.59zm15.31 162.23c3.23,12.5 8.04,24.39 14.18,35.42 13.13,23.58 32.39,43.29 55.6,56.94 22.37,13.16 48.52,20.71 76.49,20.71 41.71,0 79.47,-16.9 106.8,-44.23 27.32,-27.32 44.23,-65.08 44.23,-106.79 0,-41.71 -16.91,-79.47 -44.23,-106.8 -27.33,-27.32 -65.09,-44.23 -106.8,-44.23 -31.07,0 -59.91,9.34 -83.84,25.33 -24.74,16.54 -44.33,40.19 -55.82,67.98 -3.68,8.91 -6.56,18.35 -8.5,28.22 -1.87,9.49 -2.86,19.36 -2.86,29.5 0,13.24 1.65,25.96 4.75,37.95z"
+        />
+        <path
+            className="fil1"
+            d="M55.23 188.52c-7.98,0 -14.45,-6.47 -14.45,-14.44 0,-7.98 6.47,-14.45 14.45,-14.45l63.94 0c7.98,0 14.45,6.47 14.45,14.45 0,7.97 -6.47,14.44 -14.45,14.44l-63.94 0zm0.72 167.68c-7.97,0 -14.44,-6.47 -14.44,-14.45 0,-7.97 6.47,-14.45 14.44,-14.45l64.58 0c7.97,0 14.45,6.48 14.45,14.45 0,7.98 -6.48,14.45 -14.45,14.45l-64.58 0zm-41.5 -84.94c-7.98,0 -14.45,-6.47 -14.45,-14.45 0,-7.97 6.47,-14.44 14.45,-14.44l89.12 0c7.98,0 14.45,6.47 14.45,14.44 0,7.98 -6.47,14.45 -14.45,14.45l-89.12 0z"
+        />
     </svg>
 );
 
 export const mediumSpeedIcon: JSX.Element = (
     <svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 122.88 104.55">
-        <defs><style>{`.cls-1{fill:#fe0000;}`}</style></defs>
-        <path d="M42,82.34a42.82,42.82,0,0,1-4.05-10.13A43.2,43.2,0,0,1,76.72,18.29V11.05c0-.11,0-.22,0-.33H68.65a2.41,2.41,0,0,1-2.41-2.41V2.41A2.41,2.41,0,0,1,68.65,0H93a2.42,2.42,0,0,1,2.42,2.41v5.9A2.42,2.42,0,0,1,93,10.72H84.87c0,.11,0,.22,0,.33V18.5h0A43.17,43.17,0,1,1,42,82.34ZM88.22,49.45l2.66,6.44h.39l2.66-6.44h8.37L96.94,61.09l5.36,12.45H93.74L90.85,66.6H90.5l-2.85,6.94H79.47l5.25-12.22L79.47,49.45ZM58.65,56.08l-1-5.75a33.58,33.58,0,0,1,9.68-1.46c1.28,0,2.35,0,3.22.11a11.77,11.77,0,0,1,2.67.58,5.41,5.41,0,0,1,2.2,1.28c1.24,1.23,1.85,3.12,1.85,5.66s-.72,4.42-2.16,5.63S70.64,64.73,66,66.3v1.08H76.89v6.16H57.11V68.72a10.73,10.73,0,0,1,.81-4.12,8.4,8.4,0,0,1,2.43-2.7,12.13,12.13,0,0,1,2.79-1.7l3.32-1.52c1-.47,1.88-.87,2.52-1.17V55.42a28.59,28.59,0,0,0-3.2-.19,30.66,30.66,0,0,0-7.13.85Zm59.83-24.54c1.68-4,1.48-8.19-.92-11-2.88-3.37-8.08-3.76-12.91-1.39a69.74,69.74,0,0,1,13.83,12.38Zm-77.56,0c-1.67-4-1.48-8.19.92-11,2.88-3.37,8.08-3.76,12.91-1.39A70,70,0,0,0,40.92,31.54ZM44.6,70.48A36,36,0,0,0,48,79a35.91,35.91,0,1,0-3.4-8.5Z"/>
-        <path className="cls-1" d="M13.25,45.25a3.47,3.47,0,0,1,0-6.94H28.6a3.47,3.47,0,0,1,0,6.94Z"/>
-        <path className="cls-1" d="M3.47,65.1a3.47,3.47,0,1,1,0-6.93H24.86a3.47,3.47,0,0,1,0,6.93Z"/>
-        <path className="cls-1" d="M13.43,85.49a3.47,3.47,0,1,1,0-6.94h15.5a3.47,3.47,0,0,1,0,6.94Z"/>
+        <defs>
+            <style>{`.cls-1{fill:#fe0000;}`}</style>
+        </defs>
+        <path d="M42,82.34a42.82,42.82,0,0,1-4.05-10.13A43.2,43.2,0,0,1,76.72,18.29V11.05c0-.11,0-.22,0-.33H68.65a2.41,2.41,0,0,1-2.41-2.41V2.41A2.41,2.41,0,0,1,68.65,0H93a2.42,2.42,0,0,1,2.42,2.41v5.9A2.42,2.42,0,0,1,93,10.72H84.87c0,.11,0,.22,0,.33V18.5h0A43.17,43.17,0,1,1,42,82.34ZM88.22,49.45l2.66,6.44h.39l2.66-6.44h8.37L96.94,61.09l5.36,12.45H93.74L90.85,66.6H90.5l-2.85,6.94H79.47l5.25-12.22L79.47,49.45ZM58.65,56.08l-1-5.75a33.58,33.58,0,0,1,9.68-1.46c1.28,0,2.35,0,3.22.11a11.77,11.77,0,0,1,2.67.58,5.41,5.41,0,0,1,2.2,1.28c1.24,1.23,1.85,3.12,1.85,5.66s-.72,4.42-2.16,5.63S70.64,64.73,66,66.3v1.08H76.89v6.16H57.11V68.72a10.73,10.73,0,0,1,.81-4.12,8.4,8.4,0,0,1,2.43-2.7,12.13,12.13,0,0,1,2.79-1.7l3.32-1.52c1-.47,1.88-.87,2.52-1.17V55.42a28.59,28.59,0,0,0-3.2-.19,30.66,30.66,0,0,0-7.13.85Zm59.83-24.54c1.68-4,1.48-8.19-.92-11-2.88-3.37-8.08-3.76-12.91-1.39a69.74,69.74,0,0,1,13.83,12.38Zm-77.56,0c-1.67-4-1.48-8.19.92-11,2.88-3.37,8.08-3.76,12.91-1.39A70,70,0,0,0,40.92,31.54ZM44.6,70.48A36,36,0,0,0,48,79a35.91,35.91,0,1,0-3.4-8.5Z" />
+        <path className="cls-1" d="M13.25,45.25a3.47,3.47,0,0,1,0-6.94H28.6a3.47,3.47,0,0,1,0,6.94Z" />
+        <path className="cls-1" d="M3.47,65.1a3.47,3.47,0,1,1,0-6.93H24.86a3.47,3.47,0,0,1,0,6.93Z" />
+        <path className="cls-1" d="M13.43,85.49a3.47,3.47,0,1,1,0-6.94h15.5a3.47,3.47,0,0,1,0,6.94Z" />
     </svg>
 );
 
 export const fastSpeedIcon: JSX.Element = (
     <svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 122.88 104.55">
-        <defs><style>{`.cls-1{fill:#fe0000;`}</style></defs>
-        <path d="M42,82.34a42.82,42.82,0,0,1-4.05-10.13A43.2,43.2,0,0,1,76.72,18.29V11.05c0-.11,0-.22,0-.33H68.65a2.41,2.41,0,0,1-2.41-2.41V2.41A2.41,2.41,0,0,1,68.65,0H93a2.42,2.42,0,0,1,2.42,2.41v5.9A2.42,2.42,0,0,1,93,10.72H84.87c0,.11,0,.22,0,.33V18.5h0A43.17,43.17,0,1,1,42,82.34ZM88.22,49.61l2.66,6.44h.39l2.66-6.44h8.37L96.94,61.26l5.36,12.45H93.74l-2.9-6.94H90.5l-2.86,6.94H79.47l5.24-12.22L79.47,49.61Zm-19,8.48v-2.5a24.92,24.92,0,0,0-3.74-.2A33.25,33.25,0,0,0,59,56.2l-1-5.7A30.47,30.47,0,0,1,67.13,49a22.86,22.86,0,0,1,5.48.47,6.91,6.91,0,0,1,2.5,1.11,5.62,5.62,0,0,1,1.78,4.55,5.84,5.84,0,0,1-3.2,5.56v.19a5.73,5.73,0,0,1,3.81,5.74,8.67,8.67,0,0,1-.63,3.49,6,6,0,0,1-1.6,2.24,7.15,7.15,0,0,1-2.55,1.25,25.64,25.64,0,0,1-6.61.66,37.78,37.78,0,0,1-8.54-1l1.08-6.37a27.22,27.22,0,0,0,6.21.89,35.79,35.79,0,0,0,4.35-.23V65.11l-6.63-.65V58.87l6.63-.78Zm49.27-26.55c1.68-4,1.48-8.19-.92-11-2.88-3.37-8.08-3.76-12.91-1.39a69.74,69.74,0,0,1,13.83,12.38Zm-77.56,0c-1.67-4-1.48-8.19.92-11,2.88-3.37,8.08-3.76,12.91-1.39A70,70,0,0,0,40.92,31.54ZM44.6,70.48A36,36,0,0,0,48,79a35.91,35.91,0,1,0-3.4-8.5Z"/>
-        <path className="cls-1" d="M13.25,45.25a3.47,3.47,0,0,1,0-6.94H28.6a3.47,3.47,0,0,1,0,6.94Zm.18,40.24a3.47,3.47,0,1,1,0-6.94h15.5a3.47,3.47,0,0,1,0,6.94ZM3.47,65.1a3.47,3.47,0,1,1,0-6.93H24.86a3.47,3.47,0,0,1,0,6.93Z"/>
+        <defs>
+            <style>{`.cls-1{fill:#fe0000;`}</style>
+        </defs>
+        <path d="M42,82.34a42.82,42.82,0,0,1-4.05-10.13A43.2,43.2,0,0,1,76.72,18.29V11.05c0-.11,0-.22,0-.33H68.65a2.41,2.41,0,0,1-2.41-2.41V2.41A2.41,2.41,0,0,1,68.65,0H93a2.42,2.42,0,0,1,2.42,2.41v5.9A2.42,2.42,0,0,1,93,10.72H84.87c0,.11,0,.22,0,.33V18.5h0A43.17,43.17,0,1,1,42,82.34ZM88.22,49.61l2.66,6.44h.39l2.66-6.44h8.37L96.94,61.26l5.36,12.45H93.74l-2.9-6.94H90.5l-2.86,6.94H79.47l5.24-12.22L79.47,49.61Zm-19,8.48v-2.5a24.92,24.92,0,0,0-3.74-.2A33.25,33.25,0,0,0,59,56.2l-1-5.7A30.47,30.47,0,0,1,67.13,49a22.86,22.86,0,0,1,5.48.47,6.91,6.91,0,0,1,2.5,1.11,5.62,5.62,0,0,1,1.78,4.55,5.84,5.84,0,0,1-3.2,5.56v.19a5.73,5.73,0,0,1,3.81,5.74,8.67,8.67,0,0,1-.63,3.49,6,6,0,0,1-1.6,2.24,7.15,7.15,0,0,1-2.55,1.25,25.64,25.64,0,0,1-6.61.66,37.78,37.78,0,0,1-8.54-1l1.08-6.37a27.22,27.22,0,0,0,6.21.89,35.79,35.79,0,0,0,4.35-.23V65.11l-6.63-.65V58.87l6.63-.78Zm49.27-26.55c1.68-4,1.48-8.19-.92-11-2.88-3.37-8.08-3.76-12.91-1.39a69.74,69.74,0,0,1,13.83,12.38Zm-77.56,0c-1.67-4-1.48-8.19.92-11,2.88-3.37,8.08-3.76,12.91-1.39A70,70,0,0,0,40.92,31.54ZM44.6,70.48A36,36,0,0,0,48,79a35.91,35.91,0,1,0-3.4-8.5Z" />
+        <path className="cls-1" d="M13.25,45.25a3.47,3.47,0,0,1,0-6.94H28.6a3.47,3.47,0,0,1,0,6.94Zm.18,40.24a3.47,3.47,0,1,1,0-6.94h15.5a3.47,3.47,0,0,1,0,6.94ZM3.47,65.1a3.47,3.47,0,1,1,0-6.93H24.86a3.47,3.47,0,0,1,0,6.93Z" />
     </svg>
 );
-
diff --git a/src/client/views/nodes/MapBox/AnimationUtility.ts b/src/client/views/nodes/MapBox/AnimationUtility.ts
index 35153f439..cf5315da3 100644
--- a/src/client/views/nodes/MapBox/AnimationUtility.ts
+++ b/src/client/views/nodes/MapBox/AnimationUtility.ts
@@ -87,25 +87,24 @@ export class AnimationUtility {
     @computed get currentPitch(): number {
         if (!this.isStreetViewAnimation) return 50;
         if (!this.terrainDisplayed) return 80;
-        else {
-            // const groundElevation = 0;
-            const heightAboveGround = this.currentAnimationAltitude;
-            const horizontalDistance = 500;
-
-            let pitch;
-            if (heightAboveGround >= 0) {
-                pitch = 90 - Math.atan(heightAboveGround / horizontalDistance) * (180 / Math.PI);
-            } else {
-                pitch = 80;
-            }
 
-            console.log(Math.max(50, Math.min(pitch, 85)));
+        // const groundElevation = 0;
+        const heightAboveGround = this.currentAnimationAltitude;
+        const horizontalDistance = 500;
 
-            if (this.previousPitch) {
-                return this.lerp(Math.max(50, Math.min(pitch, 85)), this.previousPitch, 0.02);
-            }
-            return Math.max(50, Math.min(pitch, 85));
+        let pitch;
+        if (heightAboveGround >= 0) {
+            pitch = 90 - Math.atan(heightAboveGround / horizontalDistance) * (180 / Math.PI);
+        } else {
+            pitch = 80;
+        }
+
+        console.log(Math.max(50, Math.min(pitch, 85)));
+
+        if (this.previousPitch) {
+            return this.lerp(Math.max(50, Math.min(pitch, 85)), this.previousPitch, 0.02);
         }
+        return Math.max(50, Math.min(pitch, 85));
     }
 
     @computed get flyInEndPitch() {
@@ -214,8 +213,8 @@ export class AnimationUtility {
         currentAnimationPhase: number;
         updateAnimationPhase: (newAnimationPhase: number) => void;
         updateFrameId: (newFrameId: number) => void;
-    }) => {
-        return new Promise<void>(async resolve => {
+    }) =>
+        new Promise<void>(async resolve => {
             let startTime: number | null = null;
 
             const frame = async (currentTime: number) => {
@@ -257,7 +256,7 @@ export class AnimationUtility {
                 updateAnimationPhase(animationPhase);
 
                 // compute corrected camera ground position, so that he leading edge of the path is in view
-                var correctedPosition = this.computeCameraPosition(
+                const correctedPosition = this.computeCameraPosition(
                     this.isStreetViewAnimation,
                     this.currentPitch,
                     bearing,
@@ -277,7 +276,7 @@ export class AnimationUtility {
                 map.setFreeCameraOptions(camera);
 
                 this.previousAltitude = this.currentAnimationAltitude;
-                this.previousPitch = this.previousPitch;
+                // this.previousPitch = this.previousPitch;
 
                 // repeat!
                 const innerFrameId = await window.requestAnimationFrame(frame);
@@ -287,15 +286,14 @@ export class AnimationUtility {
             const outerFrameId = await window.requestAnimationFrame(frame);
             updateFrameId(outerFrameId);
         });
-    };
 
-    public flyInAndRotate = async ({ map, updateFrameId }: { map: MapRef; updateFrameId: (newFrameId: number) => void }) => {
-        return new Promise<{ bearing: number; altitude: number }>(async resolve => {
+    public flyInAndRotate = async ({ map, updateFrameId }: { map: MapRef; updateFrameId: (newFrameId: number) => void }) =>
+        new Promise<{ bearing: number; altitude: number }>(async resolve => {
             let start: number | null;
 
-            var currentAltitude;
-            var currentBearing;
-            var currentPitch;
+            let currentAltitude;
+            let currentBearing;
+            let currentPitch;
 
             // the animation frame will run as many times as necessary until the duration has been reached
             const frame = async (time: number) => {
@@ -319,7 +317,7 @@ export class AnimationUtility {
                 currentPitch = this.FLY_IN_START_PITCH + (this.flyInEndPitch - this.FLY_IN_START_PITCH) * d3.easeCubicOut(animationPhase);
 
                 // compute corrected camera ground position, so the start of the path is always in view
-                var correctedPosition = this.computeCameraPosition(false, currentPitch, currentBearing, this.FIRST_LNG_LAT, currentAltitude);
+                const correctedPosition = this.computeCameraPosition(false, currentPitch, currentBearing, this.FIRST_LNG_LAT, currentAltitude);
 
                 // set the pitch and bearing of the camera
                 const camera = map.getFreeCameraOptions();
@@ -349,13 +347,10 @@ export class AnimationUtility {
             const outerFrameId = await window.requestAnimationFrame(frame);
             updateFrameId(outerFrameId);
         });
-    };
 
     previousCameraPosition: { lng: number; lat: number } | null = null;
 
-    lerp = (start: number, end: number, amt: number) => {
-        return (1 - amt) * start + amt * end;
-    };
+    lerp = (start: number, end: number, amt: number) => (1 - amt) * start + amt * end;
 
     computeCameraPosition = (isStreetViewAnimation: boolean, pitch: number, bearing: number, targetPosition: { lng: number; lat: number }, altitude: number, smooth = false) => {
         const bearingInRadian = (bearing * Math.PI) / 180;
diff --git a/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx b/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx
index fe7f8d8b3..f176317d2 100644
--- a/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx
+++ b/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx
@@ -14,6 +14,7 @@ import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
 
 @observer
 export class DirectionsAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
+    // eslint-disable-next-line no-use-before-define
     static Instance: DirectionsAnchorMenu;
 
     private _disposer: IReactionDisposer | undefined;
@@ -24,8 +25,8 @@ export class DirectionsAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
     public OnClick: (e: PointerEvent) => void = unimplementedFunction;
     // public OnAudio: (e: PointerEvent) => void = unimplementedFunction;
     public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction;
-    public Highlight: (color: string, isTargetToggler: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => Opt<Doc> = (color: string, isTargetToggler: boolean) => undefined;
-    public GetAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => undefined;
+    public Highlight: (color: string, isTargetToggler: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => Opt<Doc> = () => undefined;
+    public GetAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = () => undefined;
     public Delete: () => void = unimplementedFunction;
     // public MakeTargetToggle: () => void = unimplementedFunction;
     // public ShowTargetTrail: () => void = unimplementedFunction;
@@ -56,7 +57,7 @@ export class DirectionsAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
     componentDidMount() {
         this._disposer = reaction(
             () => SelectionManager.Views.slice(),
-            sel => DirectionsAnchorMenu.Instance.fadeOut(true)
+            () => DirectionsAnchorMenu.Instance.fadeOut(true)
         );
     }
     // audioDown = (e: React.PointerEvent) => {
@@ -104,8 +105,8 @@ export class DirectionsAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
                     color={SettingsManager.userColor}
                 />
 
-                <IconButton tooltip="Animate route" onPointerDown={this.Delete} /**TODO: fix */ icon={<FontAwesomeIcon icon={faRoute as IconLookup} />} color={SettingsManager.userColor} />
-                <IconButton tooltip="Add to calendar" onPointerDown={this.Delete} /**TODO: fix */ icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />} color={SettingsManager.userColor} />
+                <IconButton tooltip="Animate route" onPointerDown={this.Delete} /* *TODO: fix */ icon={<FontAwesomeIcon icon={faRoute as IconLookup} />} color={SettingsManager.userColor} />
+                <IconButton tooltip="Add to calendar" onPointerDown={this.Delete} /* *TODO: fix */ icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />} color={SettingsManager.userColor} />
             </div>
         );
 
diff --git a/src/client/views/nodes/MapBox/GeocoderControl.tsx b/src/client/views/nodes/MapBox/GeocoderControl.tsx
index e4ba51316..e118c57d9 100644
--- a/src/client/views/nodes/MapBox/GeocoderControl.tsx
+++ b/src/client/views/nodes/MapBox/GeocoderControl.tsx
@@ -3,8 +3,6 @@
 // import { ControlPosition, MarkerProps, useControl } from "react-map-gl";
 
 // import '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css'
-
-
 // export type GeocoderControlProps = Omit<GeocoderOptions, 'accessToken' | 'mapboxgl' | 'marker'> & {
 //     mapboxAccessToken: string;
 //     marker?: Omit<MarkerProps, 'longitude' | 'latitude'>;
@@ -31,7 +29,6 @@
 //           ctrl.on('results', props.onResults);
 //           ctrl.on('result', evt => {
 //             props.onResult(evt);
-    
 //             // const {result} = evt;
 //             // const location =
 //             //   result &&
@@ -49,8 +46,6 @@
 //           position: props.position
 //         }
 //       );
-
-
 //     // @ts-ignore (TS2339) private member
 //     if (geocoder._map) {
 //         if (geocoder.getProximity() !== props.proximity && props.proximity !== undefined) {
@@ -104,4 +99,4 @@
 //   onLoading: noop,
 //   onResults: noop,
 //   onError: noop
-// };
\ No newline at end of file
+// };
diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
index d17c4298c..174511e1a 100644
--- a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
+++ b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/button-has-type */
 import { IconLookup, faAdd, faArrowDown, faArrowLeft, faArrowsRotate, faBicycle, faCalendarDays, faCar, faDiamondTurnRight, faEdit, faPersonWalking, faRoute } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Autocomplete, Checkbox, FormControlLabel, TextField } from '@mui/material';
@@ -24,6 +25,7 @@ type MapAnchorMenuType = 'standard' | 'routeCreation' | 'calendar' | 'customize'
 
 @observer
 export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
+    // eslint-disable-next-line no-use-before-define
     static Instance: MapAnchorMenu;
 
     private _disposer: IReactionDisposer | undefined;
@@ -36,8 +38,8 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
     public OnClick: (e: PointerEvent) => void = unimplementedFunction;
     // public OnAudio: (e: PointerEvent) => void = unimplementedFunction;
     public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction;
-    public Highlight: (color: string, isTargetToggler: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => Opt<Doc> = (color: string, isTargetToggler: boolean) => undefined;
-    public GetAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => undefined;
+    public Highlight: (color: string, isTargetToggler: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => Opt<Doc> = () => undefined;
+    public GetAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = () => undefined;
     public Delete: () => void = unimplementedFunction;
     // public MakeTargetToggle: () => void = unimplementedFunction;
     // public ShowTargetTrail: () => void = unimplementedFunction;
@@ -125,7 +127,7 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
     componentDidMount() {
         this._disposer = reaction(
             () => SelectionManager.Views.slice(),
-            sel => MapAnchorMenu.Instance.fadeOut(true)
+            () => MapAnchorMenu.Instance.fadeOut(true)
         );
     }
     // audioDown = (e: React.PointerEvent) => {
@@ -148,12 +150,12 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
         setupMoveUpEvents(
             this,
             e,
-            (e: PointerEvent) => {
-                this.StartDrag(e, this._commentRef.current!);
+            moveEv => {
+                this.StartDrag(moveEv, this._commentRef.current!);
                 return true;
             },
             returnFalse,
-            e => this.OnClick(e)
+            clickEv => this.OnClick(clickEv)
         );
     };
 
@@ -275,7 +277,7 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
 
     HandleAddRouteClick = () => {
         if (this.currentRouteInfoMap && this.selectedTransportationType && this.selectedDestinationFeature) {
-            const coordinates = this.currentRouteInfoMap[this.selectedTransportationType].coordinates;
+            const { coordinates } = this.currentRouteInfoMap[this.selectedTransportationType];
             console.log(coordinates);
             console.log(this.selectedDestinationFeature);
             this.AddNewRouteToMap(coordinates, this.title ?? '', this.selectedDestinationFeature, this.createPinForDestination);
@@ -294,34 +296,30 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
 
     getDirectionsButton: JSX.Element = (<IconButton tooltip="Get directions" onPointerDown={this.DirectionsClick} icon={<FontAwesomeIcon icon={faDiamondTurnRight as IconLookup} />} color={SettingsManager.userColor} />);
 
-    getAddToCalendarButton = (docType: string): JSX.Element => {
-        return (
-            <IconButton
-                tooltip="Add to calendar"
-                onPointerDown={() => {
-                    CalendarManager.Instance.open(undefined, docType === 'pin' ? this.pinDoc : this.routeDoc);
-                }}
-                icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />}
-                color={SettingsManager.userColor}
-            />
-        );
-    };
+    getAddToCalendarButton = (docType: string): JSX.Element => (
+        <IconButton
+            tooltip="Add to calendar"
+            onPointerDown={() => {
+                CalendarManager.Instance.open(undefined, docType === 'pin' ? this.pinDoc : this.routeDoc);
+            }}
+            icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />}
+            color={SettingsManager.userColor}
+        />
+    );
     addToCalendarButton: JSX.Element = (
         <IconButton tooltip="Add to calendar" onPointerDown={() => CalendarManager.Instance.open(undefined, this.pinDoc)} icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />} color={SettingsManager.userColor} />
     );
 
-    getLinkNoteToDocButton = (docType: string): JSX.Element => {
-        return (
-            <div ref={this._commentRef}>
-                <IconButton
-                    tooltip={`Link Note to ${docType === 'pin' ? 'Pin' : 'Route'}`} //
-                    onPointerDown={this.notePointerDown}
-                    icon={<FontAwesomeIcon icon="sticky-note" />}
-                    color={SettingsManager.userColor}
-                />
-            </div>
-        );
-    };
+    getLinkNoteToDocButton = (docType: string): JSX.Element => (
+        <div ref={this._commentRef}>
+            <IconButton
+                tooltip={`Link Note to ${docType === 'pin' ? 'Pin' : 'Route'}`} //
+                onPointerDown={this.notePointerDown}
+                icon={<FontAwesomeIcon icon="sticky-note" />}
+                color={SettingsManager.userColor}
+            />
+        </div>
+    );
 
     linkNoteToPinOrRoutenButton: JSX.Element = (
         <div ref={this._commentRef}>
@@ -363,16 +361,14 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
         />
     );
 
-    getDeleteButton = (type: string) => {
-        return (
-            <IconButton
-                tooltip={`Delete ${type === 'pin' ? 'Pin' : 'Route'}`} //
-                onPointerDown={this.Delete}
-                icon={<FontAwesomeIcon icon="trash-alt" />}
-                color={SettingsManager.userColor}
-            />
-        );
-    };
+    getDeleteButton = (type: string) => (
+        <IconButton
+            tooltip={`Delete ${type === 'pin' ? 'Pin' : 'Route'}`} //
+            onPointerDown={this.Delete}
+            icon={<FontAwesomeIcon icon="trash-alt" />}
+            color={SettingsManager.userColor}
+        />
+    );
 
     animateRouteButton: JSX.Element = (<IconButton tooltip="Animate route" onPointerDown={() => this.OpenAnimationPanel(this.routeDoc)} icon={<FontAwesomeIcon icon={faRoute as IconLookup} />} color={SettingsManager.userColor} />);
 
@@ -453,18 +449,17 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
                             }}
                             options={this.destinationFeatures.filter(feature => feature.place_name).map(feature => feature)}
                             getOptionLabel={(feature: any) => feature.place_name}
+                            // eslint-disable-next-line react/jsx-props-no-spreading
                             renderInput={(params: any) => <TextField {...params} placeholder="Enter a destination" />}
                         />
-                        {this.selectedDestinationFeature && (
-                            <>
-                                {!this.allMapPinDocs.some(pinDoc => pinDoc.title === this.selectedDestinationFeature.place_name) && (
-                                    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '5px' }}>
-                                        <FormControlLabel label="Create pin for destination?" control={<Checkbox color="success" checked={this.createPinForDestination} onChange={this.toggleCreatePinForDestinationCheckbox} />} />
-                                    </div>
-                                )}
-                            </>
-                        )}
-                        <button id="get-routes-button" disabled={this.selectedDestinationFeature ? false : true} onClick={() => this.getRoutes(this.selectedDestinationFeature)}>
+                        {!this.selectedDestinationFeature
+                            ? null
+                            : !this.allMapPinDocs.some(pinDoc => pinDoc.title === this.selectedDestinationFeature.place_name) && (
+                                  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '5px' }}>
+                                      <FormControlLabel label="Create pin for destination?" control={<Checkbox color="success" checked={this.createPinForDestination} onChange={this.toggleCreatePinForDestinationCheckbox} />} />
+                                  </div>
+                              )}
+                        <button id="get-routes-button" disabled={!this.selectedDestinationFeature} onClick={() => this.getRoutes(this.selectedDestinationFeature)}>
                             Get routes
                         </button>
 
@@ -517,7 +512,7 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
                                 </div>
                             ))}
                         </div>
-                        <div style={{ width: '100%', height: '3px', color: 'white' }}></div>
+                        <div style={{ width: '100%', height: '3px', color: 'white' }} />
                     </div>
                 )}
                 {this.menuType === 'route' && this.routeDoc && <div>{StrCast(this.routeDoc.title)}</div>}
diff --git a/src/client/views/nodes/MapBox/MapboxApiUtility.ts b/src/client/views/nodes/MapBox/MapboxApiUtility.ts
index 592330ac2..5c5192372 100644
--- a/src/client/views/nodes/MapBox/MapboxApiUtility.ts
+++ b/src/client/views/nodes/MapBox/MapboxApiUtility.ts
@@ -1,4 +1,3 @@
-
 const MAPBOX_FORWARD_GEOCODE_BASE_URL = 'https://api.mapbox.com/geocoding/v5/mapbox.places/';
 const MAPBOX_REVERSE_GEOCODE_BASE_URL = 'https://api.mapbox.com/geocoding/v5/mapbox.places/';
 const MAPBOX_DIRECTIONS_BASE_URL = 'https://api.mapbox.com/directions/v5/mapbox';
@@ -7,92 +6,79 @@ const MAPBOX_ACCESS_TOKEN = 'pk.eyJ1IjoiemF1bHRhdmFuZ2FyIiwiYSI6ImNscHgwNDd1MDA3
 export type TransportationType = 'driving' | 'cycling' | 'walking';
 
 export class MapboxApiUtility {
-
     static forwardGeocodeForFeatures = async (searchText: string) => {
         try {
-            const url = MAPBOX_FORWARD_GEOCODE_BASE_URL + encodeURI(searchText) +'.json' +`?access_token=${MAPBOX_ACCESS_TOKEN}`;
+            const url = MAPBOX_FORWARD_GEOCODE_BASE_URL + encodeURI(searchText) + `.json?access_token=${MAPBOX_ACCESS_TOKEN}`;
             const response = await fetch(url);
             const data = await response.json();
             return data.features;
-        } catch (error: any){
-            // TODO: handle error in better way 
+        } catch (error: any) {
+            // TODO: handle error in better way
             return null;
         }
-    }
+    };
 
     static reverseGeocodeForFeatures = async (longitude: number, latitude: number) => {
         try {
-            const url = MAPBOX_REVERSE_GEOCODE_BASE_URL + encodeURI(longitude.toString() + "," + latitude.toString()) + '.json' +
-                `?access_token=${MAPBOX_ACCESS_TOKEN}`;
+            const url = MAPBOX_REVERSE_GEOCODE_BASE_URL + encodeURI(longitude.toString() + ',' + latitude.toString()) + `.json?access_token=${MAPBOX_ACCESS_TOKEN}`;
             const response = await fetch(url);
             const data = await response.json();
             return data.features;
-        } catch (error: any){
+        } catch (error: any) {
             return null;
         }
-    }
+    };
 
     static getDirections = async (origin: number[], destination: number[]): Promise<Record<TransportationType, any> | undefined> => {
         try {
-
             const directionsPromises: Promise<any>[] = [];
             const transportationTypes: TransportationType[] = ['driving', 'cycling', 'walking'];
 
-            transportationTypes.forEach((type) => {
-                directionsPromises.push(
-                  fetch(
-                    `${MAPBOX_DIRECTIONS_BASE_URL}/${type}/${origin[0]},${origin[1]};${destination[0]},${destination[1]}?steps=true&geometries=geojson&access_token=${MAPBOX_ACCESS_TOKEN}`
-                  ).then((response) => response.json())
-                );
-              });
+            transportationTypes.forEach(type => {
+                directionsPromises.push(fetch(`${MAPBOX_DIRECTIONS_BASE_URL}/${type}/${origin[0]},${origin[1]};${destination[0]},${destination[1]}?steps=true&geometries=geojson&access_token=${MAPBOX_ACCESS_TOKEN}`).then(response => response.json()));
+            });
 
             const results = await Promise.all(directionsPromises);
 
             const routeInfoMap: Record<TransportationType, any> = {
-                'driving': {},
-                'cycling': {},
-                'walking': {},
+                driving: {},
+                cycling: {},
+                walking: {},
             };
 
             transportationTypes.forEach((type, index) => {
                 const routeData = results[index].routes[0];
                 if (routeData) {
-                  const geometry = routeData.geometry;
-                  const coordinates = geometry.coordinates;
-          
-                  routeInfoMap[type] = {
-                    duration: this.secondsToMinutesHours(routeData.duration),
-                    distance: this.metersToMiles(routeData.distance),
-                    coordinates: coordinates,
-                  };
+                    const { geometry } = routeData;
+                    const { coordinates } = geometry;
+
+                    routeInfoMap[type] = {
+                        duration: this.secondsToMinutesHours(routeData.duration),
+                        distance: this.metersToMiles(routeData.distance),
+                        coordinates: coordinates,
+                    };
                 }
-              });
+            });
 
             return routeInfoMap;
 
-            // return current route info, and the temporary route 
-
-        } catch (error: any){
+            // return current route info, and the temporary route
+        } catch (error: any) {
             return undefined;
-            console.log("Error: ", error);
         }
-    }
+    };
 
     private static secondsToMinutesHours = (seconds: number) => {
         const hours = Math.floor(seconds / 3600);
         const minutes = Math.floor((seconds % 3600) / 60).toFixed(2);
 
-        if (hours === 0){
-            return `${minutes} min`
-        } else {
-            return `${hours} hr ${minutes} min`
+        if (hours === 0) {
+            return `${minutes} min`;
         }
-    }
-
-    private static metersToMiles = (meters: number) => {
-        return `${parseFloat((meters/1609.34).toFixed(2))} mi`;
-    }   
+        return `${hours} hr ${minutes} min`;
+    };
 
+    private static metersToMiles = (meters: number) => `${parseFloat((meters / 1609.34).toFixed(2))} mi`;
 }
 
 // const drivingQuery = await fetch(
@@ -136,4 +122,4 @@ export class MapboxApiUtility {
 //         distance: this.metersToMiles(routeData.distance),
 //         coordinates: coordinates
 //     }
-// })
\ No newline at end of file
+// })
diff --git a/src/client/views/nodes/MapBox/MarkerIcons.tsx b/src/client/views/nodes/MapBox/MarkerIcons.tsx
index a580fcaa0..087472112 100644
--- a/src/client/views/nodes/MapBox/MarkerIcons.tsx
+++ b/src/client/views/nodes/MapBox/MarkerIcons.tsx
@@ -17,8 +17,6 @@ import {
     faHouse,
     faLandmark,
     faLocationDot,
-    faLocationPin,
-    faMapPin,
     faMasksTheater,
     faMugSaucer,
     faPersonHiking,
@@ -65,6 +63,7 @@ export class MarkerIcons {
             iconProps.color = color;
         }
 
+        // eslint-disable-next-line react/jsx-props-no-spreading
         return <FontAwesomeIcon {...iconProps} size={size} />;
     }
 
diff --git a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx
index 189e2105d..fce52ef4b 100644
--- a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx
+++ b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx
@@ -118,9 +118,9 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
      * @param sidebarKey
      * @returns
      */
-    sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
+    sidebarAddDocument = (docsIn: Doc | Doc[], sidebarKey?: string) => {
         if (!this.layoutDoc._layout_showSidebar) this.toggleSidebar();
-        const docs = doc instanceof Doc ? [doc] : doc;
+        const docs = docsIn instanceof Doc ? [docsIn] : docsIn;
         docs.forEach(doc => {
             let existingPin = this.allPushpins.find(pin => pin.latitude === doc.latitude && pin.longitude === doc.longitude) ?? this.selectedPin;
             if (doc.latitude !== undefined && doc.longitude !== undefined && !existingPin) {
@@ -139,7 +139,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
             }
         }); // add to annotation list
 
-        return this.addDocument(doc, sidebarKey); // add to sidebar list
+        return this.addDocument(docs, sidebarKey); // add to sidebar list
     };
 
     removeMapDocument = (doc: Doc | Doc[], annotationKey?: string) => {
@@ -168,7 +168,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
         setupMoveUpEvents(
             this,
             e,
-            (e, down, delta) =>
+            (moveEv, down, delta) =>
                 runInAction(() => {
                     const localDelta = this._props
                         .ScreenToLocalTransform()
@@ -243,10 +243,10 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
         const docView = this.DocumentView?.();
         docView &&
             DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(docView, sourceAnchorCreator, targetCreator), e.pageX, e.pageY, {
-                dragComplete: e => {
-                    if (!e.aborted && e.annoDragData && e.annoDragData.linkSourceDoc && e.annoDragData.dropDocument && e.linkDocument) {
-                        e.annoDragData.linkSourceDoc.followLinkToggle = e.annoDragData.dropDocument.annotationOn === this.Document;
-                        e.annoDragData.linkSourceDoc.followLinkZoom = false;
+                dragComplete: dragEv => {
+                    if (!dragEv.aborted && dragEv.annoDragData && dragEv.annoDragData.linkSourceDoc && dragEv.annoDragData.dropDocument && dragEv.linkDocument) {
+                        dragEv.annoDragData.linkSourceDoc.followLinkToggle = dragEv.annoDragData.dropDocument.annotationOn === this.Document;
+                        dragEv.annoDragData.linkSourceDoc.followLinkZoom = false;
                     }
                 },
             });
@@ -680,23 +680,23 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
         setupMoveUpEvents(
             e,
             e,
-            e => {
+            moveEv => {
                 if (!dragClone) {
                     dragClone = this._dragRef.current?.cloneNode(true) as HTMLDivElement;
                     dragClone.style.position = 'absolute';
                     dragClone.style.zIndex = '10000';
                     DragManager.Root().appendChild(dragClone);
                 }
-                dragClone.style.transform = `translate(${e.clientX - 15}px, ${e.clientY - 15}px)`;
+                dragClone.style.transform = `translate(${moveEv.clientX - 15}px, ${moveEv.clientY - 15}px)`;
                 return false;
             },
-            e => {
+            upEv => {
                 if (!dragClone) return;
                 DragManager.Root().removeChild(dragClone);
-                let target = document.elementFromPoint(e.x, e.y);
+                let target = document.elementFromPoint(upEv.x, upEv.y);
                 while (target) {
                     if (target === this._ref.current) {
-                        const cpt = this.ScreenToLocalBoxXf().transformPoint(e.clientX, e.clientY);
+                        const cpt = this.ScreenToLocalBoxXf().transformPoint(upEv.clientX, upEv.clientY);
                         const x = cpt[0] - (this._props.PanelWidth() - this.sidebarWidth()) / 2;
                         const y = cpt[1] - 32 /* height of search bar */ - this._props.PanelHeight() / 2;
                         const location = this._bingMap.current.tryPixelToLocation(new this.MicrosoftMaps.Point(x, y));
@@ -706,7 +706,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<FieldViewProps>
                     target = target.parentElement;
                 }
             },
-            e => {
+            () => {
                 const createPin = () => this.createPushpin(this.Document.latitude, this.Document.longitude, this.Document.map);
                 if (this.bingSearchBarContents) {
                     this.bingSearch().then(createPin);
diff --git a/src/client/views/nodes/RadialMenu.tsx b/src/client/views/nodes/RadialMenu.tsx
index 16450c359..48da4937a 100644
--- a/src/client/views/nodes/RadialMenu.tsx
+++ b/src/client/views/nodes/RadialMenu.tsx
@@ -6,22 +6,57 @@ import { RadialMenuItem, RadialMenuProps } from './RadialMenuItem';
 
 @observer
 export class RadialMenu extends React.Component {
+    // eslint-disable-next-line no-use-before-define
     static Instance: RadialMenu;
     static readonly buffer = 20;
 
+    @observable private _mouseX: number = -1;
+    @observable private _mouseY: number = -1;
+    @observable private _shouldDisplay: boolean = false;
+    @observable private _mouseDown: boolean = false;
+    @observable private _closest: number = -1;
+    @observable private _pageX: number = 0;
+    @observable private _pageY: number = 0;
+    @observable _display: boolean = false;
+    @observable private _yRelativeToTop: boolean = true;
+    @observable private _items: Array<RadialMenuProps> = [];
+    private _reactionDisposer?: IReactionDisposer;
+
     constructor(props: any) {
         super(props);
         makeObservable(this);
         RadialMenu.Instance = this;
     }
 
-    @observable private _mouseX: number = -1;
-    @observable private _mouseY: number = -1;
-    @observable private _shouldDisplay: boolean = false;
-    @observable private _mouseDown: boolean = false;
-    private _reactionDisposer?: IReactionDisposer;
+    componentDidMount() {
+        document.addEventListener('pointerdown', this.onPointerDown);
+        document.addEventListener('pointerup', this.onPointerUp);
+        this.previewcircle();
+        this._reactionDisposer = reaction(
+            () => this._shouldDisplay,
+            () =>
+                this._shouldDisplay &&
+                !this._mouseDown &&
+                runInAction(() => {
+                    this._display = true;
+                })
+        );
+    }
 
-    public used: boolean = false;
+    componentDidUpdate() {
+        this.previewcircle();
+    }
+    componentWillUnmount() {
+        document.removeEventListener('pointerdown', this.onPointerDown);
+
+        document.removeEventListener('pointerup', this.onPointerUp);
+        this._reactionDisposer && this._reactionDisposer();
+    }
+
+    @computed get menuItems() {
+        // eslint-disable-next-line react/jsx-props-no-spreading
+        return this._items.map((item, index) => <RadialMenuItem {...item} key={item.description} closeMenu={this.closeMenu} max={this._items.length} min={index} selected={this._closest} />);
+    }
 
     catchTouch = (te: React.TouchEvent) => {
         te.stopPropagation();
@@ -33,13 +68,9 @@ export class RadialMenu extends React.Component {
         this._mouseDown = true;
         this._mouseX = e.clientX;
         this._mouseY = e.clientY;
-        this.used = false;
         document.addEventListener('pointermove', this.onPointerMove);
     };
 
-    @observable
-    private _closest: number = -1;
-
     @action
     onPointerMove = (e: PointerEvent) => {
         const curX = e.clientX;
@@ -65,7 +96,6 @@ export class RadialMenu extends React.Component {
     };
     @action
     onPointerUp = (e: PointerEvent) => {
-        this.used = true;
         this._mouseDown = false;
         const curX = e.clientX;
         const curY = e.clientY;
@@ -78,86 +108,6 @@ export class RadialMenu extends React.Component {
             this._items[this._closest].event();
         }
     };
-    componentWillUnmount() {
-        document.removeEventListener('pointerdown', this.onPointerDown);
-
-        document.removeEventListener('pointerup', this.onPointerUp);
-        this._reactionDisposer && this._reactionDisposer();
-    }
-
-    @action
-    componentDidMount() {
-        document.addEventListener('pointerdown', this.onPointerDown);
-        document.addEventListener('pointerup', this.onPointerUp);
-        this.previewcircle();
-        this._reactionDisposer = reaction(
-            () => this._shouldDisplay,
-            () => this._shouldDisplay && !this._mouseDown && runInAction(() => (this._display = true))
-        );
-    }
-
-    componentDidUpdate = () => {
-        this.previewcircle();
-    };
-
-    @observable private _pageX: number = 0;
-    @observable private _pageY: number = 0;
-    @observable _display: boolean = false;
-    @observable private _yRelativeToTop: boolean = true;
-
-    @observable private _width: number = 0;
-    @observable private _height: number = 0;
-
-    getItems() {
-        return this._items;
-    }
-
-    @action
-    addItem(item: RadialMenuProps) {
-        if (this._items.indexOf(item) === -1) {
-            this._items.push(item);
-        }
-    }
-
-    @observable
-    private _items: Array<RadialMenuProps> = [];
-
-    @action
-    displayMenu = (x: number, y: number) => {
-        //maxX and maxY will change if the UI/font size changes, but will work for any amount
-        //of items added to the menu
-        this._mouseX = x;
-        this._mouseY = y;
-        this._shouldDisplay = true;
-    };
-    // @computed
-    // get pageX() {
-    //     const x = this._pageX;
-    //     if (x < 0) {
-    //         return 0;
-    //     }
-    //     const width = this._width;
-    //     if (x + width > window.innerWidth - RadialMenu.buffer) {
-    //         return window.innerWidth - RadialMenu.buffer - width;
-    //     }
-    //     return x;
-    // }
-    // @computed
-    // get pageY() {
-    //     const y = this._pageY;
-    //     if (y < 0) {
-    //         return 0;
-    //     }
-    //     const height = this._height;
-    //     if (y + height > window.innerHeight - RadialMenu.buffer) {
-    //         return window.innerHeight - RadialMenu.buffer - height;
-    //     }
-    //     return y;
-    // }
-
-    @computed get menuItems() {
-        return this._items.map((item, index) => <RadialMenuItem {...item} key={item.description} closeMenu={this.closeMenu} max={this._items.length} min={index} selected={this._closest} />);
-    }
 
     @action
     closeMenu = () => {
@@ -166,14 +116,6 @@ export class RadialMenu extends React.Component {
         this._shouldDisplay = false;
     };
 
-    @action
-    openMenu = (x: number, y: number) => {
-        this._pageX = x;
-        this._pageY = y;
-        this._shouldDisplay;
-        this._display = true;
-    };
-
     @action
     clearItems() {
         this._items = [];
diff --git a/src/client/views/nodes/RadialMenuItem.tsx b/src/client/views/nodes/RadialMenuItem.tsx
index 91dc37d34..6f10e7b65 100644
--- a/src/client/views/nodes/RadialMenuItem.tsx
+++ b/src/client/views/nodes/RadialMenuItem.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/require-default-props */
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { observer } from 'mobx-react';
@@ -53,6 +54,7 @@ export class RadialMenuItem extends React.Component<RadialMenuProps> {
                 case 2:
                     color = 'lightgray';
                     break;
+                default:
             }
             if (circlemax % 3 === 1 && circlemin === circlemax - 1) {
                 color = '#c2c2c5';
@@ -80,7 +82,6 @@ export class RadialMenuItem extends React.Component<RadialMenuProps> {
         const avg = (circlemin / circlemax + (circlemin + 1) / circlemax) / 2;
         const degrees = 360 * avg;
         const x = 100 * Math.cos((degrees * Math.PI) / 180);
-        const y = -125 * Math.sin((degrees * Math.PI) / 180);
         return x;
     }
 
@@ -91,7 +92,6 @@ export class RadialMenuItem extends React.Component<RadialMenuProps> {
         this.props.max ? (circlemax = this.props.max) : null;
         const avg = (circlemin / circlemax + (circlemin + 1) / circlemax) / 2;
         const degrees = 360 * avg;
-        const x = 125 * Math.cos((degrees * Math.PI) / 180);
         const y = -100 * Math.sin((degrees * Math.PI) / 180);
         return y;
     }
diff --git a/src/client/views/nodes/RecordingBox/ProgressBar.tsx b/src/client/views/nodes/RecordingBox/ProgressBar.tsx
index 1bb2b7c84..62798bc2f 100644
--- a/src/client/views/nodes/RecordingBox/ProgressBar.tsx
+++ b/src/client/views/nodes/RecordingBox/ProgressBar.tsx
@@ -1,31 +1,33 @@
+/* eslint-disable react/no-array-index-key */
+/* eslint-disable react/require-default-props */
 import * as React from 'react';
-import { useEffect, useState, useCallback, useRef } from "react"
-import "./ProgressBar.scss"
+import { useEffect, useState, useRef } from 'react';
+import './ProgressBar.scss';
 import { MediaSegment } from './RecordingView';
 
 interface ProgressBarProps {
-    videos: MediaSegment[],
-    setVideos: React.Dispatch<React.SetStateAction<MediaSegment[]>>,
-    orderVideos: boolean,
-    progress: number,
-    recording: boolean,
-    doUndo: boolean,
-    setCanUndo?: React.Dispatch<React.SetStateAction<boolean>>,
+    videos: MediaSegment[];
+    setVideos: React.Dispatch<React.SetStateAction<MediaSegment[]>>;
+    orderVideos: boolean;
+    progress: number;
+    recording: boolean;
+    doUndo: boolean;
+    setCanUndo?: React.Dispatch<React.SetStateAction<boolean>>;
 }
 
 interface SegmentBox {
-    endTime: number,
-    startTime: number,
-    order: number,
+    endTime: number;
+    startTime: number;
+    order: number;
 }
 interface CurrentHover {
-    index: number,
-    minX: number,
-    maxX: number
+    index: number;
+    minX: number;
+    maxX: number;
 }
 
 export function ProgressBar(props: ProgressBarProps) {
-    const progressBarRef = useRef<HTMLDivElement | null>(null)
+    const progressBarRef = useRef<HTMLDivElement | null>(null);
 
     // the actual list of JSX elements rendered as segments
     const [segments, setSegments] = useState<JSX.Element[]>([]);
@@ -47,8 +49,6 @@ export function ProgressBar(props: ProgressBarProps) {
     // update the canUndo props based on undo stack
     useEffect(() => props.setCanUndo?.(undoStack.length > 0), [undoStack.length]);
 
-    // useEffect for undo - brings back the most recently deleted segment
-    useEffect(() => handleUndo(), [props.doUndo])
     const handleUndo = () => {
         // get the last element from the undo if it exists
         if (undoStack.length === 0) return;
@@ -59,27 +59,36 @@ export function ProgressBar(props: ProgressBarProps) {
         // update the removed time and place element back into ordered
         setTotalRemovedTime(prevRemoved => prevRemoved - (last.endTime - last.startTime));
         setOrdered(prevOrdered => [...prevOrdered, last]);
-    }
+    };
+    // useEffect for undo - brings back the most recently deleted segment
+    useEffect(() => handleUndo(), [props.doUndo]);
 
     // useEffect for recording changes - changes style to disabled and adds the "expanding-segment"
     useEffect(() => {
         // get segments segment's html using it's id -> make them appeared disabled (or enabled)
-        segments.forEach((seg) => document.getElementById(seg.props.id)?.classList.toggle('segment-disabled', props.recording));
+        segments.forEach(seg => document.getElementById(seg.props.id)?.classList.toggle('segment-disabled', props.recording));
         progressBarRef.current?.classList.toggle('progressbar-disabled', props.recording);
 
         if (props.recording)
-            setSegments(prevSegments => [...prevSegments, <div key='segment-expanding' id='segment-expanding' className='segment segment-expanding blink' style={{ width: 'fit-content' }}>{props.videos.length + 1}</div>]);
-    }, [props.recording])
-
+            setSegments(prevSegments => [
+                ...prevSegments,
+                <div key="segment-expanding" id="segment-expanding" className="segment segment-expanding blink" style={{ width: 'fit-content' }}>
+                    {props.videos.length + 1}
+                </div>,
+            ]);
+    }, [props.recording]);
 
     // useEffect that updates the segmentsJSX, which is rendered
     // only updated when ordered is updated or if the user is dragging around a segment
     useEffect(() => {
         const totalTime = props.progress * 1000 - totalRemovedTime;
-        const segmentsJSX = ordered.map((seg, i) =>
-            <div key={`segment-${i}`} id={`segment-${i}`} className={dragged === i ? 'segment-hide' : 'segment'} style={{ width: `${((seg.endTime - seg.startTime) / totalTime) * 100}%` }}>{seg.order + 1}</div>);
+        const segmentsJSX = ordered.map((seg, i) => (
+            <div key={`segment-${i}`} id={`segment-${i}`} className={dragged === i ? 'segment-hide' : 'segment'} style={{ width: `${((seg.endTime - seg.startTime) / totalTime) * 100}%` }}>
+                {seg.order + 1}
+            </div>
+        ));
 
-        setSegments(segmentsJSX)
+        setSegments(segmentsJSX);
     }, [dragged, ordered]);
 
     // useEffect for dragged - update the cursor to be grabbing while grabbing
@@ -89,14 +98,14 @@ export function ProgressBar(props: ProgressBarProps) {
 
     // to imporve performance, only want to update the CSS width, not re-render the whole JSXList
     useEffect(() => {
-        if (!props.recording) return
+        if (!props.recording) return;
         const totalTime = props.progress * 1000 - totalRemovedTime;
         let remainingTime = totalTime;
         segments.forEach((seg, i) => {
             // for the last segment, we need to set that directly
             if (i === segments.length - 1) return;
             // update remaining time
-            remainingTime -= (ordered[i].endTime - ordered[i].startTime);
+            remainingTime -= ordered[i].endTime - ordered[i].startTime;
 
             // update the width for this segment
             const htmlId = seg.props.id;
@@ -106,8 +115,7 @@ export function ProgressBar(props: ProgressBarProps) {
 
         // update the width of the expanding segment using the remaining time
         const segExapandHtml = document.getElementById('segment-expanding');
-        if (segExapandHtml)
-            segExapandHtml.style.width = ordered.length === 0 ? '100%' : `${(remainingTime / totalTime) * 100}%`;
+        if (segExapandHtml) segExapandHtml.style.width = ordered.length === 0 ? '100%' : `${(remainingTime / totalTime) * 100}%`;
     }, [props.progress]);
 
     // useEffect for props.videos - update the ordered array when a new video is added
@@ -120,9 +128,7 @@ export function ProgressBar(props: ProgressBarProps) {
         // in this case, a new video is added -> push it onto ordered
         if (order >= ordered.length) {
             const { endTime, startTime } = props.videos.lastElement();
-            setOrdered(prevOrdered => {
-                return [...prevOrdered, { endTime, startTime, order }];
-            });
+            setOrdered(prevOrdered => [...prevOrdered, { endTime, startTime, order }]);
         }
 
         // in this case, a video is removed
@@ -132,7 +138,7 @@ export function ProgressBar(props: ProgressBarProps) {
     }, [props.videos]);
 
     // useEffect for props.orderVideos - matched the order array with the videos array before the export
-    useEffect(() => props.setVideos(vids => ordered.map((seg) => vids[seg.order])), [props.orderVideos]);
+    useEffect(() => props.setVideos(vids => ordered.map(seg => vids[seg.order])), [props.orderVideos]);
 
     // useEffect for removed - handles logic for removing a segment
     useEffect(() => {
@@ -151,36 +157,68 @@ export function ProgressBar(props: ProgressBarProps) {
     // returns the new currentHover based on the new index
     const updateCurrentHover = (segId: number): CurrentHover | null => {
         // get the segId of the segment that will become the new bounding area
-        const rect = progressBarRef.current?.children[segId].getBoundingClientRect()
-        if (rect == null) return null
+        const rect = progressBarRef.current?.children[segId].getBoundingClientRect();
+        if (rect == null) return null;
         return {
             index: segId,
             minX: rect.x,
             maxX: rect.x + rect.width,
-        }
-    }
+        };
+    };
+
+    const swapSegments = (oldIndex: number, newIndex: number) => {
+        if (newIndex == null) return;
+        setOrdered(prevOrdered => {
+            const temp = { ...prevOrdered[oldIndex] };
+            prevOrdered[oldIndex] = prevOrdered[newIndex];
+            prevOrdered[newIndex] = temp;
+            return prevOrdered;
+        });
+        // update visually where the segment is hovering over
+        setDragged(newIndex);
+    };
+
+    // functions for the floating segment that tracks the cursor while grabbing it
+    const initDetachSegment = (dot: HTMLDivElement, rect: DOMRect) => {
+        dot.classList.add('segment-selected');
+        dot.style.transitionDuration = '0s';
+        dot.style.position = 'absolute';
+        dot.style.zIndex = '999';
+        dot.style.width = `${rect.width}px`;
+        dot.style.height = `${rect.height}px`;
+        dot.style.left = `${rect.x}px`;
+        dot.style.top = `${rect.y}px`;
+        dot.draggable = false;
+        document.body.append(dot);
+    };
+    const followCursor = (event: PointerEvent, dot: HTMLDivElement): void => {
+        // event.stopPropagation()
+        const { width, height } = dot.getBoundingClientRect();
+        dot.style.left = `${event.clientX - width / 2}px`;
+        dot.style.top = `${event.clientY - height / 2}px`;
+    };
 
     // pointerdown event for the progress bar
-  const onPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {
-           // don't move the videobox element
-    e.stopPropagation();  
+    const onPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {
+        // don't move the videobox element
+        e.stopPropagation();
 
         // if recording, do nothing
-      if (props.recording) return;
+        if (props.recording) return;
 
         // get the segment the user clicked on to be dragged
-        const clickedSegment = e.target as HTMLDivElement & EventTarget
+        const clickedSegment = e.target as HTMLDivElement & EventTarget;
 
         // get the profess bar ro add event listeners
         // don't do anything if null
-        const progressBar = progressBarRef.current
-        if (progressBar == null || clickedSegment.id === progressBar.id) return
+        const progressBar = progressBarRef.current;
+        if (progressBar == null || clickedSegment.id === progressBar.id) return;
 
         // if holding shift key, let's remove that segment
         if (e.shiftKey) {
             const segId = parseInt(clickedSegment.id.split('-')[1]);
             setRemoved(segId);
-            return
+            return;
         }
 
         // if holding ctrl key and click, let's undo that segment #hiddenfeature lol
@@ -192,26 +230,26 @@ export function ProgressBar(props: ProgressBarProps) {
         // if we're here, the user is dragging a segment around
         // let the progress bar capture all the pointer events until the user releases (pointerUp)
         const ptrId = e.pointerId;
-        progressBar.setPointerCapture(ptrId)
+        progressBar.setPointerCapture(ptrId);
 
-        const rect = clickedSegment.getBoundingClientRect()
-        // id for segment is like 'segment-1' or 'segment-10', 
+        const rect = clickedSegment.getBoundingClientRect();
+        // id for segment is like 'segment-1' or 'segment-10',
         // so this works to get the id
-        const segId = parseInt(clickedSegment.id.split('-')[1])
+        const segId = parseInt(clickedSegment.id.split('-')[1]);
         // set the selected segment to be the one dragged
-        setDragged(segId)
+        setDragged(segId);
 
-        // this is the logic for storing the lower X bound and upper X bound to know 
+        // this is the logic for storing the lower X bound and upper X bound to know
         // whether a swap is needed between two segments
         let currentHover: CurrentHover = {
             index: segId,
             minX: rect.x,
             maxX: rect.x + rect.width,
-        }
+        };
 
         // create the floating segment that tracks the cursor
-        const detchedSegment = document.createElement("div")
-        initDeatchSegment(detchedSegment, rect);
+        const detchedSegment = document.createElement('div');
+        initDetachSegment(detchedSegment, rect);
 
         const updateSegmentOrder = (event: PointerEvent): void => {
             event.stopPropagation();
@@ -219,6 +257,7 @@ export function ProgressBar(props: ProgressBarProps) {
 
             // this fixes a bug where pointerup doesn't fire while cursor is upped while being dragged
             if (!progressBar.hasPointerCapture(ptrId)) {
+                // eslint-disable-next-line no-use-before-define
                 placeSegmentandCleanup();
                 return;
             }
@@ -228,24 +267,23 @@ export function ProgressBar(props: ProgressBarProps) {
             const curX = event.clientX;
             // handle the left bound
             if (curX < currentHover.minX && currentHover.index > 0) {
-                swapSegments(currentHover.index, currentHover.index - 1)
-                currentHover = updateCurrentHover(currentHover.index - 1) ?? currentHover
+                swapSegments(currentHover.index, currentHover.index - 1);
+                currentHover = updateCurrentHover(currentHover.index - 1) ?? currentHover;
             }
             // handle the right bound
             else if (curX > currentHover.maxX && currentHover.index < segments.length - 1) {
-                swapSegments(currentHover.index, currentHover.index + 1)
-                currentHover = updateCurrentHover(currentHover.index + 1) ?? currentHover
+                swapSegments(currentHover.index, currentHover.index + 1);
+                currentHover = updateCurrentHover(currentHover.index + 1) ?? currentHover;
             }
-        }
+        };
 
         // handles when the user is done dragging the segment (pointerUp)
         const placeSegmentandCleanup = (event?: PointerEvent): void => {
             event?.stopPropagation();
             event?.preventDefault();
             // if they put the segment outside of the bounds, remove it
-            if (event && (event.clientX < 0 || event.clientX > document.body.clientWidth || event.clientY < 0 || event.clientY > document.body.clientHeight))
-                setRemoved(currentHover.index);
-            
+            if (event && (event.clientX < 0 || event.clientX > document.body.clientWidth || event.clientY < 0 || event.clientY > document.body.clientHeight)) setRemoved(currentHover.index);
+
             // remove the update event listener for pointermove
             progressBar.removeEventListener('pointermove', updateSegmentOrder);
             // remove the floating segment from the DOM
@@ -253,49 +291,16 @@ export function ProgressBar(props: ProgressBarProps) {
             // dragged is -1 is equiv to nothing being dragged, so the normal state
             // so this will place the segment in it's location and update the segment bar
             setDragged(-1);
-        }
+        };
 
         // event listeners that allow the user to drag and release the floating segment
         progressBar.addEventListener('pointermove', updateSegmentOrder);
         progressBar.addEventListener('pointerup', placeSegmentandCleanup, { once: true });
-    }
-
-    const swapSegments = (oldIndex: number, newIndex: number) => {
-        if (newIndex == null) return;
-        setOrdered(prevOrdered => {
-            const temp = { ...prevOrdered[oldIndex] }
-            prevOrdered[oldIndex] = prevOrdered[newIndex]
-            prevOrdered[newIndex] = temp
-            return prevOrdered
-        });
-        // update visually where the segment is hovering over
-        setDragged(newIndex);
-    }
-
-    // functions for the floating segment that tracks the cursor while grabbing it  
-    const initDeatchSegment = (dot: HTMLDivElement, rect: DOMRect) => {
-        dot.classList.add("segment-selected");
-        dot.style.transitionDuration = '0s';
-        dot.style.position = 'absolute';
-        dot.style.zIndex = '999';
-        dot.style.width = `${rect.width}px`;
-        dot.style.height = `${rect.height}px`;
-        dot.style.left = `${rect.x}px`;
-        dot.style.top = `${rect.y}px`;
-        dot.draggable = false;
-        document.body.append(dot);
-    }
-    const followCursor = (event: PointerEvent, dot: HTMLDivElement): void => {
-        // event.stopPropagation()
-        const { width, height } = dot.getBoundingClientRect();
-        dot.style.left = `${event.clientX - width / 2}px`;
-        dot.style.top = `${event.clientY - height / 2}px`;
-    }
-
+    };
 
     return (
         <div className="progressbar" id="progressbar" onPointerDown={onPointerDown} ref={progressBarRef}>
             {segments}
         </div>
-    )
-}
\ No newline at end of file
+    );
+}
diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx
index 7d123d90c..2bc749e1b 100644
--- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx
@@ -44,18 +44,11 @@ export class RecordingBox extends ViewBoxBaseComponent<FieldViewProps>() {
     }
 
     @observable result: Upload.AccessPathInfo | undefined = undefined;
-    @observable videoDuration: number | undefined = undefined;
-
-    @action
-    setVideoDuration = (duration: number) => {
-        this.videoDuration = duration;
-    };
 
     @action
     setResult = (info: Upload.AccessPathInfo, presentation?: Presentation) => {
         this.result = info;
         this.dataDoc.type = DocumentType.VID;
-        this.dataDoc[this.fieldKey + '_duration'] = this.videoDuration;
 
         this.dataDoc.layout = VideoBox.LayoutString(this.fieldKey);
         this.dataDoc[this._props.fieldKey] = new VideoField(this.result.accessPaths.client);
@@ -194,15 +187,7 @@ export class RecordingBox extends ViewBoxBaseComponent<FieldViewProps>() {
     render() {
         return (
             <div className="recordingBox" style={{ width: '100%' }} ref={this._ref}>
-                {!this.result && (
-                    <RecordingView
-                        forceTrackScreen={BoolCast(this.layoutDoc[this.fieldKey + '_trackScreen'])}
-                        getControls={this.getControls}
-                        setResult={this.setResult}
-                        setDuration={this.setVideoDuration}
-                        id={DocCast(this.Document.proto)?.[Id] || ''}
-                    />
-                )}
+                {!this.result && <RecordingView forceTrackScreen={BoolCast(this.layoutDoc[this.fieldKey + '_trackScreen'])} getControls={this.getControls} setResult={this.setResult} id={DocCast(this.Document.proto)?.[Id] || ''} />}
             </div>
         );
     }
diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx
index 9c05a3e94..b8451fe60 100644
--- a/src/client/views/nodes/RecordingBox/RecordingView.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx
@@ -1,3 +1,6 @@
+/* eslint-disable jsx-a11y/label-has-associated-control */
+/* eslint-disable react/button-has-type */
+/* eslint-disable jsx-a11y/control-has-associated-label */
 import * as React from 'react';
 import { useEffect, useRef, useState } from 'react';
 import { IconContext } from 'react-icons';
@@ -19,19 +22,18 @@ export interface MediaSegment {
 
 interface IRecordingViewProps {
     setResult: (info: Upload.AccessPathInfo, presentation?: Presentation) => void;
-    setDuration: (seconds: number) => void;
     id: string;
     getControls: (record: () => void, pause: () => void, finish: () => void) => void;
     forceTrackScreen: boolean;
 }
 
 const MAXTIME = 100000;
+const iconVals = { color: '#cc1c08', className: 'video-edit-buttons' };
 
 export function RecordingView(props: IRecordingViewProps) {
     const [recording, setRecording] = useState(false);
     const recordingTimerRef = useRef<number>(0);
     const [recordingTimer, setRecordingTimer] = useState(0); // unit is 0.01 second
-    const [playing, setPlaying] = useState(false);
     const [progress, setProgress] = useState(0);
 
     // acts as a "refresh state" to tell progressBar when to undo
@@ -62,7 +64,7 @@ export function RecordingView(props: IRecordingViewProps) {
     useEffect(() => {
         if (finished) {
             // make the total presentation that'll match the concatted video
-            let concatPres = (trackScreen || props.forceTrackScreen) && TrackMovements.Instance.concatPresentations(videos.map(v => v.presentation as Presentation));
+            const concatPres = (trackScreen || props.forceTrackScreen) && TrackMovements.Instance.concatPresentations(videos.map(v => v.presentation as Presentation));
 
             // this async function uses the server to create the concatted video and then sets the result to it's accessPaths
             (async () => {
@@ -100,16 +102,16 @@ export function RecordingView(props: IRecordingViewProps) {
         return () => clearInterval(interval);
     }, [recording]);
 
+    const setVideoProgressHelper = (curProgrss: number) => {
+        const newProgress = (curProgrss / MAXTIME) * 100;
+        setProgress(newProgress);
+    };
+
     useEffect(() => {
         setVideoProgressHelper(recordingTimer);
         recordingTimerRef.current = recordingTimer;
     }, [recordingTimer]);
 
-    const setVideoProgressHelper = (progress: number) => {
-        const newProgress = (progress / MAXTIME) * 100;
-        setProgress(newProgress);
-    };
-
     const startShowingStream = async (mediaConstraints = DEFAULT_MEDIA_CONSTRAINTS) => {
         const stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);
 
@@ -131,7 +133,7 @@ export function RecordingView(props: IRecordingViewProps) {
             if (event.data.size > 0) videoChunks.push(event.data);
         };
 
-        videoRecorder.current.onstart = (event: any) => {
+        videoRecorder.current.onstart = () => {
             setRecording(true);
             // start the recording api when the video recorder starts
             (trackScreen || props.forceTrackScreen) && TrackMovements.Instance.start();
@@ -149,7 +151,7 @@ export function RecordingView(props: IRecordingViewProps) {
 
                 // depending on if a presenation exists, add it to the video
                 const presentation = TrackMovements.Instance.yieldPresentation();
-                setVideos(videos => [...videos, presentation != null && (trackScreen || props.forceTrackScreen) ? { ...nextVideo, presentation } : nextVideo]);
+                setVideos(theVideos => [...theVideos, presentation != null && (trackScreen || props.forceTrackScreen) ? { ...nextVideo, presentation } : nextVideo]);
             }
 
             // reset the temporary chunks
@@ -186,7 +188,7 @@ export function RecordingView(props: IRecordingViewProps) {
             e,
             returnTrue,
             returnFalse,
-            e => {
+            () => {
                 // start recording if not already recording
                 if (!videoRecorder.current || videoRecorder.current.state === 'inactive') record();
 
@@ -202,14 +204,8 @@ export function RecordingView(props: IRecordingViewProps) {
         setDoUndo(prev => !prev);
     };
 
-    const handleOnTimeUpdate = () => {
-        playing && setVideoProgressHelper(videoElementRef.current!.currentTime);
-    };
-
     const millisecondToMinuteSecond = (milliseconds: number) => {
-        const toTwoDigit = (digit: number) => {
-            return String(digit).length == 1 ? '0' + digit : digit;
-        };
+        const toTwoDigit = (digit: number) => (String(digit).length === 1 ? '0' + digit : digit);
         const minutes = Math.floor((milliseconds % (1000 * 60 * 60)) / (1000 * 60));
         const seconds = Math.floor((milliseconds % (1000 * 60)) / 1000);
         return toTwoDigit(minutes) + ' : ' + toTwoDigit(seconds);
@@ -219,10 +215,11 @@ export function RecordingView(props: IRecordingViewProps) {
         props.getControls(record, pause, finish);
     }, []);
 
+    const iconUndoVals = React.useMemo(() => ({ color: 'grey', className: 'video-edit-buttons', style: { display: canUndo ? 'inherit' : 'none' } }), []);
     return (
         <div className="recording-container">
             <div className="video-wrapper">
-                <video id={`video-${props.id}`} autoPlay muted onTimeUpdate={() => handleOnTimeUpdate()} ref={videoElementRef} />
+                <video id={`video-${props.id}`} autoPlay muted ref={videoElementRef} />
                 <div className="recording-sign">
                     <span className="dot" />
                     <p className="timer">{millisecondToMinuteSecond(recordingTimer * 10)}</p>
@@ -246,10 +243,10 @@ export function RecordingView(props: IRecordingViewProps) {
                         {!recording &&
                             (videos.length > 0 ? (
                                 <div className="options-wrapper video-edit-wrapper">
-                                    <IconContext.Provider value={{ color: 'grey', className: 'video-edit-buttons', style: { display: canUndo ? 'inherit' : 'none' } }}>
+                                    <IconContext.Provider value={iconUndoVals}>
                                         <MdBackspace onPointerDown={undoPrevious} />
                                     </IconContext.Provider>
-                                    <IconContext.Provider value={{ color: '#cc1c08', className: 'video-edit-buttons' }}>
+                                    <IconContext.Provider value={iconVals}>
                                         <FaCheckCircle
                                             onPointerDown={e => {
                                                 e.stopPropagation();
@@ -268,7 +265,7 @@ export function RecordingView(props: IRecordingViewProps) {
                                                 setTrackScreen(e.target.checked);
                                             }}
                                         />
-                                        <span className="checkmark"></span>
+                                        <span className="checkmark" />
                                         Track Screen
                                     </label>
                                 </div>
diff --git a/src/client/views/nodes/RecordingBox/index.ts b/src/client/views/nodes/RecordingBox/index.ts
index ff21eaed6..e4f9b5e55 100644
--- a/src/client/views/nodes/RecordingBox/index.ts
+++ b/src/client/views/nodes/RecordingBox/index.ts
@@ -1,2 +1,2 @@
-export * from './RecordingView'
-export * from './RecordingBox'
\ No newline at end of file
+export * from './RecordingView';
+export * from './RecordingBox';
diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx
index 60d7e4b00..5ebc50a1b 100644
--- a/src/client/views/nodes/ScriptingBox.tsx
+++ b/src/client/views/nodes/ScriptingBox.tsx
@@ -1,4 +1,5 @@
-let ReactTextareaAutocomplete = require('@webscopeio/react-textarea-autocomplete').default;
+/* 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';
@@ -17,10 +18,12 @@ import { ContextMenu } from '../ContextMenu';
 import { ViewBoxAnnotatableComponent } from '../DocComponent';
 import { EditableView } from '../EditableView';
 import { OverlayView } from '../OverlayView';
-import { FieldView, FieldViewProps } from '../nodes/FieldView';
+import { FieldView, FieldViewProps } from './FieldView';
 import { DocumentIconContainer } from './DocumentIcon';
 import './ScriptingBox.scss';
+
 const _global = (window /* browser */ || global) /* node */ as any;
+const ReactTextareaAutocomplete = require('@webscopeio/react-textarea-autocomplete').default;
 
 @observer
 export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@@ -79,26 +82,24 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     @computed({ keepAlive: true }) get rawScript() {
         return ScriptCast(this.dataDoc[this.fieldKey])?.script.originalScript ?? '';
     }
-    @computed({ keepAlive: true }) get functionName() {
-        return StrCast(this.dataDoc[this.fieldKey + '-functionName'], '');
-    }
-    @computed({ keepAlive: true }) get functionDescription() {
-        return StrCast(this.dataDoc[this.fieldKey + '-functionDescription'], '');
-    }
-    @computed({ keepAlive: true }) get compileParams() {
-        return Cast(this.dataDoc[this.fieldKey + '-params'], listSpec('string'), []);
-    }
-
     set rawScript(value) {
         this.dataDoc[this.fieldKey] = new ScriptField(undefined, undefined, value);
     }
+    @computed({ keepAlive: true }) get functionName() {
+        return StrCast(this.dataDoc[this.fieldKey + '-functionName'], '');
+    }
     set functionName(value) {
         this.dataDoc[this.fieldKey + '-functionName'] = value;
     }
+    @computed({ keepAlive: true }) get functionDescription() {
+        return StrCast(this.dataDoc[this.fieldKey + '-functionDescription'], '');
+    }
     set functionDescription(value) {
         this.dataDoc[this.fieldKey + '-functionDescription'] = value;
     }
-
+    @computed({ keepAlive: true }) get compileParams() {
+        return Cast(this.dataDoc[this.fieldKey + '-params'], listSpec('string'), []);
+    }
     set compileParams(value) {
         this.dataDoc[this.fieldKey + '-params'] = new List<string>(value);
     }
@@ -107,9 +108,8 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         if (typeof result === 'object') {
             const text = descrip ? result[1] : result[2];
             return text !== undefined ? text : '';
-        } else {
-            return '';
         }
+        return '';
     }
 
     onClickScriptDisable = returnAlways;
@@ -118,19 +118,18 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     componentDidMount() {
         this._props.setContentViewBox?.(this);
         this.rawText = this.rawScript;
-        const observer = new _global.ResizeObserver(
-            action((entries: any) => {
+        const resizeObserver = new _global.ResizeObserver(
+            action(() => {
                 const area = document.querySelector('textarea');
                 if (area) {
-                    for (const {} of entries) {
-                        const getCaretCoordinates = require('textarea-caret');
-                        const caret = getCaretCoordinates(area, this._selection);
-                        this.resetSuggestionPos(caret);
-                    }
+                    // eslint-disable-next-line global-require
+                    const getCaretCoordinates = require('textarea-caret');
+                    const caret = getCaretCoordinates(area, this._selection);
+                    this.resetSuggestionPos(caret);
                 }
             })
         );
-        observer.observe(document.getElementsByClassName('scriptingBox-outerDiv')[0]);
+        resizeObserver.observe(document.getElementsByClassName('scriptingBox-outerDiv')[0]);
     }
 
     @action
@@ -138,12 +137,12 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         if (!this._suggestionRef.current || !this._scriptTextRef.current) return;
         const suggestionWidth = this._suggestionRef.current.offsetWidth;
         const scriptWidth = this._scriptTextRef.current.offsetWidth;
-        const top = caret.top;
-        const x = this.dataDoc.x;
-        let left = caret.left;
+        const { top } = caret;
+        const { x } = this.dataDoc;
+        let { left } = caret;
         if (left + suggestionWidth > x + scriptWidth) {
             const diff = left + suggestionWidth - (x + scriptWidth);
-            left = left - diff;
+            left -= diff;
         }
 
         this._suggestionBoxX = left;
@@ -155,7 +154,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     }
 
     protected createDashEventsTarget = (ele: HTMLDivElement, dropFunc: (e: Event, de: DragManager.DropEvent) => void) => {
-        //used for stacking and masonry view
+        // used for stacking and masonry view
         if (ele) {
             this.dropDisposer?.();
             this.dropDisposer = DragManager.MakeDropTarget(ele, dropFunc, this.layoutDoc);
@@ -164,7 +163,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
 
     // only included in buttons, transforms scripting UI to a button
     @action
-    onFinish = () => (this.layoutDoc.layout_fieldKey = 'layout');
+    onFinish = () => {
+        this.layoutDoc.layout_fieldKey = 'layout';
+    };
 
     // displays error message
     @action
@@ -176,7 +177,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     @action
     onCompile = () => {
         const params: ScriptParam = {};
-        this.compileParams.forEach(p => (params[p.split(':')[0].trim()] = p.split(':')[1].trim()));
+        this.compileParams.forEach(p => {
+            params[p.split(':')[0].trim()] = p.split(':')[1].trim();
+        });
 
         const result = !this.rawText.trim()
             ? ({ compiled: false, errors: undefined } as any)
@@ -196,7 +199,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     onRun = () => {
         if (this.onCompile()) {
             const bindings: { [name: string]: any } = {};
-            this.paramsNames.forEach(key => (bindings[key] = this.dataDoc[key]));
+            this.paramsNames.forEach(key => {
+                bindings[key] = this.dataDoc[key];
+            });
             // binds vars so user doesnt have to refer to everything as this.<var>
             ScriptCast(this.dataDoc[this.fieldKey], null)?.script.run({ ...bindings, this: this.Document }, this.onError);
         }
@@ -247,7 +252,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
 
         this.dataDoc.name = this.functionName;
         this.dataDoc.description = this.functionDescription;
-        //this.dataDoc.parameters = this.compileParams;
+        // this.dataDoc.parameters = this.compileParams;
         this.dataDoc.script = this.rawScript;
 
         ScriptManager.Instance.addScript(this.dataDoc);
@@ -255,6 +260,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         this._scriptKeys = ScriptingGlobals.getGlobals();
         this._scriptingDescriptions = ScriptingGlobals.getDescriptions();
         this._scriptingParams = ScriptingGlobals.getParameters();
+        return undefined;
     };
 
     // overlays document numbers (ex. d32) over all documents when clicked on
@@ -267,7 +273,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     @action
     onDrop = (e: Event, de: DragManager.DropEvent, fieldKey: string) => {
         if (de.complete.docDragData) {
-            de.complete.docDragData.droppedDocuments.forEach(doc => (this.dataDoc[fieldKey] = doc));
+            de.complete.docDragData.droppedDocuments.forEach(doc => {
+                this.dataDoc[fieldKey] = doc;
+            });
             e.stopPropagation();
             return true;
         }
@@ -285,8 +293,7 @@ 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) => {
-        //@ts-ignore
-        const val = e.target.selectedOptions[0].value;
+        const val = (e.target as any).selectedOptions[0].value;
         this.dataDoc[name] = val[0] === 'S' ? val.substring(1) : val[0] === 'N' ? parseInt(val.substring(1)) : val.substring(1) === 'true';
     };
 
@@ -306,8 +313,26 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     };
 
     renderFunctionInputs() {
-        const descriptionInput = <textarea className="scriptingBox-textarea-inputs" onChange={e => (this.functionDescription = e.target.value)} placeholder="enter description here" value={this.functionDescription} />;
-        const nameInput = <textarea className="scriptingBox-textarea-inputs" onChange={e => (this.functionName = e.target.value)} placeholder="enter name here" value={this.functionName} />;
+        const descriptionInput = (
+            <textarea
+                className="scriptingBox-textarea-inputs"
+                onChange={e => {
+                    this.functionDescription = e.target.value;
+                }}
+                placeholder="enter description here"
+                value={this.functionDescription}
+            />
+        );
+        const nameInput = (
+            <textarea
+                className="scriptingBox-textarea-inputs"
+                onChange={e => {
+                    this.functionName = e.target.value;
+                }}
+                placeholder="enter name here"
+                value={this.functionName}
+            />
+        );
 
         return (
             <div className="scriptingBox-inputDiv" onPointerDown={e => this._props.isSelected() && e.stopPropagation()}>
@@ -339,7 +364,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         return (
             <div className="scriptingBox-paramInputs" onFocus={this.onFocus} onBlur={() => this._overlayDisposer?.()} ref={ele => ele && this.createDashEventsTarget(ele, (e, de) => this.onDrop(e, de, parameter))}>
                 <EditableView
-                    display={'block'}
+                    display="block"
                     maxHeight={72}
                     height={35}
                     fontSize={14}
@@ -371,7 +396,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         return (
             <div className="scriptingBox-paramInputs" style={{ overflowY: 'hidden' }}>
                 <EditableView
-                    display={'block'}
+                    display="block"
                     maxHeight={72}
                     height={35}
                     fontSize={14}
@@ -404,6 +429,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                             onChange={e => this.viewChanged(e, parameter)}
                             value={typeof this.dataDoc[parameter] === 'string' ? 'S' + StrCast(this.dataDoc[parameter]) : typeof this.dataDoc[parameter] === 'number' ? 'N' + NumCast(this.dataDoc[parameter]) : 'B' + BoolCast(this.dataDoc[parameter])}>
                             {types.map((type, i) => (
+                                // eslint-disable-next-line react/no-array-index-key
                                 <option key={i} className="scriptingBox-viewOption" value={(typeof type === 'string' ? 'S' : typeof type === 'number' ? 'N' : 'B') + type}>
                                     {' '}
                                     {type.toString()}{' '}
@@ -496,6 +522,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
 
     @action
     suggestionPos = () => {
+        // eslint-disable-next-line global-require
         const getCaretCoordinates = require('textarea-caret');
         const This = this;
         document.querySelector('textarea')?.addEventListener('input', function () {
@@ -509,7 +536,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
     keyHandler(e: any, pos: number) {
         e.stopPropagation();
         if (this._lastChar === 'Enter') {
-            this.rawText = this.rawText + ' ';
+            this.rawText += ' ';
         }
         if (e.key === '(') {
             this.suggestionPos();
@@ -524,20 +551,18 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
             }
         } else if (e.key === ')') {
             this._paramSuggestion = false;
-        } else {
-            if (e.key === 'Backspace') {
-                if (this._lastChar === '(') {
-                    this._paramSuggestion = false;
-                } else if (this._lastChar === ')') {
-                    if (this.rawText.slice(0, this.rawText.length - 1).split('(').length - 1 > this.rawText.slice(0, this.rawText.length - 1).split(')').length - 1) {
-                        if (this._scriptParamsText.length > 0) {
-                            this._paramSuggestion = true;
-                        }
+        } else if (e.key === 'Backspace') {
+            if (this._lastChar === '(') {
+                this._paramSuggestion = false;
+            } else if (this._lastChar === ')') {
+                if (this.rawText.slice(0, this.rawText.length - 1).split('(').length - 1 > this.rawText.slice(0, this.rawText.length - 1).split(')').length - 1) {
+                    if (this._scriptParamsText.length > 0) {
+                        this._paramSuggestion = true;
                     }
                 }
-            } else if (this.rawText.split('(').length - 1 <= this.rawText.split(')').length - 1) {
-                this._paramSuggestion = false;
             }
+        } else if (this.rawText.split('(').length - 1 <= this.rawText.split(')').length - 1) {
+            this._paramSuggestion = false;
         }
         this._lastChar = e.key === 'Backspace' ? this.rawText[this.rawText.length - 2] : e.key;
 
@@ -559,9 +584,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
 
             parameters.forEach((element: string, i: number) => {
                 if (i < numEntered - 1) {
-                    first = first + element;
+                    first += element;
                 } else if (i > numEntered - 1) {
-                    last = last + element;
+                    last += element;
                 }
             });
 
@@ -598,16 +623,16 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                     placeholder="write your script here"
                     onFocus={this.onFocus}
                     onBlur={() => this._overlayDisposer?.()}
-                    onChange={action((e: any) => (this.rawText = e.target.value))}
+                    onChange={action((e: any) => {
+                        this.rawText = e.target.value;
+                    })}
                     value={this.rawText}
-                    movePopupAsYouType={true}
+                    movePopupAsYouType
                     loadingComponent={() => <span>Loading</span>}
                     trigger={{
                         ' ': {
                             dataProvider: (token: any) => this.handleToken(token),
-                            component: (blob: any) => {
-                                return this.renderFuncListElement(blob.entity);
-                            },
+                            component: (blob: any) => this.renderFuncListElement(blob.entity),
                             output: (item: any, trigger: any) => {
                                 this._spaced = true;
                                 return trigger + item.trim();
@@ -615,9 +640,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                         },
                         '.': {
                             dataProvider: (token: any) => this.handleToken(token),
-                            component: (blob: any) => {
-                                return this.renderFuncListElement(blob.entity);
-                            },
+                            component: (blob: any) => this.renderFuncListElement(blob.entity),
                             output: (item: any, trigger: any) => {
                                 this._spaced = true;
                                 return trigger + item.trim();
@@ -653,16 +676,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         // params box on bottom
         const parameterInput = (
             <div className="scriptingBox-params">
-                <EditableView
-                    display={'block'}
-                    maxHeight={72}
-                    height={35}
-                    fontSize={22}
-                    contents={''}
-                    GetValue={returnEmptyString}
-                    SetValue={value => (value && value !== ' ' ? this.compileParam(value) : false)}
-                    placeholder={'enter parameters here'}
-                />
+                <EditableView display="block" maxHeight={72} height={35} fontSize={22} contents="" GetValue={returnEmptyString} SetValue={value => (value && value !== ' ' ? this.compileParam(value) : false)} placeholder="enter parameters here" />
             </div>
         );
 
@@ -670,13 +684,14 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
         const definedParameters = !this.compileParams.length ? null : (
             <div className="scriptingBox-plist" style={{ width: '30%' }}>
                 {this.compileParams.map((parameter, i) => (
+                    // eslint-disable-next-line react/no-array-index-key
                     <div key={i} className="scriptingBox-pborder" onKeyDown={e => e.key === 'Enter' && this._overlayDisposer?.()}>
                         <EditableView
-                            display={'block'}
+                            display="block"
                             maxHeight={72}
                             height={35}
                             fontSize={12}
-                            background-color={'beige'}
+                            background-color="beige"
                             contents={parameter}
                             GetValue={() => parameter}
                             SetValue={value => (value && value !== ' ' ? this.compileParam(value, i) : this.onDelete(i))}
@@ -749,6 +764,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
                 {!this.compileParams.length || !this.paramsNames ? null : (
                     <div className="scriptingBox-plist">
                         {this.paramsNames.map((parameter: string, i: number) => (
+                            // eslint-disable-next-line react/no-array-index-key
                             <div key={i} className="scriptingBox-pborder" onKeyDown={e => e.key === 'Enter' && this._overlayDisposer?.()}>
                                 <div className="scriptingBox-wrapper" style={{ maxHeight: '40px' }}>
                                     <div className="scriptingBox-paramNames"> {`${parameter}:${this.paramsTypes[i]} = `} </div>
diff --git a/src/client/views/nodes/SliderBox-components.tsx b/src/client/views/nodes/SliderBox-components.tsx
index e19f28f08..b9f215d77 100644
--- a/src/client/views/nodes/SliderBox-components.tsx
+++ b/src/client/views/nodes/SliderBox-components.tsx
@@ -1,6 +1,6 @@
-import * as React from "react";
-import { SliderItem } from "react-compound-slider";
-import "./SliderBox-tooltip.css";
+import * as React from 'react';
+import { SliderItem } from 'react-compound-slider';
+import './SliderBox-tooltip.css';
 
 const { Component, Fragment } = React;
 
@@ -8,24 +8,24 @@ const { Component, Fragment } = React;
 // TOOLTIP RAIL
 // *******************************************************
 const railStyle: React.CSSProperties = {
-    position: "absolute",
-    width: "100%",
+    position: 'absolute',
+    width: '100%',
     height: 40,
     borderRadius: 7,
-    cursor: "pointer",
+    cursor: 'pointer',
     opacity: 0.3,
     zIndex: 300,
-    border: "1px solid grey"
+    border: '1px solid grey',
 };
 
 const railCenterStyle: React.CSSProperties = {
-    position: "absolute",
-    width: "100%",
+    position: 'absolute',
+    width: '100%',
     height: 14,
     borderRadius: 7,
-    cursor: "pointer",
-    pointerEvents: "none",
-    backgroundColor: "rgb(155,155,155)"
+    cursor: 'pointer',
+    pointerEvents: 'none',
+    backgroundColor: 'rgb(155,155,155)',
 };
 
 interface TooltipRailProps {
@@ -37,21 +37,21 @@ interface TooltipRailProps {
 export class TooltipRail extends Component<TooltipRailProps> {
     state = {
         value: null,
-        percent: null
+        percent: null,
     };
 
     static defaultProps = {
-        disabled: false
+        disabled: false,
     };
 
     onMouseEnter = () => {
-        document.addEventListener("mousemove", this.onMouseMove);
-    }
+        document.addEventListener('mousemove', this.onMouseMove);
+    };
 
     onMouseLeave = () => {
         this.setState({ value: null, percent: null });
-        document.removeEventListener("mousemove", this.onMouseMove);
-    }
+        document.removeEventListener('mousemove', this.onMouseMove);
+    };
 
     onMouseMove = (e: Event) => {
         const { activeHandleID, getEventData } = this.props;
@@ -61,7 +61,7 @@ export class TooltipRail extends Component<TooltipRailProps> {
         } else {
             this.setState(getEventData(e));
         }
-    }
+    };
 
     render() {
         const { value, percent } = this.state;
@@ -73,11 +73,10 @@ export class TooltipRail extends Component<TooltipRailProps> {
                     <div
                         style={{
                             left: `${percent}%`,
-                            position: "absolute",
-                            marginLeft: "-11px",
-                            marginTop: "-35px"
-                        }}
-                    >
+                            position: 'absolute',
+                            marginLeft: '-11px',
+                            marginTop: '-35px',
+                        }}>
                         <div className="tooltip">
                             <span className="tooltiptext">Value: {value}</span>
                         </div>
@@ -87,7 +86,7 @@ export class TooltipRail extends Component<TooltipRailProps> {
                     style={railStyle}
                     {...getRailProps({
                         onMouseEnter: this.onMouseEnter,
-                        onMouseLeave: this.onMouseLeave
+                        onMouseLeave: this.onMouseLeave,
                     })}
                 />
                 <div style={railCenterStyle} />
@@ -110,20 +109,20 @@ interface HandleProps {
 
 export class Handle extends Component<HandleProps> {
     static defaultProps = {
-        disabled: false
+        disabled: false,
     };
 
     state = {
-        mouseOver: false
+        mouseOver: false,
     };
 
     onMouseEnter = () => {
         this.setState({ mouseOver: true });
-    }
+    };
 
     onMouseLeave = () => {
         this.setState({ mouseOver: false });
-    }
+    };
 
     render() {
         const {
@@ -131,7 +130,7 @@ export class Handle extends Component<HandleProps> {
             handle: { id, value, percent },
             isActive,
             disabled,
-            getHandleProps
+            getHandleProps,
         } = this.props;
         const { mouseOver } = this.state;
 
@@ -141,11 +140,10 @@ export class Handle extends Component<HandleProps> {
                     <div
                         style={{
                             left: `${percent}%`,
-                            position: "absolute",
-                            marginLeft: "-11px",
-                            marginTop: "-35px"
-                        }}
-                    >
+                            position: 'absolute',
+                            marginLeft: '-11px',
+                            marginTop: '-35px',
+                        }}>
                         <div className="tooltip">
                             <span className="tooltiptext">Value: {value}</span>
                         </div>
@@ -158,21 +156,21 @@ export class Handle extends Component<HandleProps> {
                     aria-valuenow={value}
                     style={{
                         left: `${percent}%`,
-                        position: "absolute",
-                        marginLeft: "-11px",
-                        marginTop: "-6px",
+                        position: 'absolute',
+                        marginLeft: '-11px',
+                        marginTop: '-6px',
                         zIndex: 400,
                         width: 24,
                         height: 24,
-                        cursor: "pointer",
+                        cursor: 'pointer',
                         border: 0,
-                        borderRadius: "50%",
-                        boxShadow: "1px 1px 1px 1px rgba(0, 0, 0, 0.4)",
-                        backgroundColor: disabled ? "#666" : "#3e1db3"
+                        borderRadius: '50%',
+                        boxShadow: '1px 1px 1px 1px rgba(0, 0, 0, 0.4)',
+                        backgroundColor: disabled ? '#666' : '#3e1db3',
                     }}
                     {...getHandleProps(id, {
                         onMouseEnter: this.onMouseEnter,
-                        onMouseLeave: this.onMouseLeave
+                        onMouseLeave: this.onMouseLeave,
                     })}
                 />
             </Fragment>
@@ -190,23 +188,18 @@ interface TrackProps {
     getTrackProps: () => object;
 }
 
-export function Track({
-    source,
-    target,
-    getTrackProps,
-    disabled = false
-}: TrackProps) {
+export function Track({ source, target, getTrackProps, disabled = false }: TrackProps) {
     return (
         <div
             style={{
-                position: "absolute",
+                position: 'absolute',
                 height: 14,
                 zIndex: 1,
-                backgroundColor: disabled ? "#999" : "#3e1db3",
+                backgroundColor: disabled ? '#999' : '#3e1db3',
                 borderRadius: 7,
-                cursor: "pointer",
+                cursor: 'pointer',
                 left: `${source.percent}%`,
-                width: `${target.percent - source.percent}%`
+                width: `${target.percent - source.percent}%`,
             }}
             {...getTrackProps()}
         />
@@ -229,25 +222,24 @@ export function Tick({ tick, count, format = defaultFormat }: TickProps) {
         <div>
             <div
                 style={{
-                    position: "absolute",
+                    position: 'absolute',
                     marginTop: 20,
                     width: 1,
                     height: 5,
-                    backgroundColor: "rgb(200,200,200)",
-                    left: `${tick.percent}%`
+                    backgroundColor: 'rgb(200,200,200)',
+                    left: `${tick.percent}%`,
                 }}
             />
             <div
                 style={{
-                    position: "absolute",
+                    position: 'absolute',
                     marginTop: 25,
                     fontSize: 10,
-                    textAlign: "center",
+                    textAlign: 'center',
                     marginLeft: `${-(100 / count) / 2}%`,
                     width: `${100 / count}%`,
-                    left: `${tick.percent}%`
-                }}
-            >
+                    left: `${tick.percent}%`,
+                }}>
                 {format(tick.value)}
             </div>
         </div>
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 5b3f37993..1121134cf 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -271,7 +271,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
         setupMoveUpEvents(
             e.target,
             e,
-            action((e, down, delta) => {
+            action((moveEv, down, delta) => {
                 if (this._controlsTransform) {
                     this._controlsTransform.X = Math.max(0, Math.min(delta[0] + this._controlsTransform.X, window.innerWidth));
                     this._controlsTransform.Y = Math.max(0, Math.min(delta[1] + this._controlsTransform.Y, window.innerHeight));
@@ -309,8 +309,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
             // convert to desired file format
             const dataUrl = canvas.toDataURL('image/png'); // can also use 'image/png'
             // if you want to preview the captured image,
-            const retitled = StrCast(this.Document.title).replace(/[ -\.:]/g, '');
-            const encodedFilename = encodeURIComponent(('snapshot' + retitled + '_' + (this.layoutDoc._layout_currentTimecode || 0).toString()).replace(/[\.\/\?\=]/g, '_'));
+            const retitled = StrCast(this.Document.title).replace(/[ -.:]/g, '');
+            const encodedFilename = encodeURIComponent(('snapshot' + retitled + '_' + (this.layoutDoc._layout_currentTimecode || 0).toString()).replace(/[./?=]/g, '_'));
             const filename = basename(encodedFilename);
             ClientUtils.convertDataUri(dataUrl, filename).then((returnedFilename: string) => returnedFilename && (cb ?? this.createSnapshotLink)(returnedFilename, downX, downY));
         }
@@ -410,7 +410,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
             canvas.height = 100;
             canvas.width = 100;
             canvas.getContext('2d')?.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, 100, 100);
-            const retitled = StrCast(this.Document.title).replace(/[ -\.:]/g, '');
+            const retitled = StrCast(this.Document.title).replace(/[ -.:]/g, '');
             const encodedFilename = encodeURIComponent('thumbnail' + retitled + '_' + video.currentTime.toString().replace(/\./, '_'));
             thumbnailPromises?.push(ClientUtils.convertDataUri(canvas.toDataURL(), basename(encodedFilename), true));
             const newTime = video.currentTime + video.duration / (VideoBox.numThumbnails - 1);
@@ -486,7 +486,13 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
                     },
                     icon: 'expand-arrows-alt',
                 });
-            subitems.push({ description: (this.layoutDoc.dontAutoFollowLinks ? '' : "Don't") + ' follow links when encountered', event: () => (this.layoutDoc.dontAutoFollowLinks = !this.layoutDoc.dontAutoFollowLinks), icon: 'expand-arrows-alt' });
+            subitems.push({
+                description: (this.layoutDoc.dontAutoFollowLinks ? '' : "Don't") + ' follow links when encountered',
+                event: () => {
+                    this.layoutDoc.dontAutoFollowLinks = !this.layoutDoc.dontAutoFollowLinks;
+                },
+                icon: 'expand-arrows-alt',
+            });
             subitems.push({
                 description: (this.layoutDoc.dontAutoPlayFollowedLinks ? '' : "Don't") + ' play when link is selected',
                 event: () => {
@@ -494,7 +500,13 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
                 },
                 icon: 'expand-arrows-alt',
             });
-            subitems.push({ description: (this.layoutDoc.autoPlayAnchors ? "Don't auto play" : 'Auto play') + ' anchors onClick', event: () => (this.layoutDoc.autoPlayAnchors = !this.layoutDoc.autoPlayAnchors), icon: 'expand-arrows-alt' });
+            subitems.push({
+                description: (this.layoutDoc.autoPlayAnchors ? "Don't auto play" : 'Auto play') + ' anchors onClick',
+                event: () => {
+                    this.layoutDoc.autoPlayAnchors = !this.layoutDoc.autoPlayAnchors;
+                },
+                icon: 'expand-arrows-alt',
+            });
             // subitems.push({ description: "Start Trim All", event: () => this.startTrim(TrimScope.All), icon: "expand-arrows-alt" });
             // subitems.push({ description: "Start Trim Clip", event: () => this.startTrim(TrimScope.Clip), icon: "expand-arrows-alt" });
             // subitems.push({ description: "Stop Trim", event: () => this.finishTrim(), icon: "expand-arrows-alt" });
@@ -593,8 +605,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
         setupMoveUpEvents(
             this,
             e,
-            e => {
-                this.Snapshot(e.clientX, e.clientY);
+            moveEv => {
+                this.Snapshot(moveEv.clientX, moveEv.clientY);
                 return true;
             },
             emptyFunction,
@@ -657,13 +669,13 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
 
     // for annotating, adds doc with time info
     @action.bound
-    addDocWithTimecode(doc: Doc | Doc[]): boolean {
-        const docs = doc instanceof Doc ? [doc] : doc;
+    addDocWithTimecode(docIn: Doc | Doc[]): boolean {
+        const docs = docIn instanceof Doc ? [docIn] : docIn;
         const curTime = NumCast(this.layoutDoc._layout_currentTimecode);
         docs.forEach(doc => {
             doc._timecodeToHide = (doc._timecodeToShow = curTime) + 1;
         });
-        return this.addDocument(doc);
+        return this.addDocument(docs);
     }
 
     // play back the audio from seekTimeInSeconds, fullPlay tells whether clip is being played to end vs link range
@@ -671,7 +683,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
     playFrom = (seekTimeInSeconds: number, endTime?: number, fullPlay: boolean = false) => {
         clearTimeout(this._playRegionTimer);
         this._playRegionTimer = undefined;
-        if (isNaN(this.player?.duration)) {
+        if (this.player?.duration === undefined || isNaN(this.player.duration)) {
             setTimeout(() => this.playFrom(seekTimeInSeconds, endTime), 500);
         } else if (this.player) {
             // trimBounds override requested playback bounds
@@ -723,7 +735,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
                 e,
                 returnFalse,
                 returnFalse,
-                action((e: PointerEvent, doubleTap?: boolean) => {
+                action((clickEv: PointerEvent, doubleTap?: boolean) => {
                     if (doubleTap) {
                         this.startTrim(TrimScope.All);
                     } else if (this.timeline) {
@@ -782,9 +794,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() impl
             setupMoveUpEvents(
                 this,
                 e,
-                action(e => {
+                action(moveEv => {
                     MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
-                    this._marqueeref.current?.onInitiateSelection([e.clientX, e.clientY]);
+                    this._marqueeref.current?.onInitiateSelection([moveEv.clientX, moveEv.clientY]);
                     return true;
                 }),
                 returnFalse,
diff --git a/src/client/views/nodes/audio/AudioWaveform.tsx b/src/client/views/nodes/audio/AudioWaveform.tsx
index 7fd799952..2d1d3d7db 100644
--- a/src/client/views/nodes/audio/AudioWaveform.tsx
+++ b/src/client/views/nodes/audio/AudioWaveform.tsx
@@ -7,8 +7,8 @@ import { List } from '../../../../fields/List';
 import { listSpec } from '../../../../fields/Schema';
 import { Cast } from '../../../../fields/Types';
 import { numberRange } from '../../../../Utils';
+import { Colors } from '../../global/globalEnums';
 import { ObservableReactComponent } from '../../ObservableReactComponent';
-import { Colors } from './../../global/globalEnums';
 import './AudioWaveform.scss';
 import { WaveCanvas } from './WaveCanvas';
 
@@ -62,7 +62,7 @@ export class AudioWaveform extends ObservableReactComponent<AudioWaveformProps>
         return NumListCast(this._props.layoutDoc[this.audioBucketField(this.clipStart, this.clipEnd, this.zoomFactor)]);
     }
 
-    audioBucketField = (start: number, end: number, zoomFactor: number) => this._props.fieldKey + '_audioBuckets/' + '/' + start.toFixed(2).replace('.', '_') + '/' + end.toFixed(2).replace('.', '_') + '/' + zoomFactor * 10;
+    audioBucketField = (start: number, end: number, zoomFactor: number) => this._props.fieldKey + '_audioBuckets//' + start.toFixed(2).replace('.', '_') + '/' + end.toFixed(2).replace('.', '_') + '/' + zoomFactor * 10;
 
     componentWillUnmount() {
         this._disposer?.();
@@ -72,7 +72,7 @@ export class AudioWaveform extends ObservableReactComponent<AudioWaveformProps>
         this._disposer = reaction(
             () => ({ clipStart: this.clipStart, clipEnd: this.clipEnd, fieldKey: this.audioBucketField(this.clipStart, this.clipEnd, this.zoomFactor), zoomFactor: this._props.zoomFactor }),
             ({ clipStart, clipEnd, fieldKey, zoomFactor }) => {
-                if (!this._props.layoutDoc[fieldKey] && this._props.layoutDoc.layout_fieldKey != 'layout_icon') {
+                if (!this._props.layoutDoc[fieldKey] && this._props.layoutDoc.layout_fieldKey !== 'layout_icon') {
                     // setting these values here serves as a "lock" to prevent multiple attempts to create the waveform at nerly the same time.
                     const waveform = Cast(this._props.layoutDoc[this.audioBucketField(0, this._props.rawDuration, 1)], listSpec('number'));
                     this._props.layoutDoc[fieldKey] = waveform && new List<number>(waveform.slice((clipStart / this._props.rawDuration) * waveform.length, (clipEnd / this._props.rawDuration) * waveform.length));
@@ -109,7 +109,7 @@ export class AudioWaveform extends ObservableReactComponent<AudioWaveformProps>
                     progressColor={Colors.MEDIUM_BLUE_ALT}
                     progress={this._props.progress ?? 1}
                     barWidth={200 / this.audioBuckets.length}
-                    //gradientColors={this._props.gradientColors}
+                    // gradientColors={this._props.gradientColors}
                     peaks={this.audioBuckets}
                     width={(this._props.PanelWidth ?? 0) * window.devicePixelRatio}
                     height={this.waveHeight * window.devicePixelRatio}
diff --git a/src/client/views/nodes/audio/WaveCanvas.tsx b/src/client/views/nodes/audio/WaveCanvas.tsx
index d3f5669a2..eacda2d42 100644
--- a/src/client/views/nodes/audio/WaveCanvas.tsx
+++ b/src/client/views/nodes/audio/WaveCanvas.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/require-default-props */
 import React from 'react';
 
 interface WaveCanvasProps {
@@ -14,7 +15,7 @@ interface WaveCanvasProps {
 
 export class WaveCanvas extends React.Component<WaveCanvasProps> {
     // If the first value of peaks is negative, addToIndices will be 1
-    posPeaks = (peaks: number[], addToIndices: number) => peaks.filter((_, index) => (index + addToIndices) % 2 == 0);
+    posPeaks = (peaks: number[], addToIndices: number) => peaks.filter((_, index) => (index + addToIndices) % 2 === 0);
 
     drawBars = (waveCanvasCtx: CanvasRenderingContext2D, width: number, halfH: number, peaks: number[]) => {
         // Bar wave draws the bottom only as a reflection of the top,
@@ -47,6 +48,7 @@ export class WaveCanvas extends React.Component<WaveCanvasProps> {
 
         // A half-pixel offset makes lines crisp
         const $ = 0.5 / this.props.pixelRatio;
+        // eslint-disable-next-line no-bitwise
         const length = ~~(allPeaks.length / 2); // ~~ is Math.floor for positive numbers.
 
         const scale = width / length;
@@ -55,14 +57,14 @@ export class WaveCanvas extends React.Component<WaveCanvasProps> {
         waveCanvasCtx.beginPath();
         waveCanvasCtx.moveTo($, halfH);
 
-        for (var i = 0; i < length; i++) {
-            var h = Math.round((allPeaks[2 * i] / absmax) * halfH);
+        for (let i = 0; i < length; i++) {
+            const h = Math.round((allPeaks[2 * i] / absmax) * halfH);
             waveCanvasCtx.lineTo(i * scale + $, halfH - h);
         }
 
         // Draw the bottom edge going backwards, to make a single closed hull to fill.
-        for (var i = length - 1; i >= 0; i--) {
-            var h = Math.round((allPeaks[2 * i + 1] / absmax) * halfH);
+        for (let i = length - 1; i >= 0; i--) {
+            const h = Math.round((allPeaks[2 * i + 1] / absmax) * halfH);
             waveCanvasCtx.lineTo(i * scale + $, halfH - h);
         }
 
diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx
index 8577510e3..5893c346f 100644
--- a/src/client/views/nodes/calendarBox/CalendarBox.tsx
+++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx
@@ -57,12 +57,13 @@ export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>() {
 
     docBackgroundColor(type: string): string {
         // TODO: Return a different color based on the event type
+        console.log(type);
         return 'blue';
     }
 
     get calendarEvents(): EventSourceInput | undefined {
         if (this.childDocs.length === 0) return undefined;
-        return this.childDocs.map((doc, idx) => {
+        return this.childDocs.map(doc => {
             const docTitle = StrCast(doc.title);
             const docDateRange = StrCast(doc.date_range);
             const [startDate, endDate] = dateRangeStrToDates(docDateRange);
@@ -85,7 +86,7 @@ export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>() {
         });
     }
 
-    handleEventClick = (arg: EventClickArg) => {
+    handleEventClick = (/* arg: EventClickArg */) => {
         // TODO: open popover with event description, option to open CalendarManager and change event date, delete event, etc.
     };
 
@@ -113,7 +114,7 @@ export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>() {
     render() {
         return (
             <div className="calendar-box-conatiner">
-                <div id="calendar-box-v1"></div>
+                <div id="calendar-box-v1" />
             </div>
         );
     }
diff --git a/src/client/views/nodes/formattedText/DashDocCommentView.tsx b/src/client/views/nodes/formattedText/DashDocCommentView.tsx
index a72ed1813..3ec49fa27 100644
--- a/src/client/views/nodes/formattedText/DashDocCommentView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocCommentView.tsx
@@ -1,60 +1,11 @@
 import { TextSelection } from 'prosemirror-state';
 import * as ReactDOM from 'react-dom/client';
-import { Doc } from '../../../../fields/Doc';
-import { DocServer } from '../../../DocServer';
 import * as React from 'react';
 import { IReactionDisposer, computed, reaction } from 'mobx';
+import { Doc } from '../../../../fields/Doc';
+import { DocServer } from '../../../DocServer';
 import { NumCast } from '../../../../fields/Types';
 
-// creates an inline comment in a note when '>>' is typed.
-// the comment sits on the right side of the note and vertically aligns with its anchor in the text.
-// 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;
-
-    constructor(node: any, view: any, getPos: any) {
-        this.node = node;
-        this.dom = document.createElement('div');
-        this.dom.style.width = node.attrs.width;
-        this.dom.style.height = node.attrs.height;
-        this.dom.style.fontWeight = 'bold';
-        this.dom.style.position = 'relative';
-        this.dom.style.display = 'inline-block';
-        this.dom.onkeypress = function (e: any) {
-            e.stopPropagation();
-        };
-        this.dom.onkeydown = function (e: any) {
-            e.stopPropagation();
-        };
-        this.dom.onkeyup = function (e: any) {
-            e.stopPropagation();
-        };
-        this.dom.onmousedown = function (e: any) {
-            e.stopPropagation();
-        };
-
-        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;
-    }
-
-    setHeight = (hgt: number) => {
-        !this.node.attrs.reflow && DocServer.GetRefField(this.node.attrs.docId).then(doc => doc instanceof Doc && (this.dom.style.height = hgt + ''));
-    };
-
-    destroy() {
-        this.root.unmount();
-    }
-    deselectNode() {
-        this.dom.classList.remove('ProseMirror-selectednode');
-    }
-    selectNode() {
-        this.dom.classList.add('ProseMirror-selectednode');
-    }
-}
-
 interface IDashDocCommentViewInternal {
     docId: string;
     view: any;
@@ -65,9 +16,6 @@ interface IDashDocCommentViewInternal {
 export class DashDocCommentViewInternal extends React.Component<IDashDocCommentViewInternal> {
     _reactionDisposer: IReactionDisposer | undefined;
 
-    @computed get _dashDoc() {
-        return DocServer.GetRefField(this.props.docId);
-    }
     constructor(props: any) {
         super(props);
         this.onPointerLeaveCollapsed = this.onPointerLeaveCollapsed.bind(this);
@@ -77,58 +25,62 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV
     }
     componentDidMount(): void {
         this._reactionDisposer?.();
-        this._dashDoc.then(
-            doc =>
-                doc instanceof Doc &&
-                (this._reactionDisposer = reaction(
+        this._dashDoc.then(doc => {
+            if (doc instanceof Doc) {
+                this._reactionDisposer = reaction(
                     () => NumCast((doc as Doc)._height),
                     hgt => this.props.setHeight(hgt),
-                    {
-                        fireImmediately: true,
-                    }
-                ))
-        );
+                    { fireImmediately: true }
+                );
+            }
+        });
     }
     componentWillUnmount(): void {
         this._reactionDisposer?.();
     }
 
-    onPointerLeaveCollapsed(e: any) {
+    @computed get _dashDoc() {
+        return DocServer.GetRefField(this.props.docId);
+    }
+
+    onPointerLeaveCollapsed = (e: any) => {
         this._dashDoc.then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowUnhighlight());
         e.preventDefault();
         e.stopPropagation();
-    }
+    };
 
-    onPointerEnterCollapsed(e: any) {
+    onPointerEnterCollapsed = (e: any) => {
         this._dashDoc.then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc, false));
         e.preventDefault();
         e.stopPropagation();
-    }
+    };
 
-    onPointerUpCollapsed(e: any) {
+    onPointerUpCollapsed = (e: any) => {
         const target = this.targetNode();
 
         if (target) {
             const expand = target.hidden;
-            const tr = this.props.view.state.tr.setNodeMarkup(target.pos, undefined, { ...target.node.attrs, hidden: target.node.attrs.hidden ? false : true });
+            const tr = this.props.view.state.tr.setNodeMarkup(target.pos, undefined, { ...target.node.attrs, hidden: !target.node.attrs.hidden });
             this.props.view.dispatch(tr.setSelection(TextSelection.create(tr.doc, this.props.getPos() + (expand ? 2 : 1)))); // update the attrs
             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))));
-                } catch (e) {}
+                } catch (err) {
+                    /* empty */
+                }
             }, 0);
         }
         e.stopPropagation();
-    }
+    };
 
-    onPointerDownCollapsed(e: any) {
+    onPointerDownCollapsed = (e: any) => {
         e.stopPropagation();
-    }
+    };
 
     targetNode = () => {
         // search forward in the prosemirror doc for the attached dashDocNode that is the target of the comment anchor
-        const state = this.props.view.state;
+        const { state } = this.props.view;
         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) {
@@ -141,7 +93,9 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV
         setTimeout(() => {
             try {
                 this.props.view.dispatch(state.tr.setSelection(TextSelection.create(state.tr.doc, this.props.getPos() + 2)));
-            } catch (e) {}
+            } catch (err) {
+                /* empty */
+            }
         }, 0);
         return undefined;
     };
@@ -154,7 +108,60 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV
                 onPointerLeave={this.onPointerLeaveCollapsed}
                 onPointerEnter={this.onPointerEnterCollapsed}
                 onPointerUp={this.onPointerUpCollapsed}
-                onPointerDown={this.onPointerDownCollapsed}></span>
+                onPointerDown={this.onPointerDownCollapsed}
+            />
         );
     }
 }
+
+// creates an inline comment in a note when '>>' is typed.
+// the comment sits on the right side of the note and vertically aligns with its anchor in the text.
+// 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;
+
+    constructor(node: any, view: any, getPos: any) {
+        this.node = node;
+        this.dom = document.createElement('div');
+        this.dom.style.width = node.attrs.width;
+        this.dom.style.height = node.attrs.height;
+        this.dom.style.fontWeight = 'bold';
+        this.dom.style.position = 'relative';
+        this.dom.style.display = 'inline-block';
+        this.dom.onkeypress = function (e: any) {
+            e.stopPropagation();
+        };
+        this.dom.onkeydown = function (e: any) {
+            e.stopPropagation();
+        };
+        this.dom.onkeyup = function (e: any) {
+            e.stopPropagation();
+        };
+        this.dom.onmousedown = function (e: any) {
+            e.stopPropagation();
+        };
+
+        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;
+    }
+
+    setHeight = (hgt: number) => {
+        !this.node.attrs.reflow &&
+            DocServer.GetRefField(this.node.attrs.docId).then(doc => {
+                doc instanceof Doc && (this.dom.style.height = hgt + '');
+            });
+    };
+
+    destroy() {
+        this.root.unmount();
+    }
+    deselectNode() {
+        this.dom.classList.remove('ProseMirror-selectednode');
+    }
+    selectNode() {
+        this.dom.classList.add('ProseMirror-selectednode');
+    }
+}
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index dee7d70bb..f311b3cdd 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -1,10 +1,10 @@
+/* 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';
 import * as React from 'react';
 import * as ReactDOM from 'react-dom/client';
-import { Utils } from '../../../../Utils';
-import { returnFalse } from '../../../../ClientUtils';
+import { ClientUtils, returnFalse } from '../../../../ClientUtils';
 import { Doc } from '../../../../fields/Doc';
 import { Height, Width } from '../../../../fields/DocSymbols';
 import { NumCast } from '../../../../fields/Types';
@@ -16,63 +16,7 @@ import { DocumentView } from '../DocumentView';
 import { FocusViewOptions } from '../FieldView';
 import { FormattedTextBox } from './FormattedTextBox';
 
-var horizPadding = 3; // horizontal padding to container to allow cursor to show up on either side.
-export class DashDocView {
-    dom: HTMLSpanElement; // container for label and value
-    root: any;
-
-    constructor(node: any, view: any, getPos: any, 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) {
-            e.stopPropagation();
-        };
-        this.dom.onkeydown = function (e: any) {
-            e.stopPropagation();
-        };
-        this.dom.onkeyup = function (e: any) {
-            e.stopPropagation();
-        };
-        this.dom.onmousedown = function (e: any) {
-            e.stopPropagation();
-        };
-
-        this.root = ReactDOM.createRoot(this.dom);
-        this.root.render(
-            <DashDocViewInternal
-                docId={node.attrs.docId}
-                embedding={node.attrs.embedding}
-                width={node.attrs.width}
-                height={node.attrs.height}
-                hidden={node.attrs.hidden}
-                fieldKey={node.attrs.fieldKey}
-                tbox={tbox}
-                view={view}
-                node={node}
-                getPos={getPos}
-            />
-        );
-    }
-    destroy() {
-        setTimeout(() => {
-            try {
-                this.root.unmount();
-            } catch {}
-        });
-    }
-    deselectNode() {
-        this.dom.style.backgroundColor = '';
-    }
-    selectNode() {
-        this.dom.style.backgroundColor = 'rgb(141, 182, 247)';
-    }
-}
-
+const horizPadding = 3; // horizontal padding to container to allow cursor to show up on either side.
 interface IDashDocViewInternal {
     docId: string;
     embedding: string;
@@ -85,6 +29,7 @@ interface IDashDocViewInternal {
     node: any;
     getPos: any;
 }
+
 @observer
 export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewInternal> {
     _spanRef = React.createRef<HTMLDivElement>();
@@ -158,7 +103,7 @@ export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewIn
 
     getDocTransform = () => {
         if (!this._spanRef.current) return Transform.Identity();
-        const { scale, translateX, translateY } = Utils.GetScreenTransform(this._spanRef.current);
+        const { scale, translateX, translateY } = ClientUtils.GetScreenTransform(this._spanRef.current);
         return new Transform(-translateX, -translateY, 1).scale(1 / scale);
     };
     outerFocus = (target: Doc, options: FocusViewOptions) => this._textBox.focus(target, options); // ideally, this would scroll to show the focus target
@@ -227,3 +172,61 @@ export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewIn
         );
     }
 }
+
+export class DashDocView {
+    dom: HTMLSpanElement; // container for label and value
+    root: any;
+
+    constructor(node: any, view: any, getPos: any, 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) {
+            e.stopPropagation();
+        };
+        this.dom.onkeydown = function (e: any) {
+            e.stopPropagation();
+        };
+        this.dom.onkeyup = function (e: any) {
+            e.stopPropagation();
+        };
+        this.dom.onmousedown = function (e: any) {
+            e.stopPropagation();
+        };
+
+        this.root = ReactDOM.createRoot(this.dom);
+        this.root.render(
+            <DashDocViewInternal
+                docId={node.attrs.docId}
+                embedding={node.attrs.embedding}
+                width={node.attrs.width}
+                height={node.attrs.height}
+                hidden={node.attrs.hidden}
+                fieldKey={node.attrs.fieldKey}
+                tbox={tbox}
+                view={view}
+                node={node}
+                getPos={getPos}
+            />
+        );
+    }
+    destroy() {
+        setTimeout(() => {
+            try {
+                this.root.unmount();
+            } catch {
+                /* empty */
+            }
+        });
+    }
+    deselectNode() {
+        this.dom.style.backgroundColor = '';
+    }
+    selectNode() {
+        this.dom.style.backgroundColor = 'rgb(141, 182, 247)';
+    }
+}
diff --git a/src/client/views/nodes/formattedText/EquationEditor.tsx b/src/client/views/nodes/formattedText/EquationEditor.tsx
index b4102e08e..d9b1a2cf8 100644
--- a/src/client/views/nodes/formattedText/EquationEditor.tsx
+++ b/src/client/views/nodes/formattedText/EquationEditor.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/require-default-props */
 import React, { Component, createRef } from 'react';
 
 // Import JQuery, required for the functioning of the equation editor
@@ -5,11 +6,9 @@ import $ from 'jquery';
 
 import './EquationEditor.scss';
 
-// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
 // @ts-ignore
 window.jQuery = $;
 
-// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
 // @ts-ignore
 require('mathquill/build/mathquill');
 
diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx
index b90653acc..5167c8f2a 100644
--- a/src/client/views/nodes/formattedText/EquationView.tsx
+++ b/src/client/views/nodes/formattedText/EquationView.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable jsx-a11y/no-static-element-interactions */
 import { IReactionDisposer } from 'mobx';
 import { observer } from 'mobx-react';
 import { TextSelection } from 'prosemirror-state';
@@ -10,44 +11,6 @@ import EquationEditor from './EquationEditor';
 import { FormattedTextBox } from './FormattedTextBox';
 import { DocData } from '../../../../fields/DocSymbols';
 
-export class EquationView {
-    dom: HTMLDivElement; // container for label and value
-    root: any;
-    tbox: FormattedTextBox;
-    view: any;
-    constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) {
-        this.tbox = tbox;
-        this.view = view;
-        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) {
-            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);
-    destroy() {
-        this.root.unmount();
-    }
-    setSelection() {
-        this._editor?.mathField.focus();
-    }
-    selectNode() {
-        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();
-            setTimeout(() => (this.tbox._applyingChange = ''));
-        });
-    }
-    deselectNode() {}
-}
-
 interface IEquationViewInternal {
     fieldKey: string;
     tbox: FormattedTextBox;
@@ -70,12 +33,12 @@ export class EquationViewInternal extends React.Component<IEquationViewInternal>
         this._textBoxDoc = props.tbox.Document;
     }
 
-    componentWillUnmount() {
-        this._reactionDisposer?.();
-    }
     componentDidMount() {
         this.props.setEditor(this._ref.current ?? undefined);
     }
+    componentWillUnmount() {
+        this._reactionDisposer?.();
+    }
 
     render() {
         return (
@@ -100,12 +63,56 @@ export class EquationViewInternal extends React.Component<IEquationViewInternal>
                 <EquationEditor
                     ref={this._ref}
                     value={StrCast(this._textBoxDoc[DocData][this._fieldKey])}
-                    onChange={(str: any) => (this._textBoxDoc[DocData][this._fieldKey] = str)}
+                    onChange={(str: any) => {
+                        this._textBoxDoc[DocData][this._fieldKey] = str;
+                    }}
                     autoCommands="pi theta sqrt sum prod alpha beta gamma rho"
                     autoOperatorNames="sin cos tan"
-                    spaceBehavesLikeTab={true}
+                    spaceBehavesLikeTab
                 />
             </div>
         );
     }
 }
+
+export class EquationView {
+    dom: HTMLDivElement; // container for label and value
+    root: any;
+    tbox: FormattedTextBox;
+    view: any;
+    constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) {
+        this.tbox = tbox;
+        this.view = view;
+        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) {
+            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;
+    };
+    destroy() {
+        this.root.unmount();
+    }
+    setSelection() {
+        this._editor?.mathField.focus();
+    }
+    selectNode() {
+        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();
+            setTimeout(() => {
+                this.tbox._applyingChange = '';
+            });
+        });
+    }
+    deselectNode() {}
+}
diff --git a/src/client/views/nodes/formattedText/FootnoteView.tsx b/src/client/views/nodes/formattedText/FootnoteView.tsx
index b327e5137..4641da2e9 100644
--- a/src/client/views/nodes/formattedText/FootnoteView.tsx
+++ b/src/client/views/nodes/formattedText/FootnoteView.tsx
@@ -2,9 +2,9 @@ import { EditorView } from 'prosemirror-view';
 import { EditorState } from 'prosemirror-state';
 import { keymap } from 'prosemirror-keymap';
 import { baseKeymap, toggleMark } from 'prosemirror-commands';
-import { schema } from './schema_rts';
 import { redo, undo } from 'prosemirror-history';
 import { StepMap } from 'prosemirror-transform';
+import { schema } from './schema_rts';
 
 export class FootnoteView {
     innerView: any;
@@ -100,8 +100,8 @@ export class FootnoteView {
         this.innerView.updateState(state);
 
         if (!tr.getMeta('fromOutside')) {
-            const outerTr = this.outerView.state.tr,
-                offsetMap = StepMap.offset(this.getPos() + 1);
+            const outerTr = this.outerView.state.tr;
+            const offsetMap = StepMap.offset(this.getPos() + 1);
             for (const transaction of transactions) {
                 for (const step of transaction.steps) {
                     outerTr.step(step.map(offsetMap));
@@ -115,7 +115,7 @@ export class FootnoteView {
         if (!node.sameMarkup(this.node)) return false;
         this.node = node;
         if (this.innerView) {
-            const state = this.innerView.state;
+            const { state } = this.innerView;
             const start = node.content.findDiffStart(state.doc.content);
             if (start !== null) {
                 let { a: endA, b: endB } = node.content.findDiffEnd(state.doc.content);
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 52d93ec38..01c46edeb 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -19,20 +19,22 @@ export function findLinkMark(marks: readonly Mark[]): Mark | undefined {
     return marks.find(m => m.type === schema.marks.autoLinkAnchor || m.type === schema.marks.linkAnchor);
 }
 export function findStartOfMark(rpos: ResolvedPos, view: EditorView, finder: (marks: readonly Mark[]) => Mark | undefined) {
-    let before = 0,
-        nbef = rpos.nodeBefore;
+    let before = 0;
+    let nbef = rpos.nodeBefore;
     while (nbef && finder(nbef.marks)) {
         before += nbef.nodeSize;
+        // eslint-disable-next-line no-param-reassign
         rpos = view.state.doc.resolve(rpos.pos - nbef.nodeSize);
         rpos && (nbef = rpos.nodeBefore);
     }
     return before;
 }
 export function findEndOfMark(rpos: ResolvedPos, view: EditorView, finder: (marks: readonly Mark[]) => Mark | undefined) {
-    let after = 0,
-        naft = rpos.nodeAfter;
+    let after = 0;
+    let naft = rpos.nodeAfter;
     while (naft && finder(naft.marks)) {
         after += naft.nodeSize;
+        // eslint-disable-next-line no-param-reassign
         rpos = view.state.doc.resolve(rpos.pos + naft.nodeSize);
         rpos && (naft = rpos.nodeAfter);
     }
@@ -80,10 +82,10 @@ export class FormattedTextBoxComment {
     }
 
     static showCommentbox(view: EditorView, nbef: number) {
-        const state = view.state;
+        const { state } = view;
         // These are in screen coordinates
-        const start = view.coordsAtPos(state.selection.from - nbef),
-            end = view.coordsAtPos(state.selection.from - nbef);
+        const start = view.coordsAtPos(state.selection.from - nbef);
+        const end = view.coordsAtPos(state.selection.from - nbef);
         // The box in which the tooltip is positioned, to use as base
         const box = (document.getElementsByClassName('mainView-container') as any)[0].getBoundingClientRect();
         // Find a center-ish x position from the selection endpoints (when crossing lines, end may be more to the left)
@@ -110,14 +112,16 @@ export class FormattedTextBoxComment {
     }
 
     static setupPreview(view: EditorView, textBox: FormattedTextBox, hrefs?: string[], linkDoc?: string, noPreview?: boolean) {
-        const state = view.state;
+        const { state } = view;
         // this section checks to see if the insertion point is over text entered by a different user.  If so, it sets ths comment text to indicate the user and the modification date
         if (state.selection.$from) {
             const nbef = findStartOfMark(state.selection.$from, view, findOtherUserMark);
             const naft = findEndOfMark(state.selection.$from, view, findOtherUserMark);
             const noselection = state.selection.$from === state.selection.$to;
             let child: any = null;
-            state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any, pos: number, parent: any) => !child && node.marks.length && (child = node));
+            state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any /* , pos: number, parent: any */) => {
+                !child && node.marks.length && (child = node);
+            });
             const mark = child && findOtherUserMark(child.marks);
             if (mark && child && (nbef || naft) && (!mark.attrs.opened || noselection)) {
                 FormattedTextBoxComment.saveMarkRegion(textBox, state.selection.$from.pos - nbef, state.selection.$from.pos + naft, mark);
@@ -132,7 +136,7 @@ export class FormattedTextBoxComment {
         if (state.selection.$from && hrefs?.length) {
             const nbef = findStartOfMark(state.selection.$from, view, findLinkMark);
             const naft = findEndOfMark(state.selection.$from, view, findLinkMark) || nbef;
-            //nbef &&
+            // nbef &&
             naft &&
                 LinkInfo.SetLinkInfo({
                     DocumentView: textBox.DocumentView,
diff --git a/src/client/views/nodes/formattedText/OrderedListView.tsx b/src/client/views/nodes/formattedText/OrderedListView.tsx
index c3595e59b..dbc60f7bf 100644
--- a/src/client/views/nodes/formattedText/OrderedListView.tsx
+++ b/src/client/views/nodes/formattedText/OrderedListView.tsx
@@ -1,8 +1,7 @@
 export class OrderedListView {
-
-    update(node: any) {
-        // if attr's of an ordered_list (e.g., bulletStyle) change, 
+    update() {
+        // if attr's of an ordered_list (e.g., bulletStyle) change,
         // return false forces the dom node to be recreated which is necessary for the bullet labels to update
-        return false; 
+        return false;
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts b/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts
index 30da91710..6c88a0d29 100644
--- a/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts
+++ b/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts
@@ -1,18 +1,19 @@
+/* eslint-disable import/extensions */
+import { Node, DOMOutputSpec } from 'prosemirror-model';
 import clamp from '../../../util/clamp';
 import convertToCSSPTValue from '../../../util/convertToCSSPTValue';
 import toCSSLineSpacing from '../../../util/toCSSLineSpacing';
-import { Node, DOMOutputSpec } from 'prosemirror-model';
 
-//import type { NodeSpec } from './Types';
+// import type { NodeSpec } from './Types';
 type NodeSpec = {
-    attrs?: { [key: string]: any },
-    content?: string,
-    draggable?: boolean,
-    group?: string,
-    inline?: boolean,
-    name?: string,
-    parseDOM?: Array<any>,
-    toDOM?: (node: any) => DOMOutputSpec,
+    attrs?: { [key: string]: any };
+    content?: string;
+    draggable?: boolean;
+    group?: string;
+    inline?: boolean;
+    name?: string;
+    parseDOM?: Array<any>;
+    toDOM?: (node: any) => DOMOutputSpec;
 };
 
 // This assumes that every 36pt maps to one indent level.
@@ -25,41 +26,18 @@ export const EMPTY_CSS_VALUE = new Set(['', '0%', '0pt', '0px']);
 
 const ALIGN_PATTERN = /(left|right|center|justify)/;
 
-// https://github.com/ProseMirror/prosemirror-schema-basic/blob/master/src/schema-basic.js
-// :: NodeSpec A plain paragraph textblock. Represented in the DOM
-// as a `<p>` element.
-export const ParagraphNodeSpec: NodeSpec = {
-    attrs: {
-        align: { default: null },
-        color: { default: null },
-        id: { default: null },
-        indent: { default: null },
-        inset: { default: null },
-        lineSpacing: { default: null },
-        // TODO: Add UI to let user edit / clear padding.
-        paddingBottom: { default: null },
-        // TODO: Add UI to let user edit / clear padding.
-        paddingTop: { default: null },
-    },
-    content: 'inline*',
-    group: 'block',
-    parseDOM: [{ tag: 'p', getAttrs }],
-    toDOM,
-};
+function convertMarginLeftToIndentValue(marginLeft: string): number {
+    const ptValue = convertToCSSPTValue(marginLeft);
+    return clamp(MIN_INDENT_LEVEL, Math.floor(ptValue / INDENT_MARGIN_PT_SIZE), MAX_INDENT_LEVEL);
+}
 
 function getAttrs(dom: HTMLElement): Object {
-    const {
-        lineHeight,
-        textAlign,
-        marginLeft,
-        paddingTop,
-        paddingBottom,
-    } = dom.style;
+    const { lineHeight, textAlign, marginLeft, paddingTop, paddingBottom } = dom.style;
 
     let align = dom.getAttribute('align') || textAlign || '';
-    align = ALIGN_PATTERN.test(align) ? align : "";
+    align = ALIGN_PATTERN.test(align) ? align : '';
 
-    let indent = parseInt(dom.getAttribute(ATTRIBUTE_INDENT) || "", 10);
+    let indent = parseInt(dom.getAttribute(ATTRIBUTE_INDENT) || '', 10);
 
     if (!indent && marginLeft) {
         indent = convertMarginLeftToIndentValue(marginLeft);
@@ -74,15 +52,7 @@ function getAttrs(dom: HTMLElement): Object {
 }
 
 function toDOM(node: Node): DOMOutputSpec {
-    const {
-        align,
-        indent,
-        inset,
-        lineSpacing,
-        paddingTop,
-        paddingBottom,
-        id,
-    } = node.attrs;
+    const { align, indent, inset, lineSpacing, paddingTop, paddingBottom, id } = node.attrs;
     const attrs: { [key: string]: any } | null = {};
 
     let style = '';
@@ -128,16 +98,29 @@ function toDOM(node: Node): DOMOutputSpec {
     return ['p', attrs, 0];
 }
 
+// https://github.com/ProseMirror/prosemirror-schema-basic/blob/master/src/schema-basic.js
+// :: NodeSpec A plain paragraph textblock. Represented in the DOM
+// as a `<p>` element.
+export const ParagraphNodeSpec: NodeSpec = {
+    attrs: {
+        align: { default: null },
+        color: { default: null },
+        id: { default: null },
+        indent: { default: null },
+        inset: { default: null },
+        lineSpacing: { default: null },
+        // TODO: Add UI to let user edit / clear padding.
+        paddingBottom: { default: null },
+        // TODO: Add UI to let user edit / clear padding.
+        paddingTop: { default: null },
+    },
+    content: 'inline*',
+    group: 'block',
+    parseDOM: [{ tag: 'p', getAttrs }],
+    toDOM,
+};
+
 export const toParagraphDOM = toDOM;
 export const getParagraphNodeAttrs = getAttrs;
 
-export function convertMarginLeftToIndentValue(marginLeft: string): number {
-    const ptValue = convertToCSSPTValue(marginLeft);
-    return clamp(
-        MIN_INDENT_LEVEL,
-        Math.floor(ptValue / INDENT_MARGIN_PT_SIZE),
-        MAX_INDENT_LEVEL
-    );
-}
-
-export default ParagraphNodeSpec;
\ No newline at end of file
+export default ParagraphNodeSpec;
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts
index 88adab66e..c107a6724 100644
--- a/src/client/views/nodes/formattedText/RichTextRules.ts
+++ b/src/client/views/nodes/formattedText/RichTextRules.ts
@@ -14,6 +14,7 @@ import { CollectionView } from '../../collections/CollectionView';
 import { ContextMenu } from '../../ContextMenu';
 import { KeyValueBox } from '../KeyValueBox';
 import { FormattedTextBox } from './FormattedTextBox';
+// eslint-disable-next-line import/extensions
 import { wrappingInputRule } from './prosemirrorPatches';
 import { RichTextMenu } from './RichTextMenu';
 import { schema } from './schema_rts';
@@ -253,7 +254,7 @@ export class RichTextRules {
                 }
                 if (marks) {
                     const tr = state.tr.deleteRange(start, end);
-                    return marks ? Array.from(marks).reduce((tr, m) => tr.addStoredMark(m), tr) : tr;
+                    return marks ? Array.from(marks).reduce((tr2, m) => tr2.addStoredMark(m), tr) : tr;
                 }
 
                 const isValidColor = (strColor: string) => {
@@ -283,7 +284,7 @@ export class RichTextRules {
                 return marks
                     ? Array.from(marks)
                           .filter(m => m.type !== state.schema.marks.user_mark)
-                          .reduce((tr, m) => tr.removeStoredMark(m), tr)
+                          .reduce((tr2, m) => tr2.removeStoredMark(m), tr)
                     : tr;
             }),
 
@@ -309,11 +310,11 @@ export class RichTextRules {
                             teditor.dispatch(tstate.tr.setSelection(new TextSelection(tstate.doc.resolve(selection))));
                         }
                     };
-                    const getTitledDoc = (docTitle: string) => {
-                        if (!DocServer.FindDocByTitle(docTitle)) {
-                            Docs.Create.TextDocument('', { title: docTitle, _width: 400, _layout_fitWidth: true, _layout_autoHeight: true });
+                    const getTitledDoc = (title: string) => {
+                        if (!DocServer.FindDocByTitle(title)) {
+                            Docs.Create.TextDocument('', { title: title, _width: 400, _layout_fitWidth: true, _layout_autoHeight: true });
                         }
-                        const titledDoc = DocServer.FindDocByTitle(docTitle);
+                        const titledDoc = DocServer.FindDocByTitle(title);
                         return titledDoc ? Doc.BestEmbedding(titledDoc) : titledDoc;
                     };
                     const target = getTitledDoc(docTitle);
@@ -336,7 +337,7 @@ export class RichTextRules {
                     const assign = match[4] === ':' ? (match[4] = '') : match[4];
                     const value = match[5];
                     const dataDoc = value === undefined ? !fieldKey.startsWith('_') : !assign?.startsWith('=');
-                    const getTitledDoc = (docTitle: string) => DocServer.FindDocByTitle(docTitle);
+                    const getTitledDoc = (title: string) => DocServer.FindDocByTitle(title);
                     // if the value has commas assume its an array (unless it's part of a chat gpt call indicated by '((' )
                     if (value?.includes(',') && !value.startsWith('((')) {
                         const values = value.split(',');
diff --git a/src/client/views/nodes/formattedText/SummaryView.tsx b/src/client/views/nodes/formattedText/SummaryView.tsx
index 7ec296ed2..2c366b49b 100644
--- a/src/client/views/nodes/formattedText/SummaryView.tsx
+++ b/src/client/views/nodes/formattedText/SummaryView.tsx
@@ -3,6 +3,15 @@ import { Fragment, Node, Slice } from 'prosemirror-model';
 import * as ReactDOM from 'react-dom/client';
 import * as React from 'react';
 
+interface ISummaryView {}
+// currently nothing needs to be rendered for the internal view of a summary.
+// eslint-disable-next-line react/prefer-stateless-function
+export class SummaryViewInternal extends React.Component<ISummaryView> {
+    render() {
+        return null;
+    }
+}
+
 // an elidable textblock that collapses when its '<-' is clicked and expands when its '...' anchor is clicked.
 // this node actively edits prosemirror (as opposed to just changing how things are rendered) and thus doesn't
 // really need a react view.  However, it would be cleaner to figure out how to do this just as a react rendering
@@ -32,8 +41,8 @@ export class SummaryView {
         };
 
         const js = node.toJSON;
-        node.toJSON = function () {
-            return js.apply(this, arguments);
+        node.toJSON = function (...args: any[]) {
+            return js.apply(this, args);
         };
 
         this.root = ReactDOM.createRoot(this.dom);
@@ -54,7 +63,8 @@ export class SummaryView {
         const visited = new Set();
         for (let i: number = start + 1; i < view.state.doc.nodeSize - 1; i++) {
             let skip = false;
-            view.state.doc.nodesBetween(start, i, (node: Node, pos: number, parent: Node, index: number) => {
+            // eslint-disable-next-line no-loop-func
+            view.state.doc.nodesBetween(start, i, (node: Node /* , pos: number, parent: Node, index: number */) => {
                 if (node.isLeaf && !visited.has(node) && !skip) {
                     if (node.marks.find((m: any) => m.type === mtype || m.type === mtypeInc)) {
                         visited.add(node);
@@ -87,11 +97,3 @@ export class SummaryView {
         this.dom.className = this.className(visible);
     };
 }
-
-interface ISummaryView {}
-// currently nothing needs to be rendered for the internal view of a summary.
-export class SummaryViewInternal extends React.Component<ISummaryView> {
-    render() {
-        return <> </>;
-    }
-}
diff --git a/src/client/views/nodes/generativeFill/GenerativeFill.tsx b/src/client/views/nodes/generativeFill/GenerativeFill.tsx
index 95eb86720..b195654ce 100644
--- a/src/client/views/nodes/generativeFill/GenerativeFill.tsx
+++ b/src/client/views/nodes/generativeFill/GenerativeFill.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable jsx-a11y/label-has-associated-control */
 /* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
 /* eslint-disable jsx-a11y/img-redundant-alt */
 /* eslint-disable jsx-a11y/click-events-have-key-events */
@@ -56,7 +57,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
     // format: array of [image source, corresponding image Doc]
     const [edits, setEdits] = useState<(string | Doc)[][]>([]);
     const [edited, setEdited] = useState(false);
-    const [brushStyle, setBrushStyle] = useState<BrushStyle>(BrushStyle.ADD);
+    const [brushStyle] = useState<BrushStyle>(BrushStyle.ADD);
     const [input, setInput] = useState('');
     const [loading, setLoading] = useState(false);
     const [canvasDims, setCanvasDims] = useState<ImageDimensions>({
@@ -102,8 +103,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
         if (!ctx || !currImg.current || !canvasRef.current) return;
 
         const target = redoStack.current[redoStack.current.length - 1];
-        if (!target) {
-        } else {
+        if (target) {
             undoStack.current = [...undoStack.current, canvasRef.current?.toDataURL()];
             const img = new Image();
             img.src = target;
@@ -139,7 +139,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
     };
 
     // stop brushing, push to undo stack
-    const handlePointerUp = (e: React.PointerEvent) => {
+    const handlePointerUp = () => {
         const ctx = ImageUtility.getCanvasContext(canvasBackgroundRef);
         if (!ctx) return;
         if (!isBrushing) return;
@@ -148,11 +148,11 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
 
     // handles brushing on pointer movement
     useEffect(() => {
-        if (!isBrushing) return;
+        if (!isBrushing) return undefined;
         const canvas = canvasRef.current;
-        if (!canvas) return;
+        if (!canvas) return undefined;
         const ctx = ImageUtility.getCanvasContext(canvasRef);
-        if (!ctx) return;
+        if (!ctx) return undefined;
 
         const handlePointerMove = (e: PointerEvent) => {
             const currPoint = PointerHandler.getPointRelativeToElement(canvas, e, canvasScale);
@@ -300,6 +300,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
                     CollectionDockingView.AddSplit(newCollectionRef.current, OpenWhereMod.right);
 
                     // add the doc to the main freeform
+                    // eslint-disable-next-line no-use-before-define
                     await createNewImgDoc(originalImg.current, true);
                 }
             } else {
@@ -313,12 +314,14 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
                 const imgUrls = await Promise.all(urls.map(url => ImageUtility.convertImgToCanvasUrl(url, canvasDims.width, canvasDims.height)));
                 const imgRes = await Promise.all(
                     imgUrls.map(async url => {
+                        // eslint-disable-next-line no-use-before-define
                         const saveRes = await onSave(url);
                         return [url, saveRes as Doc];
                     })
                 );
                 setEdits(imgRes);
                 const image = new Image();
+                // eslint-disable-next-line prefer-destructuring
                 image.src = imgUrls[0];
                 ImageUtility.drawImgToCanvas(image, canvasRef, canvasDims.width, canvasDims.height);
                 currImg.current = image;
@@ -351,7 +354,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
 
     // creates a new image document and returns its reference
     const createNewImgDoc = async (img: HTMLImageElement, firstDoc: boolean): Promise<Doc | undefined> => {
-        if (!imageRootDoc) return;
+        if (!imageRootDoc) return undefined;
         const { src } = img;
         const [result] = await Networking.PostToServer('/uploadRemoteImage', { sources: [src] });
         const source = ClientUtils.prepend(result.accessPaths.agnostic.client);
@@ -375,7 +378,7 @@ const GenerativeFill = ({ imageEditorOpen, imageEditorSource, imageRootDoc, addD
             parentDoc.current = newImg;
             return newImg;
         }
-        if (!parentDoc.current) return;
+        if (!parentDoc.current) return undefined;
         const x = NumCast(parentDoc.current.x) + freeformRenderSize + offsetX;
         const initialY = 0;
 
diff --git a/src/client/views/nodes/generativeFill/GenerativeFillButtons.tsx b/src/client/views/nodes/generativeFill/GenerativeFillButtons.tsx
index 185ba2280..d1f68ee0e 100644
--- a/src/client/views/nodes/generativeFill/GenerativeFillButtons.tsx
+++ b/src/client/views/nodes/generativeFill/GenerativeFillButtons.tsx
@@ -1,9 +1,9 @@
 import './GenerativeFillButtons.scss';
 import * as React from 'react';
 import ReactLoading from 'react-loading';
-import { activeColor } from './generativeFillUtils/generativeFillConstants';
 import { Button, IconButton, Type } from 'browndash-components';
 import { AiOutlineInfo } from 'react-icons/ai';
+import { activeColor } from './generativeFillUtils/generativeFillConstants';
 
 interface ButtonContainerProps {
     getEdit: () => Promise<void>;
@@ -11,7 +11,7 @@ interface ButtonContainerProps {
     onReset: () => void;
 }
 
-const Buttons = ({ loading, getEdit, onReset }: ButtonContainerProps) => {
+function Buttons({ loading, getEdit, onReset }: ButtonContainerProps) {
     return (
         <div className="generativeFillBtnContainer">
             <Button text="RESET" type={Type.PRIM} color={activeColor} onClick={onReset} />
@@ -20,7 +20,7 @@ const Buttons = ({ loading, getEdit, onReset }: ButtonContainerProps) => {
                     text="GET EDITS"
                     type={Type.TERT}
                     color={activeColor}
-                    icon={<ReactLoading type="spin" color={'#ffffff'} width={20} height={20} />}
+                    icon={<ReactLoading type="spin" color="#ffffff" width={20} height={20} />}
                     iconPlacement="right"
                     onClick={() => {
                         if (!loading) getEdit();
@@ -36,9 +36,9 @@ const Buttons = ({ loading, getEdit, onReset }: ButtonContainerProps) => {
                     }}
                 />
             )}
-            <IconButton type={Type.SEC} color={activeColor} tooltip="Open Documentation" icon={<AiOutlineInfo size={'16px'} />} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/features/generativeai/#editing', '_blank')} />
+            <IconButton type={Type.SEC} color={activeColor} tooltip="Open Documentation" icon={<AiOutlineInfo size="16px" />} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/features/generativeai/#editing', '_blank')} />
         </div>
     );
-};
+}
 
 export default Buttons;
diff --git a/src/client/views/nodes/generativeFill/generativeFillUtils/GenerativeFillMathHelpers.ts b/src/client/views/nodes/generativeFill/generativeFillUtils/GenerativeFillMathHelpers.ts
index 97e03ff20..6da8c3da0 100644
--- a/src/client/views/nodes/generativeFill/generativeFillUtils/GenerativeFillMathHelpers.ts
+++ b/src/client/views/nodes/generativeFill/generativeFillUtils/GenerativeFillMathHelpers.ts
@@ -1,10 +1,6 @@
 import { Point } from './generativeFillInterfaces';
 
 export class GenerativeFillMathHelpers {
-    static distanceBetween = (p1: Point, p2: Point) => {
-        return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
-    };
-    static angleBetween = (p1: Point, p2: Point) => {
-        return Math.atan2(p2.x - p1.x, p2.y - p1.y);
-    };
+    static distanceBetween = (p1: Point, p2: Point) => Math.sqrt((p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2);
+    static angleBetween = (p1: Point, p2: Point) => Math.atan2(p2.x - p1.x, p2.y - p1.y);
 }
diff --git a/src/client/views/nodes/generativeFill/generativeFillUtils/ImageHandler.ts b/src/client/views/nodes/generativeFill/generativeFillUtils/ImageHandler.ts
index 47a14135f..24dba1778 100644
--- a/src/client/views/nodes/generativeFill/generativeFillUtils/ImageHandler.ts
+++ b/src/client/views/nodes/generativeFill/generativeFillUtils/ImageHandler.ts
@@ -17,15 +17,14 @@ export class ImageUtility {
      * @param canvas Canvas to convert
      * @returns Blob of canvas
      */
-    static canvasToBlob = (canvas: HTMLCanvasElement): Promise<Blob> => {
-        return new Promise(resolve => {
+    static canvasToBlob = (canvas: HTMLCanvasElement): Promise<Blob> =>
+        new Promise(resolve => {
             canvas.toBlob(blob => {
                 if (blob) {
                     resolve(blob);
                 }
             }, 'image/png');
         });
-    };
 
     // given a square api image, get the cropped img
     static getCroppedImg = (img: HTMLImageElement, width: number, height: number): HTMLCanvasElement | undefined => {
@@ -48,11 +47,12 @@ export class ImageUtility {
             }
             return canvas;
         }
+        return undefined;
     };
 
     // converts an image to a canvas data url
-    static convertImgToCanvasUrl = async (imageSrc: string, width: number, height: number): Promise<string> => {
-        return new Promise<string>((resolve, reject) => {
+    static convertImgToCanvasUrl = async (imageSrc: string, width: number, height: number): Promise<string> =>
+        new Promise<string>((resolve, reject) => {
             const img = new Image();
             img.onload = () => {
                 const canvas = this.getCroppedImg(img, width, height);
@@ -66,7 +66,6 @@ export class ImageUtility {
             };
             img.src = imageSrc;
         });
-    };
 
     // calls the openai api to get image edits
     static getEdit = async (imgBlob: Blob, maskBlob: Blob, prompt: string, n?: number): Promise<APISuccess | APIError> => {
@@ -91,7 +90,7 @@ export class ImageUtility {
             console.log(data.data);
             return {
                 status: 'success',
-                urls: (data.data as { b64_json: string }[]).map(data => `data:image/png;base64,${data.b64_json}`),
+                urls: (data.data as { b64_json: string }[]).map(urlData => `data:image/png;base64,${urlData.b64_json}`),
             };
         } catch (err) {
             console.log(err);
@@ -100,12 +99,10 @@ export class ImageUtility {
     };
 
     // mock api call
-    static mockGetEdit = async (mockSrc: string): Promise<APISuccess | APIError> => {
-        return {
-            status: 'success',
-            urls: [mockSrc, mockSrc, mockSrc],
-        };
-    };
+    static mockGetEdit = async (mockSrc: string): Promise<APISuccess | APIError> => ({
+        status: 'success',
+        urls: [mockSrc, mockSrc, mockSrc],
+    });
 
     // Gets the canvas rendering context of a canvas
     static getCanvasContext = (canvasRef: RefObject<HTMLCanvasElement>): CanvasRenderingContext2D | null => {
@@ -150,12 +147,12 @@ export class ImageUtility {
 
     // Draws the image to the current canvas
     static drawImgToCanvas = (img: HTMLImageElement, canvasRef: React.RefObject<HTMLCanvasElement>, width: number, height: number) => {
-        const drawImg = (img: HTMLImageElement) => {
+        const drawImg = (htmlImg: HTMLImageElement) => {
             const ctx = this.getCanvasContext(canvasRef);
             if (!ctx) return;
             ctx.globalCompositeOperation = 'source-over';
             ctx.clearRect(0, 0, width, height);
-            ctx.drawImage(img, 0, 0, width, height);
+            ctx.drawImage(htmlImg, 0, 0, width, height);
         };
 
         if (img.complete) {
@@ -173,7 +170,7 @@ export class ImageUtility {
         canvas.width = canvasSize;
         canvas.height = canvasSize;
         const ctx = canvas.getContext('2d');
-        if (!ctx) return;
+        if (!ctx) return undefined;
         ctx?.clearRect(0, 0, canvasSize, canvasSize);
         ctx.drawImage(paddedCanvas, 0, 0);
 
@@ -195,7 +192,7 @@ export class ImageUtility {
     // Fills in the blank areas of the image with an image reflection (to fill in a square-shaped canvas)
     static drawHorizontalReflection = (ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, xOffset: number) => {
         const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
-        const data = imageData.data;
+        const { data } = imageData;
         for (let i = 0; i < canvas.height; i++) {
             for (let j = 0; j < xOffset; j++) {
                 const targetIdx = 4 * (i * canvas.width + j);
@@ -224,7 +221,7 @@ export class ImageUtility {
     // Fills in the blank areas of the image with an image reflection (to fill in a square-shaped canvas)
     static drawVerticalReflection = (ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement, yOffset: number) => {
         const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
-        const data = imageData.data;
+        const { data } = imageData;
         for (let j = 0; j < canvas.width; j++) {
             for (let i = 0; i < yOffset; i++) {
                 const targetIdx = 4 * (i * canvas.width + j);
@@ -256,7 +253,7 @@ export class ImageUtility {
         canvas.width = canvasSize;
         canvas.height = canvasSize;
         const ctx = canvas.getContext('2d');
-        if (!ctx) return;
+        if (!ctx) return undefined;
         // fix scaling
         const scale = Math.min(canvasSize / img.width, canvasSize / img.height);
         const width = Math.floor(img.width * scale);
@@ -310,5 +307,6 @@ export class ImageUtility {
         } catch (err) {
             console.error(err);
         }
+        return undefined;
     };
 }
diff --git a/src/client/views/nodes/generativeFill/generativeFillUtils/PointerHandler.ts b/src/client/views/nodes/generativeFill/generativeFillUtils/PointerHandler.ts
index 9e620ad11..260923a64 100644
--- a/src/client/views/nodes/generativeFill/generativeFillUtils/PointerHandler.ts
+++ b/src/client/views/nodes/generativeFill/generativeFillUtils/PointerHandler.ts
@@ -1,15 +1,11 @@
-import { Point } from "./generativeFillInterfaces";
+import { Point } from './generativeFillInterfaces';
 
 export class PointerHandler {
-  static getPointRelativeToElement = (
-    element: HTMLElement,
-    e: React.PointerEvent | PointerEvent,
-    scale: number
-  ): Point => {
-    const boundingBox = element.getBoundingClientRect();
-    return {
-      x: (e.clientX - boundingBox.x) / scale,
-      y: (e.clientY - boundingBox.y) / scale,
+    static getPointRelativeToElement = (element: HTMLElement, e: React.PointerEvent | PointerEvent, scale: number): Point => {
+        const boundingBox = element.getBoundingClientRect();
+        return {
+            x: (e.clientX - boundingBox.x) / scale,
+            y: (e.clientY - boundingBox.y) / scale,
+        };
     };
-  };
 }
diff --git a/src/client/views/nodes/importBox/ImportElementBox.tsx b/src/client/views/nodes/importBox/ImportElementBox.tsx
index dec9a5019..317719032 100644
--- a/src/client/views/nodes/importBox/ImportElementBox.tsx
+++ b/src/client/views/nodes/importBox/ImportElementBox.tsx
@@ -22,13 +22,14 @@ export class ImportElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
         return (
             <div style={{ backgroundColor: 'pink' }}>
                 <DocumentView
+                    // eslint-disable-next-line react/jsx-props-no-spreading
                     {...this._props} //
                     LayoutTemplateString={undefined}
                     Document={this.Document}
                     isContentActive={returnFalse}
                     addDocument={returnFalse}
                     ScreenToLocalTransform={this.screenToLocalXf}
-                    hideResizeHandles={true}
+                    hideResizeHandles
                 />
             </div>
         );
diff --git a/src/client/views/nodes/trails/index.ts b/src/client/views/nodes/trails/index.ts
index 8f3f7b03a..7b18974df 100644
--- a/src/client/views/nodes/trails/index.ts
+++ b/src/client/views/nodes/trails/index.ts
@@ -1,3 +1,3 @@
-export * from "./PresBox";
-export * from "./PresElementBox";
-export * from "./PresEnums";
\ No newline at end of file
+export * from './PresBox';
+export * from './PresElementBox';
+export * from './PresEnums';
diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx
index 02ff661e5..7b959533f 100644
--- a/src/client/views/pdf/AnchorMenu.tsx
+++ b/src/client/views/pdf/AnchorMenu.tsx
@@ -95,29 +95,29 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
         setupMoveUpEvents(
             this,
             e,
-            (e: PointerEvent) => {
-                this.StartDrag(e, this._commentRef.current!);
+            (moveEv: PointerEvent) => {
+                this.StartDrag(moveEv, this._commentRef.current!);
                 return true;
             },
             returnFalse,
-            e => this.OnClick?.(e)
+            clickEv => this.OnClick?.(clickEv)
         );
     };
 
     audioDown = (e: React.PointerEvent) => {
-        setupMoveUpEvents(this, e, returnFalse, returnFalse, e => this.OnAudio?.(e));
+        setupMoveUpEvents(this, e, returnFalse, returnFalse, clickEv => this.OnAudio?.(clickEv));
     };
 
     cropDown = (e: React.PointerEvent) => {
         setupMoveUpEvents(
             this,
             e,
-            (e: PointerEvent) => {
-                this.StartCropDrag(e, this._cropRef.current!);
+            (moveEv: PointerEvent) => {
+                this.StartCropDrag(moveEv, this._cropRef.current!);
                 return true;
             },
             returnFalse,
-            e => this.OnCrop?.(e)
+            clickev => this.OnCrop?.(clickev)
         );
     };
 
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index 4fff2a8e7..7a1e35636 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -30,7 +30,6 @@ export class Uploader extends React.Component<ImageUploadProps> {
     @observable nm: string = 'Choose files'; // Text of 'Choose Files' button
     @observable process: string = ''; // Current status of upload
     @observable private dialogueBoxOpacity = 1;
-    @observable private overlayOpacity = 0.4;
 
     onClick = async () => {
         try {
@@ -167,6 +166,6 @@ export class Uploader extends React.Component<ImageUploadProps> {
     };
 
     render() {
-        return <MainViewModal contents={this.uploadInterface} isDisplayed interactive dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} overlayDisplayedOpacity={this.overlayOpacity} closeOnExternalClick={this.closeUpload} />;
+        return <MainViewModal contents={this.uploadInterface} isDisplayed interactive dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} closeOnExternalClick={this.closeUpload} />;
     }
 }
-- 
cgit v1.2.3-70-g09d2

