From 216385c7e84febce8988ef1390845b0c661fb04f Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 8 Nov 2023 12:55:59 -0500 Subject: fixed bug where tableBox's didn't render all of the rows they receive. lots of code cleanup -- moving things from Doc.ts to better locations. Changed overlays and published docs to be local to their dashboard. changed treeview icons. --- src/client/views/nodes/EquationBox.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/client/views/nodes/EquationBox.tsx') diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx index a77e4bdd1..d8b8bcb27 100644 --- a/src/client/views/nodes/EquationBox.tsx +++ b/src/client/views/nodes/EquationBox.tsx @@ -2,7 +2,6 @@ import EquationEditor from 'equation-editor-react'; import { action, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Width } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { NumCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; @@ -68,7 +67,7 @@ export class EquationBox extends ViewBoxBaseComponent() { } if (e.key === 'Tab') { const graph = Docs.Create.FunctionPlotDocument([this.rootDoc], { - x: NumCast(this.layoutDoc.x) + this.layoutDoc[Width](), + x: NumCast(this.layoutDoc.x) + NumCast(this.layoutDoc._width), y: NumCast(this.layoutDoc.y), _width: 400, _height: 300, -- cgit v1.2.3-70-g09d2 From 2b0e4ccc096998eb1d727f2e85ea8c1a63b27e08 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 18 Nov 2023 23:47:13 -0500 Subject: fixed ctrl-drag for expressions, maps, fform doc selections. fixed using shift to add Doc to a selection and also when bounding box already covers the doc to add. fixed dragging maximize button to start goldenlayout drag properly. fixed typing character to group,etc a multiselection when a text doc has input focus. fixed using clusters. add Shift-U to ungroup alternate group style. multi-select blurs() all active inputs. shift-selecting a multi-selected Doc, deselects it. --- src/client/documents/Documents.ts | 31 +- src/client/util/DragManager.ts | 4 +- src/client/util/SelectionManager.ts | 13 +- src/client/util/SnappingManager.ts | 14 + src/client/views/DocComponent.tsx | 8 +- src/client/views/DocumentDecorations.scss | 24 +- src/client/views/DocumentDecorations.tsx | 341 ++++++++------------- src/client/views/GlobalKeyHandler.ts | 38 ++- src/client/views/MainView.tsx | 11 +- .../views/collections/CollectionDockingView.tsx | 1 + .../collections/CollectionStackedTimeline.tsx | 4 +- src/client/views/collections/CollectionSubView.tsx | 4 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 23 +- .../collectionGrid/CollectionGridView.tsx | 2 +- src/client/views/nodes/DocumentContentsView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 25 +- src/client/views/nodes/EquationBox.tsx | 14 +- src/client/views/nodes/FieldView.tsx | 2 +- src/client/views/nodes/MapBox/MapAnchorMenu.tsx | 2 +- src/client/views/nodes/PDFBox.tsx | 2 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 16 +- .../views/nodes/formattedText/RichTextMenu.tsx | 12 +- src/client/views/pdf/AnchorMenu.tsx | 2 +- 23 files changed, 278 insertions(+), 317 deletions(-) (limited to 'src/client/views/nodes/EquationBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index bd5fa5d78..029653204 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -514,7 +514,17 @@ export namespace Docs { DocumentType.COL, { layout: { view: CollectionView, dataField: defaultDataKey }, - options: { _layout_fitWidth: true, freeform: '', _freeform_panX: 0, _freeform_panY: 0, _freeform_scale: 1, systemIcon: 'BsFillCollectionFill' }, + options: { + _layout_fitWidth: true, + freeform: '', + _freeform_panX: 0, + _freeform_panY: 0, + _freeform_scale: 1, + layout_nativeDimEditable: true, + layout_reflowHorizontal: true, + layout_reflowVertical: true, + systemIcon: 'BsFillCollectionFill', + }, }, ], [ @@ -535,7 +545,7 @@ export namespace Docs { DocumentType.AUDIO, { layout: { view: AudioBox, dataField: defaultDataKey }, - options: { _height: 100, layout_fitWidth: true, layout_reflowHorizontal: true, layout_nativeDimEditable: true, systemIcon: 'BsFillVolumeUpFill' }, + options: { _height: 100, layout_fitWidth: true, layout_reflowHorizontal: true, layout_reflowVertical: true, layout_nativeDimEditable: true, systemIcon: 'BsFillVolumeUpFill' }, }, ], [ @@ -615,14 +625,25 @@ export namespace Docs { DocumentType.EQUATION, { layout: { view: EquationBox, dataField: 'text' }, - options: { layout_nativeDimEditable: true, fontSize: '14px', layout_hideResizeHandles: true, layout_hideDecorationTitle: true, systemIcon: 'BsCalculatorFill' }, ///systemIcon: 'BsSuperscript' + BsSubscript + options: { + fontSize: '14px', + layout_reflowHorizontal: true, + layout_reflowVertical: true, + layout_nativeDimEditable: true, + layout_hideDecorationTitle: true, + systemIcon: 'BsCalculatorFill', + }, ///systemIcon: 'BsSuperscript' + BsSubscript }, ], [ DocumentType.FUNCPLOT, { layout: { view: FunctionPlotBox, dataField: defaultDataKey }, - options: { layout_nativeDimEditable: true }, + options: { + layout_reflowHorizontal: true, + layout_reflowVertical: true, + layout_nativeDimEditable: true, + }, }, ], [ @@ -695,7 +716,7 @@ export namespace Docs { { data: '', layout: { view: ComparisonBox, dataField: defaultDataKey }, - options: { backgroundColor: 'gray', dropAction: 'move', waitForDoubleClickToClick: 'always', systemIcon: 'BsLayoutSplit' }, + options: { backgroundColor: 'gray', dropAction: 'move', waitForDoubleClickToClick: 'always', layout_reflowHorizontal: true, layout_reflowVertical: true, layout_nativeDimEditable: true, systemIcon: 'BsLayoutSplit' }, }, ], [ diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index e59e847c2..f928a1bf9 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -57,7 +57,7 @@ export function SetupDrag(_reference: React.RefObject, docFunc: () export namespace DragManager { let dragDiv: HTMLDivElement; let dragLabel: HTMLDivElement; - export let StartWindowDrag: Opt<(e: { pageX: number; pageY: number }, dragDocs: Doc[], finishDrag?: (aborted: boolean) => void) => void>; + export let StartWindowDrag: Opt<(e: { pageX: number; pageY: number }, dragDocs: Doc[], finishDrag?: (aborted: boolean) => void) => boolean>; export let CompleteWindowDrag: Opt<(aborted: boolean) => void>; export function Root() { @@ -490,7 +490,7 @@ export namespace DragManager { if (dragData instanceof DocumentDragData) { dragData.userDropAction = e.ctrlKey && e.altKey ? 'copy' : e.ctrlKey ? 'embed' : dragData.defaultDropAction; } - if (((e.target as any)?.className === 'lm_tabs' || (e.target as any)?.className === 'lm_header' || e?.shiftKey) && dragData.draggedDocuments.length === 1) { + if (((e.target as any)?.className === 'lm_tabs' || (e.target as any)?.className === 'lm_header') && dragData.draggedDocuments.length === 1) { if (!startWindowDragTimer) { startWindowDragTimer = setTimeout(async () => { startWindowDragTimer = undefined; diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index fcf705ac0..e864458d8 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -21,18 +21,13 @@ export namespace SelectionManager { manager.SelectedSchemaDocument = doc; } @action - SelectView(docView: DocumentView, ctrlPressed: boolean): void { - // if doc is not in SelectedDocuments, add it + SelectView(docView: DocumentView, extendSelection: boolean): void { if (!docView.SELECTED) { - if (!ctrlPressed) this.DeselectAll(); + if (!extendSelection) this.DeselectAll(); manager.SelectedViews.push(docView); - } else if (!ctrlPressed && (manager.SelectedViews.length > 1 || manager.SelectedSchemaDocument)) { - manager.SelectedViews.filter(dv => dv !== docView).forEach(dv => dv.props.whenChildContentsActiveChanged(false)); - manager.SelectedSchemaDocument = undefined; - manager.SelectedViews.length = 0; + docView.SELECTED = true; + docView.props.whenChildContentsActiveChanged(true); } - docView.SELECTED = true; - docView.props.whenChildContentsActiveChanged(true); } @action DeselectView(docView?: DocumentView): void { diff --git a/src/client/util/SnappingManager.ts b/src/client/util/SnappingManager.ts index c0cd94067..fce43eef6 100644 --- a/src/client/util/SnappingManager.ts +++ b/src/client/util/SnappingManager.ts @@ -3,6 +3,8 @@ import { Doc } from '../../fields/Doc'; export namespace SnappingManager { class Manager { + @observable ShiftKey = false; + @observable CtrlKey = false; @observable IsDragging: boolean = false; @observable IsResizing: Doc | undefined; @observable CanEmbed: boolean = false; @@ -33,6 +35,12 @@ export namespace SnappingManager { return manager.vertSnapLines; } + export function SetShiftKey(down: boolean) { + runInAction(() => (manager.ShiftKey = down)); + } + export function SetCtrlKey(down: boolean) { + runInAction(() => (manager.CtrlKey = down)); + } export function SetIsDragging(dragging: boolean) { runInAction(() => (manager.IsDragging = dragging)); } @@ -42,6 +50,12 @@ export namespace SnappingManager { export function SetCanEmbed(canEmbed: boolean) { runInAction(() => (manager.CanEmbed = canEmbed)); } + export function GetShiftKey() { + return manager.ShiftKey; + } + export function GetCtrlKey() { + return manager.CtrlKey; + } export function GetIsDragging() { return manager.IsDragging; } diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index fa43b86bb..9ff27d9a0 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -50,10 +50,10 @@ interface ViewBoxBaseProps { DataDoc?: Doc; DocumentView?: () => DocumentView; fieldKey: string; - isSelected: (outsideReaction?: boolean) => boolean; + isSelected: () => boolean; isContentActive: () => boolean | undefined; renderDepth: number; - rootSelected: (outsideReaction?: boolean) => boolean; + rootSelected: () => boolean; } export function ViewBoxBaseComponent

() { class Component extends React.Component> { @@ -89,8 +89,8 @@ export interface ViewBoxAnnotatableProps { isContentActive: () => boolean | undefined; select: (isCtrlPressed: boolean) => void; whenChildContentsActiveChanged: (isActive: boolean) => void; - isSelected: (outsideReaction?: boolean) => boolean; - rootSelected: (outsideReaction?: boolean) => boolean; + isSelected: () => boolean; + rootSelected: () => boolean; renderDepth: number; isAnnotationOverlay?: boolean; } diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index f41cf1385..bbd951481 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -4,7 +4,6 @@ $linkGap: 3px; $headerHeight: 20px; $resizeHandler: 8px; -.documentDecorations-Dark, .documentDecorations { position: absolute; z-index: 2000; @@ -40,14 +39,12 @@ $resizeHandler: 8px; border-radius: 50%; } } -.documentDecorations-Dark { - background: dimgray; -} .documentDecorations-container { position: absolute; top: 0; left: 0; + transform-origin: 50% calc(50% + 10px); display: grid; grid-template-rows: $headerHeight $resizeHandler 1fr $resizeHandler; grid-template-columns: $resizeHandler 1fr $resizeHandler; @@ -60,6 +57,7 @@ $resizeHandler: 8px; flex-direction: row; gap: 2px; pointer-events: all; + color: black; cursor: move; .documentDecorations-openButton { @@ -169,7 +167,6 @@ $resizeHandler: 8px; } } - .documentDecorations-title-Dark, .documentDecorations-title { opacity: 1; width: calc(100% - 60px); // = margin-left + margin-right @@ -188,22 +185,13 @@ $resizeHandler: 8px; opacity: 1; } - .documentDecorations-titleSpan, - .documentDecorations-titleSpan-Dark { + .documentDecorations-titleSpan { width: 100%; border-radius: 8px; background: $light-gray; display: inline-block; cursor: move; } - .documentDecorations-titleSpan-Dark { - background: hsla(0, 0%, 0%, 0.412); - } - } - - .documentDecorations-title-Dark { - color: white; - background: black; } .documentDecorations-titleBackground { @@ -326,11 +314,6 @@ $resizeHandler: 8px; } } - .documentDecorations-resizer-Dark { - background: $light-gray; - opacity: 0.2; - } - .documentDecorations-topLeftResizer, .documentDecorations-leftResizer, .documentDecorations-bottomLeftResizer { @@ -357,6 +340,7 @@ $resizeHandler: 8px; background: $medium-gray; height: 10; width: 10; + opacity: 0.5; pointer-events: all; cursor: nwse-resize; } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 8df5740fa..dc62e0450 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -5,6 +5,7 @@ import { IconButton } from 'browndash-components'; import { action, computed, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { FaUndo } from 'react-icons/fa'; +import { DateField } from '../../fields/DateField'; import { Doc, DocListCast, Field, HierarchyMapping, ReverseHierarchyMap } from '../../fields/Doc'; import { AclAdmin, AclAugment, AclEdit, DocData } from '../../fields/DocSymbols'; import { InkField } from '../../fields/InkField'; @@ -35,7 +36,6 @@ import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import { ImageBox } from './nodes/ImageBox'; import React = require('react'); import _ = require('lodash'); -import { DateField } from '../../fields/DateField'; @observer export class DocumentDecorations extends React.Component<{ PanelWidth: number; PanelHeight: number; boundsLeft: number; boundsTop: number }, { value: string }> { @@ -49,64 +49,39 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P private _offset = { x: 0, y: 0 }; // offset from click pt to inner edge of resize border private _snapPt = { x: 0, y: 0 }; // last snapped location of resize border private _inkDragDocs: { doc: Doc; x: number; y: number; width: number; height: number }[] = []; + private _interactionLock?: boolean; + @observable _showNothing = true; @observable private _accumulatedTitle = ''; @observable private _titleControlString: string = '#title'; @observable private _editingTitle = false; @observable private _hidden = false; - @observable public AddToSelection = false; // if Shift is pressed, then this should be set so that clicking on the selection background is ignored so overlapped documents can be added to the selection set. - @observable public pushIcon: IconProp = 'arrow-alt-circle-up'; - @observable public pullIcon: IconProp = 'arrow-alt-circle-down'; - @observable public pullColor: string = 'white'; @observable private _isRotating: boolean = false; @observable private _isRounding: boolean = false; - @observable private showLayoutAcl: boolean = false; + @observable private _showLayoutAcl: boolean = false; + @observable private _showRotCenter = false; // whether to show a draggable green dot that represents the center of rotation + @observable private _rotCenter = [0, 0]; // the center of rotation in object coordinates (0,0) = object center (not top left!) constructor(props: any) { super(props); DocumentDecorations.Instance = this; - reaction( - () => SelectionManager.Views().slice(), - action(views => { - this._showNothing = !DocumentView.LongPress && views.length === 1; // show decorations if multiple docs are selected or we're long pressing - this._editingTitle = false; - }) - ); - document.addEventListener( - // show decorations whenever pointer moves outside of selection bounds. - 'pointermove', - action(e => { - if (this.Bounds.x || this.Bounds.y || this.Bounds.r || this.Bounds.b) { - if (this.Bounds.x !== Number.MAX_VALUE && (this.Bounds.x > e.clientX + 10 || this.Bounds.r < e.clientX - 10 || this.Bounds.y > e.clientY + 10 || this.Bounds.b < e.clientY - 10)) { - this._showNothing = false; - } else { - this._showNothing = true; - } - } - }) - ); + document.addEventListener('pointermove', // show decorations whenever pointer moves outside of selection bounds. + action(e => (this._showNothing = !(this.Bounds.x !== Number.MAX_VALUE && (this.Bounds.x > e.clientX + 10 || this.Bounds.r < e.clientX - 10 || this.Bounds.y > e.clientY + 10 || this.Bounds.b < e.clientY - 10))))); // prettier-ignore } - @computed - get Bounds() { - if (LinkFollower.IsFollowing || DocumentView.ExploreMode) return { x: 0, y: 0, r: 0, b: 0 }; - const views = SelectionManager.Views(); - return views - .filter(dv => dv.props.renderDepth > 0) - .map(dv => dv.getBounds()) - .reduce( - (bounds, rect) => - !rect - ? bounds - : { - x: Math.min(rect.left, bounds.x), - y: Math.min(rect.top, bounds.y), - r: Math.max(rect.right, bounds.r), - b: Math.max(rect.bottom, bounds.b), - c: views.length === 1 ? rect.center : undefined, - }, - { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE, c: undefined as { X: number; Y: number } | undefined } - ); + @computed get Bounds() { + return (LinkFollower.IsFollowing || DocumentView.ExploreMode) ? + { x: 0, y: 0, r: 0, b: 0 } + : SelectionManager.Views() + .filter(dv => dv.props.renderDepth > 0) + .map(dv => dv.getBounds()) + .reduce((bounds, rect) => !rect ? bounds + : { x: Math.min(rect.left, bounds.x), + y: Math.min(rect.top, bounds.y), + r: Math.max(rect.right, bounds.r), + b: Math.max(rect.bottom, bounds.b), + c: SelectionManager.Views().length === 1 ? rect.center : undefined }, + { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE, c: undefined as { X: number; Y: number } | undefined }); // prettier-ignore } @action @@ -162,48 +137,43 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P } }; - @action onContainerDown = (e: React.PointerEvent): void => { - const first = SelectionManager.Views()[0]; - const effectiveLayoutAcl = GetEffectiveAcl(first.rootDoc); + onContainerDown = (e: React.PointerEvent) => { + const effectiveLayoutAcl = GetEffectiveAcl(SelectionManager.Views()[0].rootDoc); if (effectiveLayoutAcl == AclAdmin || effectiveLayoutAcl == AclEdit || effectiveLayoutAcl == AclAugment) { - setupMoveUpEvents( - this, - e, - e => this.onBackgroundMove(true, e), - e => {}, - emptyFunction - ); + setupMoveUpEvents(this, e, e => this.onBackgroundMove(true, e), emptyFunction, emptyFunction); + e.stopPropagation(); } }; - @action onTitleDown = (e: React.PointerEvent): void => { - const first = SelectionManager.Views()[0]; - const effectiveLayoutAcl = GetEffectiveAcl(first.rootDoc); + onTitleDown = (e: React.PointerEvent) => { + const effectiveLayoutAcl = GetEffectiveAcl(SelectionManager.Views()[0].rootDoc); if (effectiveLayoutAcl == AclAdmin || effectiveLayoutAcl == AclEdit || effectiveLayoutAcl == AclAugment) { setupMoveUpEvents( this, e, e => this.onBackgroundMove(true, e), - e => {}, + emptyFunction, action(e => { !this._editingTitle && (this._accumulatedTitle = this._titleControlString.startsWith('#') ? this.selectionTitle : this._titleControlString); this._editingTitle = true; this._keyinput.current && setTimeout(this._keyinput.current.focus); }) ); + e.stopPropagation(); } }; - onBackgroundDown = (e: React.PointerEvent) => setupMoveUpEvents(this, e, e => this.onBackgroundMove(false, e), emptyFunction, emptyFunction); - + onBackgroundDown = (e: React.PointerEvent) => { + setupMoveUpEvents(this, e, e => this.onBackgroundMove(false, e), emptyFunction, emptyFunction); + e.stopPropagation(); + }; @action onBackgroundMove = (dragTitle: boolean, e: PointerEvent): boolean => { - const first = SelectionManager.Views()[0]; - const effectiveLayoutAcl = GetEffectiveAcl(first.rootDoc); + const dragDocView = SelectionManager.Views()[0]; + const effectiveLayoutAcl = GetEffectiveAcl(dragDocView.rootDoc); if (effectiveLayoutAcl != AclAdmin && effectiveLayoutAcl != AclEdit && effectiveLayoutAcl != AclAugment) { return false; } - const dragDocView = SelectionManager.Views()[0]; const containers = new Set(); SelectionManager.Views().forEach(v => containers.add(DocCast(v.rootDoc.embedContainer))); if (containers.size > 1) return false; @@ -234,9 +204,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P _deleteAfterIconify = false; _iconifyBatch: UndoManager.Batch | undefined; onCloseClick = (forceDeleteOrIconify: boolean | undefined) => { - const views = SelectionManager.Views() - .slice() - .filter(v => v && v.props.renderDepth > 0); + const views = SelectionManager.Views().filter(v => v && v.props.renderDepth > 0); if (forceDeleteOrIconify === false && this._iconifyBatch) return; this._deleteAfterIconify = forceDeleteOrIconify || this._iconifyBatch ? true : false; var iconifyingCount = views.length; @@ -251,7 +219,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P iconView.props.removeDocument?.(iconView.props.Document); } }); - views.forEach(v => SelectionManager.DeselectView()); + views.forEach(SelectionManager.DeselectView); } this._iconifyBatch?.end(); this._iconifyBatch = undefined; @@ -267,21 +235,11 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P if (forceDeleteOrIconify) finished(forceDeleteOrIconify); else if (!this._deleteAfterIconify) views.forEach(dv => dv.iconify(finished)); }; + onMaximizeDown = (e: React.PointerEvent) => { - setupMoveUpEvents( - this, - e, - () => { - DragManager.StartWindowDrag?.(e, [SelectionManager.Views().slice(-1)[0].rootDoc]); - return true; - }, - emptyFunction, - this.onMaximizeClick, - false, - false - ); + setupMoveUpEvents(this, e, () => DragManager.StartWindowDrag?.(e, [SelectionManager.Views().lastElement().rootDoc]) ?? false, emptyFunction, this.onMaximizeClick, false, false); + e.stopPropagation(); }; - onMaximizeClick = (e: any): void => { const selectedDocs = SelectionManager.Views(); if (selectedDocs.length) { @@ -319,63 +277,51 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P SelectionManager.DeselectAll(); }; - onSelectorClick = () => SelectionManager.Views()?.[0]?.props.docViewPath?.().lastElement()?.select(false); + onSelectContainerDocClick = () => SelectionManager.Views()?.[0]?.props.docViewPath?.().lastElement()?.select(false); /** - * Handles setting up events when user clicks on the border radius editor - * @param e PointerEvent + * sets up events when user clicks on the border radius editor */ @action onRadiusDown = (e: React.PointerEvent): void => { this._isRounding = DocumentView.Interacting = true; this._resizeUndo = UndoManager.StartBatch('DocDecs set radius'); - // Call util move event function setupMoveUpEvents( - this, // target - e, // pointerEvent - (e, down) => { - const x = this.Bounds.x + 3; - const y = this.Bounds.y + 3; + this, + e, + e => { + const [x, y] = [this.Bounds.x + 3, this.Bounds.y + 3]; const maxDist = Math.min((this.Bounds.r - this.Bounds.x) / 2, (this.Bounds.b - this.Bounds.y) / 2); - let dist = Math.sqrt((e.clientX - x) * (e.clientX - x) + (e.clientY - y) * (e.clientY - y)); - if (e.clientX < x && e.clientY < y) dist = 0; - SelectionManager.Views() - .map(dv => dv.props.Document) - .map(doc => { - const docMax = Math.min(NumCast(doc.width) / 2, NumCast(doc.height) / 2); - const ratio = dist / maxDist; - const radius = Math.min(1, ratio) * docMax; - doc.layout_borderRounding = `${radius}px`; - }); + const dist = e.clientX < x && e.clientY < y ? 0 : Math.sqrt((e.clientX - x) * (e.clientX - x) + (e.clientY - y) * (e.clientY - y)); + SelectionManager.Docs().map(doc => { + const docMax = Math.min(NumCast(doc.width) / 2, NumCast(doc.height) / 2); + const radius = Math.min(1, dist / maxDist) * docMax; // set radius based on ratio of drag distance to half diagonal distance of bounding box + doc.layout_borderRounding = `${radius}px`; + }); return false; - }, // moveEvent + }, action(e => { DocumentView.Interacting = this._isRounding = false; this._resizeUndo?.end(); }), // upEvent - e => {}, // clickEvent, + emptyFunction, true ); + e.stopPropagation(); }; @action onLockDown = (e: React.PointerEvent): void => { - // Call util move event function setupMoveUpEvents( - this, // target - e, // pointerEvent - returnFalse, // moveEvent - emptyFunction, // upEvent - e => { - UndoManager.RunInBatch( - () => - SelectionManager.Views().map(dv => { - dv.rootDoc._lockedPosition = !dv.rootDoc._lockedPosition; - dv.rootDoc._pointerEvents = dv.rootDoc._lockedPosition ? 'none' : undefined; - }), - 'toggleBackground' - ); - } // clickEvent + this, + e, + returnFalse, // don't care about move or up event, + emptyFunction, // just care about whether we get a click event + e => UndoManager.RunInBatch( + () => SelectionManager.Docs().forEach(doc => + doc._pointerEvents = (doc._lockedPosition = !doc._lockedPosition)? 'none' : undefined ), + 'toggleBackground' ) // prettier-ignore ); + e.stopPropagation(); }; setRotateCenter = (seldocview: DocumentView, rotCenter: number[]) => { @@ -393,16 +339,11 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P setupMoveUpEvents( this, e, - action((e: PointerEvent, down: number[], delta: number[]) => { - this.setRotateCenter(seldocview, [this.rotCenter[0] + delta[0], this.rotCenter[1] + delta[1]]); - return false; - }), // moveEvent - action(action(() => (this._isRotating = false))), // upEvent - action((e, doubleTap) => { - seldocview.rootDoc.rotation_centerX = 0; - seldocview.rootDoc.rotation_centerY = 0; - }) - ); + (e: PointerEvent, down: number[], delta: number[]) => // return false to keep getting events + this.setRotateCenter(seldocview, [this.rotCenter[0] + delta[0], this.rotCenter[1] + delta[1]]) as any as boolean, + action(e => (this._isRotating = false)), // upEvent + action(e => (seldocview.rootDoc.rotation_centerX = seldocview.rootDoc.rotation_centerY = 0)) + ); // prettier-ignore }; @action @@ -473,6 +414,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P onPointerDown = (e: React.PointerEvent): void => { SnappingManager.SetIsResizing(SelectionManager.Docs().lastElement()); setupMoveUpEvents(this, e, this.onPointerMove, this.onPointerUp, emptyFunction); + e.stopPropagation(); DocumentView.Interacting = true; // turns off pointer events on things like youtube videos and web pages so that dragging doesn't get "stuck" when cursor moves over them this._resizeHdlId = e.currentTarget.className; const bounds = e.currentTarget.getBoundingClientRect(); @@ -482,46 +424,44 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P SelectionManager.Views().forEach(docView => docView.CollectionFreeFormView?.dragStarting(false, false)); }; - _lock: any; + projectDragToAspect = (e: PointerEvent, docView: DocumentView, fixedAspect: number) => { + // need to generalize for bl and tr drag handles + const project = (p: number[], a: number[], b: number[]) => { + const atob = [b[0] - a[0], b[1] - a[1]]; + const atop = [p[0] - a[0], p[1] - a[1]]; + const len = atob[0] * atob[0] + atob[1] * atob[1]; + let dot = atop[0] * atob[0] + atop[1] * atob[1]; + const t = dot / len; + dot = (b[0] - a[0]) * (p[1] - a[1]) - (b[1] - a[1]) * (p[0] - a[0]); + return [a[0] + atob[0] * t, a[1] + atob[1] * t]; + }; + const tl = docView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); + return project([e.clientX + this._offset.x, e.clientY + this._offset.y], tl, [tl[0] + fixedAspect, tl[1] + 1]); + }; onPointerMove = (e: PointerEvent, down: number[], move: number[]): boolean => { const first = SelectionManager.Views()[0]; const effectiveAcl = GetEffectiveAcl(first.rootDoc); if (!(effectiveAcl == AclAdmin || effectiveAcl == AclEdit || effectiveAcl == AclAugment)) return false; if (!first) return false; - let thisPt = { x: e.clientX - this._offset.x, y: e.clientY - this._offset.y }; var fixedAspect = Doc.NativeAspect(first.layoutDoc); const dragHdl = this._resizeHdlId.split(' ')[0].replace('documentDecorations-', '').replace('Resizer', ''); - // do snapping of drag point - if (fixedAspect && (dragHdl === 'bottomRight' || dragHdl === 'topLeft')) { - // need to generalize for bl and tr drag handles - const project = (p: number[], a: number[], b: number[]) => { - const atob = [b[0] - a[0], b[1] - a[1]]; - const atop = [p[0] - a[0], p[1] - a[1]]; - const len = atob[0] * atob[0] + atob[1] * atob[1]; - let dot = atop[0] * atob[0] + atop[1] * atob[1]; - const t = dot / len; - dot = (b[0] - a[0]) * (p[1] - a[1]) - (b[1] - a[1]) * (p[0] - a[0]); - return [a[0] + atob[0] * t, a[1] + atob[1] * t]; - }; - const tl = first.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); - const drag = project([e.clientX + this._offset.x, e.clientY + this._offset.y], tl, [tl[0] + fixedAspect, tl[1] + 1]); - thisPt = DragManager.snapDragAspect(drag, fixedAspect); - } else { - thisPt = DragManager.snapDrag(e, -this._offset.x, -this._offset.y, this._offset.x, this._offset.y); - } + const thisPt = // do snapping of drag point + fixedAspect && (dragHdl === 'bottomRight' || dragHdl === 'topLeft') + ? DragManager.snapDragAspect(this.projectDragToAspect(e, first, fixedAspect), fixedAspect) + : DragManager.snapDrag(e, -this._offset.x, -this._offset.y, this._offset.x, this._offset.y); const { scale, refPt } = this.getResizeVals(thisPt, dragHdl); - // resize selected docs - !this._lock && runInAction(async () => { - this._lock = true; + + !this._interactionLock && runInAction(async () => { // resize selected docs if we're not in the middle of a resize (ie, throttle input events to frame rate) + this._interactionLock = true; this._snapPt = thisPt; e.ctrlKey && (SelectionManager.Views().forEach(docView => !Doc.NativeHeight(docView.props.Document) && docView.toggleNativeDimensions())); const fixedAspect = SelectionManager.Docs().some(this.hasFixedAspect); + const scaleAspect = {x:scale.x === 1 && fixedAspect ? scale.y : scale.x, y: scale.x !== 1 && fixedAspect ? scale.x : scale.y}; SelectionManager.Views().forEach(docView => - this.resizeView(docView, refPt, scale.x === 1 && fixedAspect ? scale.y : scale.x, - scale.x !== 1 && fixedAspect ? scale.x : scale.y, { dragHdl, ctrlKey:e.ctrlKey })); // prettier-ignore - await new Promise(res => setTimeout(() => res(this._lock = undefined))); + this.resizeView(docView, refPt, scaleAspect, { dragHdl, ctrlKey:e.ctrlKey })); // prettier-ignore + await new Promise(res => setTimeout(() => res(this._interactionLock = undefined))); }); // prettier-ignore return false; @@ -554,16 +494,15 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P // // resize a single DocumentView about the specified reference point, possibly setting/updating the native dimensions of the Doc // - resizeView = (docView: DocumentView, refPt: number[], scaleX: number, scaleY: number, opts: { dragHdl: string; ctrlKey: boolean }) => { + resizeView = (docView: DocumentView, refPt: number[], scale: { x: number; y: number }, opts: { dragHdl: string; ctrlKey: boolean }) => { const doc = docView.rootDoc; if (doc.isGroup) { DocListCast(doc.data) .map(member => DocumentManager.Instance.getDocumentView(member, docView)!) - .forEach(member => this.resizeView(member, refPt, scaleX, scaleY, opts)); - doc.xPadding = NumCast(doc.xPadding) * scaleX; - doc.yPadding = NumCast(doc.yPadding) * scaleY; + .forEach(member => this.resizeView(member, refPt, scale, opts)); + doc.xPadding = NumCast(doc.xPadding) * scale.x; + doc.yPadding = NumCast(doc.yPadding) * scale.y; } else { - const doc = docView.rootDoc; const refCent = docView.props.ScreenToLocalTransform().transformPoint(refPt[0], refPt[1]); // fixed reference point for resize (ie, a point that doesn't move) const [nwidth, nheight] = [docView.nativeWidth, docView.nativeHeight]; const [initWidth, initHeight] = [NumCast(doc._width, 1), NumCast(doc._height)]; @@ -574,12 +513,12 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P (doc.layout_reflowVertical && (opts.dragHdl === 'bottom' || opts.dragHdl === 'top' || opts.ctrlKey)); // eg rtf, web, pdf if (nwidth && nheight && !modifyNativeDim) { // eg., dragging right resizer on PDF -- enforce native dimensions because not expliclty overridden with ctrl or bottom resize drag - scaleX === 1 ? (scaleX = scaleY) : (scaleY = scaleX); + scale.x === 1 ? (scale.x = scale.y) : (scale.x = scale.x); } if (['right', 'left'].includes(opts.dragHdl) && modifyNativeDim && Doc.NativeWidth(doc)) { const setData = Doc.NativeWidth(Doc.GetProto(doc)) === doc.nativeWidth; - doc.nativeWidth = scaleX * Doc.NativeWidth(doc); + doc.nativeWidth = scale.x * Doc.NativeWidth(doc); if (setData) Doc.SetNativeWidth(Doc.GetProto(doc), NumCast(doc.nativeWidth)); if (doc.layout_reflowVertical && !NumCast(doc.nativeHeight)) { doc._nativeHeight = (initHeight / initWidth) * nwidth; // initializes the nativeHeight for a PDF @@ -587,18 +526,18 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P } if (['bottom', 'top'].includes(opts.dragHdl) && modifyNativeDim && Doc.NativeHeight(doc)) { const setData = Doc.NativeHeight(Doc.GetProto(doc)) === doc.nativeHeight; - doc._nativeHeight = scaleY * Doc.NativeHeight(doc); + doc._nativeHeight = scale.y * Doc.NativeHeight(doc); if (setData) Doc.SetNativeHeight(Doc.GetProto(doc), NumCast(doc._nativeHeight)); } - doc._width = NumCast(doc._width) * scaleX; - doc._height = NumCast(doc._height) * scaleY; + doc._width = NumCast(doc._width) * scale.x; + doc._height = NumCast(doc._height) * scale.y; const { deltaX, deltaY } = this.realignRefPt(doc, refCent, initWidth, initHeight); doc.x = NumCast(doc.x) + deltaX; doc.y = NumCast(doc.y) + deltaY; doc._layout_modificationDate = new DateField(); - scaleY !== 1 && (doc._layout_autoHeight = undefined); + scale.y !== 1 && (doc._layout_autoHeight = undefined); } }; @@ -628,10 +567,10 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P @action onPointerUp = (e: PointerEvent): void => { SnappingManager.SetIsResizing(undefined); - this._resizeHdlId = ''; + SnappingManager.clearSnapLines(); DocumentView.Interacting = false; + this._resizeHdlId = ''; this._resizeUndo?.end(); - SnappingManager.clearSnapLines(); // detect layout_autoHeight gesture and apply SelectionManager.Docs().forEach(doc => NumCast(doc._height) < 20 && (doc._layout_autoHeight = true)); @@ -639,16 +578,11 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P this._inkDragDocs .map(oldbds => ({ oldbds, inkPts: Cast(oldbds.doc.data, InkField)?.inkData || [] })) .forEach(({ oldbds: { doc, x, y, width, height }, inkPts }) => { - Doc.GetProto(doc).data = new InkField( - inkPts.map( - ( - ipt // (new x — oldx) + newWidth * (oldxpoint /oldWidth) - ) => ({ - X: NumCast(doc.x) - x + (NumCast(doc.width) * ipt.X) / width, - Y: NumCast(doc.y) - y + (NumCast(doc.height) * ipt.Y) / height, - }) - ) - ); + Doc.GetProto(doc).data = new InkField(inkPts.map( + (ipt) => ({// (new x — oldx) + newWidth * (oldxpoint /oldWidth) + X: NumCast(doc.x) - x + (NumCast(doc.width) * ipt.X) / width, + Y: NumCast(doc.y) - y + (NumCast(doc.height) * ipt.Y) / height, + }))); // prettier-ignore Doc.SetNativeWidth(doc, undefined); Doc.SetNativeHeight(doc, undefined); }); @@ -676,8 +610,6 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P return SelectionManager.Views().some(docView => docView.rootDoc.layout_fieldKey === 'layout_icon'); } - @observable _showRotCenter = false; - @observable _rotCenter = [0, 0]; @computed get rotCenter() { if (SelectionManager.Views().length) { const seldocview = SelectionManager.Views()[0]; @@ -694,19 +626,16 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P return this._rotCenter; } - @observable _showNothing = true; - render() { const { b, r, x, y } = this.Bounds; - const bounds = { b, r, x, y }; const seldocview = SelectionManager.Views().lastElement(); - if (SnappingManager.GetIsDragging() || bounds.r - bounds.x < 1 || bounds.x === Number.MAX_VALUE || !seldocview || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) { + if (SnappingManager.GetIsDragging() || r - x < 1 || x === Number.MAX_VALUE || !seldocview || this._hidden || isNaN(r) || isNaN(b) || isNaN(x) || isNaN(y)) { setTimeout(action(() => (this._showNothing = true))); return null; } // sharing - const acl = GetEffectiveAcl(!this.showLayoutAcl ? Doc.GetProto(seldocview.rootDoc) : seldocview.rootDoc); + const acl = GetEffectiveAcl(!this._showLayoutAcl ? Doc.GetProto(seldocview.rootDoc) : seldocview.rootDoc); const docShareMode = HierarchyMapping.get(acl)!.name; const shareMode = StrCast(docShareMode); var shareSymbolIcon = ReverseHierarchyMap.get(shareMode)?.image; @@ -745,6 +674,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P ); + const bounds = { b, r, x, y }; const leftBounds = this.props.boundsLeft; const topBounds = LightboxView.LightboxDoc ? 0 : this.props.boundsTop; bounds.x = Math.max(leftBounds, bounds.x - this._resizeBorderWidth / 2) + this._resizeBorderWidth / 2; @@ -757,8 +687,6 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P const useRotation = !hideResizers && seldocview.rootDoc.type !== DocumentType.EQUATION && seldocview.CollectionFreeFormDocumentView; // when do we want an object to not rotate? const rotation = SelectionManager.Views().length == 1 ? NumCast(seldocview.rootDoc._rotation) : 0; - const resizerScheme = ''; - // Radius constants const useRounding = seldocview.ComponentView instanceof ImageBox || seldocview.ComponentView instanceof FormattedTextBox || seldocview.ComponentView instanceof CollectionFreeFormView; const borderRadius = numberValue(Cast(seldocview.rootDoc.layout_borderRounding, 'string', null)); @@ -801,7 +729,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P onPointerDown={e => e.stopPropagation()} /> ) : ( -

e.stopPropagation}> +
{hideTitle ? null : ( {this.selectionTitle} @@ -810,7 +738,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P {sharingMenu} {!useLock ? null : ( toggle ability to interact with document
} placement="top"> -
e.preventDefault()}> +
@@ -827,30 +755,24 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P height: bounds.b - bounds.y + this._resizeBorderWidth + 'px', left: bounds.x - this._resizeBorderWidth / 2, top: bounds.y - this._resizeBorderWidth / 2, - pointerEvents: DocumentDecorations.Instance.AddToSelection || DocumentView.Interacting ? 'none' : 'all', + background: SnappingManager.GetShiftKey() ? undefined : 'yellow', + pointerEvents: SnappingManager.GetShiftKey() || DocumentView.Interacting ? 'none' : 'all', display: SelectionManager.Views().length <= 1 || hideDecorations ? 'none' : undefined, }} onPointerDown={this.onBackgroundDown} - onContextMenu={e => { - e.preventDefault(); - e.stopPropagation(); - }} /> {bounds.r - bounds.x < 15 && bounds.b - bounds.y < 15 ? null : (
@@ -861,37 +783,34 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
{hideResizers ? null : ( <> -
e.preventDefault()} /> -
e.preventDefault()} /> -
e.preventDefault()} /> -
e.preventDefault()} /> -
-
e.preventDefault()} /> -
e.preventDefault()} /> -
e.preventDefault()} /> -
e.preventDefault()} /> - - {seldocview.props.renderDepth <= 1 || !seldocview.props.docViewPath().lastElement() ? null : topBtn('selector', 'arrow-alt-circle-up', undefined, this.onSelectorClick, 'tap to select containing document')} +
+
+
+
+
+
+
+
+
+ {seldocview.props.renderDepth <= 1 || !seldocview.props.docViewPath().lastElement() + ? null + : topBtn('selector', 'arrow-alt-circle-up', undefined, this.onSelectContainerDocClick, 'tap to select containing document')} )} {useRounding && (
e.preventDefault()} /> )} {hideDocumentButtonBar || this._showNothing ? null : (
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index 13791b763..87f81fe76 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -51,12 +51,18 @@ export class KeyManager { public unhandle = action((e: KeyboardEvent) => { e.key === 'Control' && (CtrlKey = false); - if (e.key?.toLowerCase() === 'shift') runInAction(() => (DocumentDecorations.Instance.AddToSelection = false)); + }); + public handleModifiers = action((e: KeyboardEvent) => { + if (e.shiftKey) SnappingManager.SetShiftKey(true); + if (e.ctrlKey) SnappingManager.SetCtrlKey(true); + }); + public unhandleModifiers = action((e: KeyboardEvent) => { + if (!e.shiftKey) SnappingManager.SetShiftKey(false); + if (!e.ctrlKey) SnappingManager.SetCtrlKey(false); }); public handle = action((e: KeyboardEvent) => { e.key === 'Control' && (CtrlKey = true); - if (e.key?.toLowerCase() === 'shift') DocumentDecorations.Instance.AddToSelection = true; //if (!Doc.noviceMode && e.key.toLocaleLowerCase() === "shift") DocServer.UPDATE_SERVER_CACHE(true); const keyname = e.key && e.key.toLowerCase(); this.handleGreedy(keyname); @@ -94,28 +100,21 @@ export class KeyManager { switch (keyname) { case 'u': if (document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') { - const ungroupings = SelectionManager.Views().slice(); + const ungroupings = SelectionManager.Views(); UndoManager.RunInBatch(() => ungroupings.map(dv => (dv.layoutDoc.group = undefined)), 'ungroup'); SelectionManager.DeselectAll(); } break; case 'g': if (document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') { - const groupings = SelectionManager.Views().slice(); - const randomGroup = random(0, 1000); - const collectionView = groupings.reduce((col, g) => (col === null || g.CollectionFreeFormView === col ? g.CollectionFreeFormView : undefined), null as null | undefined | CollectionFreeFormView); + const selected = SelectionManager.Views(); + const collectionView = selected.reduce((col, dv) => (col === null || dv.CollectionFreeFormView === col ? dv.CollectionFreeFormView : undefined), null as null | undefined | CollectionFreeFormView); if (collectionView) { - UndoManager.RunInBatch(() => { - collectionView._marqueeViewRef.current?.collection( - e, - true, - groupings.map(g => g.rootDoc) - ); - }, 'grouping'); + UndoManager.RunInBatch(() => + collectionView._marqueeViewRef.current?.collection(e, true, SelectionManager.Docs()) + , 'grouping'); break; } - UndoManager.RunInBatch(() => groupings.map(dv => (dv.layoutDoc.group = randomGroup)), 'group'); - SelectionManager.DeselectAll(); } break; case ' ': @@ -183,11 +182,16 @@ export class KeyManager { case 'arrowright': return this.nudge(10, 0, 'nudge right'); case 'arrowup': return this.nudge(0, -10, 'nudge up'); case 'arrowdown': return this.nudge(0, 10, 'nudge down'); + case 'u' : + if (document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') { + UndoManager.RunInBatch(() => SelectionManager.Docs().forEach(doc => (doc.group = undefined)), 'unggroup'); + SelectionManager.DeselectAll(); + } + break; case 'g': if (document.activeElement?.tagName !== 'INPUT' && document.activeElement?.tagName !== 'TEXTAREA') { - const groupings = SelectionManager.Views().slice(); const randomGroup = random(0, 1000); - UndoManager.RunInBatch(() => groupings.map(dv => (dv.layoutDoc.group = randomGroup)), 'group'); + UndoManager.RunInBatch(() => SelectionManager.Docs().forEach(doc => (doc.group = randomGroup)), 'group'); SelectionManager.DeselectAll(); } break; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 5bed0f923..f40f1f3e8 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -4,7 +4,7 @@ import * as far from '@fortawesome/free-regular-svg-icons'; import * as fa from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import 'browndash-components/dist/styles/global.min.css'; -import { action, computed, configure, observable, runInAction } from 'mobx'; +import { action, computed, configure, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import 'normalize.css'; import * as React from 'react'; @@ -143,6 +143,11 @@ export class MainView extends React.Component { mainDocViewHeight = () => this._dashUIHeight - this.headerBarDocHeight(); componentDidMount() { + reaction( + // when a multi-selection occurs, remove focus from all active elements to allow keyboad input to go only to global key manager to act upon selection + () => SelectionManager.Views().slice(), + views => views.length > 1 && (document.activeElement as any)?.blur !== undefined && (document.activeElement as any)!.blur() + ); const scriptTag = document.createElement('script'); scriptTag.setAttribute('type', 'text/javascript'); scriptTag.setAttribute('src', 'https://www.bing.com/api/maps/mapcontrol?callback=makeMap'); @@ -196,6 +201,10 @@ export class MainView extends React.Component { tag.src = 'https://www.youtube.com/iframe_api'; const firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode!.insertBefore(tag, firstScriptTag); + window.removeEventListener('keydown', KeyManager.Instance.handleModifiers, true); + window.addEventListener('keydown', KeyManager.Instance.handleModifiers, true); + window.removeEventListener('keyup', KeyManager.Instance.unhandleModifiers); + window.addEventListener('keyup', KeyManager.Instance.unhandleModifiers); window.removeEventListener('keydown', KeyManager.Instance.handle); window.addEventListener('keydown', KeyManager.Instance.handle); window.removeEventListener('keyup', KeyManager.Instance.unhandle); diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 9c644e2cc..f155e64b5 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -85,6 +85,7 @@ export class CollectionDockingView extends CollectionSubView() { const dragSource = CollectionDockingView.Instance?._goldenLayout.createDragSource(document.createElement('div'), config); this.tabDragStart(dragSource, finishDrag); dragSource._dragListener.onMouseDown({ pageX: e.pageX, pageY: e.pageY, preventDefault: emptyFunction, button: 0 }); + return true; }; tabItemDropped = () => DragManager.CompleteWindowDrag?.(false); diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 7c61bc4da..584098d35 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -270,7 +270,7 @@ export class CollectionStackedTimeline extends CollectionSubView { if (shiftKey) { @@ -681,7 +681,7 @@ interface StackedTimelineAnchorProps { _timeline: HTMLDivElement | null; focus: DocFocusFunc; currentTimecode: () => number; - isSelected: (outsideReaction?: boolean) => boolean; + isSelected: () => boolean; stackedTimeline: CollectionStackedTimeline; trimStart: number; trimEnd: number; diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index f70c85dcf..328b060c4 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -60,9 +60,7 @@ export function CollectionSubView(moreProps?: X) { return this.props.DataDoc instanceof Doc && this.props.Document.isTemplateForField ? Doc.GetProto(this.props.DataDoc) : this.props.Document.resolvedDataDoc ? this.props.Document : Doc.GetProto(this.props.Document); // if the layout document has a resolvedDataDoc, then we don't want to get its parent which would be the unexpanded template } - rootSelected = (outsideReaction?: boolean) => { - return this.props.isSelected(outsideReaction) || (this.rootDoc && this.props.rootSelected(outsideReaction)); - }; + rootSelected = () => this.props.isSelected() || (this.rootDoc && this.props.rootSelected()); // The data field for rendering this collection will be on the this.props.Document unless we're rendering a template in which case we try to use props.DataDoc. // When a document has a DataDoc but it's not a template, then it contains its own rendering data, but needs to pass the DataDoc through diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 2801c1a4a..ba4e30a9b 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -104,10 +104,7 @@ export class CollectionFreeFormView extends CollectionSubView { const childLayouts = this.childLayoutPairs.map(pair => pair.layout); if (this.props.Document._freeform_useClusters) { this._clusterSets.forEach(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1)); @@ -580,7 +577,7 @@ export class CollectionFreeFormView extends CollectionSubView, props: Opt, property: string) => { let styleProp = this.props.styleProvider?.(doc, props, property); // bcz: check 'props' used to be renderDepth + 1 @@ -1186,7 +1183,7 @@ export class CollectionFreeFormView extends CollectionSubView this.doInternalLayoutComputation, + computation => (this._layoutElements = this.doLayoutComputation(computation.newPool, computation.computedElementData)), + { fireImmediately: true } + ); } static replaceCanvases(oldDiv: HTMLElement, newDiv: HTMLElement) { @@ -1570,7 +1573,7 @@ export class CollectionFreeFormView extends CollectionSubView disposer?.()); } diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index cd8b7a0cc..274012000 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -359,7 +359,7 @@ export class CollectionGridView extends CollectionSubView() { }, false ); - if (this.props.isSelected(true)) e.stopPropagation(); + if (this.props.isSelected()) e.stopPropagation(); } }; diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index c4703a47c..8c8c987fe 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -119,7 +119,7 @@ export class HTMLtag extends React.Component { @observer export class DocumentContentsView extends React.Component< DocumentViewProps & { - isSelected: (outsideReaction: boolean) => boolean; + isSelected: () => boolean; select: (ctrl: boolean) => void; NativeDimScaling?: () => number; setHeight?: (height: number) => void; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index e3d6c3fdf..a61396275 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -176,7 +176,7 @@ export interface DocumentViewSharedProps { searchFilterDocs: () => Doc[]; layout_showTitle?: () => string; whenChildContentsActiveChanged: (isActive: boolean) => void; - rootSelected: (outsideReaction?: boolean) => boolean; // whether the root of a template has been selected + rootSelected: () => boolean; // whether the root of a template has been selected addDocTab: (doc: Doc, where: OpenWhere) => boolean; filterAddDocument?: (doc: Doc[]) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example) addDocument?: (doc: Doc | Doc[], annotationKey?: string) => boolean; @@ -243,7 +243,7 @@ export interface DocumentViewProps extends DocumentViewSharedProps { export interface DocumentViewInternalProps extends DocumentViewProps { NativeWidth: () => number; NativeHeight: () => number; - isSelected: (outsideReaction?: boolean) => boolean; + isSelected: () => boolean; select: (ctrlPressed: boolean, shiftPress?: boolean) => void; DocumentView: () => DocumentView; viewPath: () => DocumentView[]; @@ -738,7 +738,7 @@ export class DocumentViewInternal extends DocComponent { - if (this.rootDoc.type !== DocumentType.MAP) DocumentViewInternal.SelectAfterContextMenu && !this.props.isSelected(true) && SelectionManager.SelectView(this.props.DocumentView(), false); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. + if (this.rootDoc.type !== DocumentType.MAP) DocumentViewInternal.SelectAfterContextMenu && !this.props.isSelected() && SelectionManager.SelectView(this.props.DocumentView(), false); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. setTimeout(() => simulateMouseClick(document.elementFromPoint(e.clientX, e.clientY), e.clientX, e.clientY, e.screenX, e.screenY)); }; if (navigator.userAgent.includes('Macintosh')) { @@ -902,7 +902,7 @@ export class DocumentViewInternal extends DocComponent this._rootSelected; panelHeight = () => this.props.PanelHeight() - this.headerMargin; @@ -1598,13 +1598,16 @@ export class DocumentView extends React.Component { docViewPathFunc = () => this.docViewPath; isSelected = () => SelectionManager.IsSelected(this); select = (extendSelection: boolean, focusSelection?: boolean) => { - SelectionManager.SelectView(this, extendSelection); - if (focusSelection) { - DocumentManager.Instance.showDocument(this.rootDoc, { - willZoomCentered: true, - zoomScale: 0.9, - zoomTime: 500, - }); + if (this.isSelected() && SelectionManager.Views().length > 1) SelectionManager.DeselectView(this); + else { + SelectionManager.SelectView(this, extendSelection); + if (focusSelection) { + DocumentManager.Instance.showDocument(this.rootDoc, { + willZoomCentered: true, + zoomScale: 0.9, + zoomTime: 500, + }); + } } }; NativeWidth = () => this.effectiveNativeWidth; diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx index d8b8bcb27..d347c285b 100644 --- a/src/client/views/nodes/EquationBox.tsx +++ b/src/client/views/nodes/EquationBox.tsx @@ -84,8 +84,18 @@ export class EquationBox extends ViewBoxBaseComponent() { updateSize = () => { const style = this._ref.current && getComputedStyle(this._ref.current.element.current); if (style?.width.endsWith('px') && style?.height.endsWith('px')) { - this.layoutDoc._width = Math.max(35, Number(style.width.replace('px', ''))); - this.layoutDoc._height = Math.max(25, Number(style.height.replace('px', ''))); + if (this.layoutDoc._nativeWidth) { + // if equation has been scaled then editing the expression must also edit the native dimensions to keep the aspect ratio + const prevNwidth = NumCast(this.layoutDoc._nativeWidth); + const prevNheight = NumCast(this.layoutDoc._nativeHeight); + this.layoutDoc._nativeWidth = Math.max(35, Number(style.width.replace('px', ''))); + this.layoutDoc._nativeHeight = Math.max(25, Number(style.height.replace('px', ''))); + this.layoutDoc._width = (NumCast(this.layoutDoc._width) * NumCast(this.layoutDoc._nativeWidth)) / prevNwidth; + this.layoutDoc._height = (NumCast(this.layoutDoc._height) * NumCast(this.layoutDoc._nativeHeight)) / prevNheight; + } else { + this.layoutDoc._width = Math.max(35, Number(style.width.replace('px', ''))); + this.layoutDoc._height = Math.max(25, Number(style.height.replace('px', ''))); + } } }; render() { diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index f014f842e..f7f94c546 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -21,7 +21,7 @@ export interface FieldViewProps extends DocumentViewSharedProps { select: (isCtrlPressed: boolean) => void; isContentActive: (outsideReaction?: boolean) => boolean | undefined; isDocumentActive?: () => boolean | undefined; - isSelected: (outsideReaction?: boolean) => boolean; + isSelected: () => boolean; setHeight?: (height: number) => void; NativeDimScaling?: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal NOTE: Must also be added to DocumentViewInternalsProps onBrowseClick?: () => ScriptField | undefined; diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx index 7af4d9b59..f6680aac0 100644 --- a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx +++ b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx @@ -48,7 +48,7 @@ export class MapAnchorMenu extends AntimodeMenu { componentDidMount() { this._disposer = reaction( () => SelectionManager.Views().slice(), - selected => MapAnchorMenu.Instance.fadeOut(true) + sel => MapAnchorMenu.Instance.fadeOut(true) ); } // audioDown = (e: React.PointerEvent) => { diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 185c6553a..108fa5ce5 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -195,7 +195,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent this.props.isSelected(), () => { document.removeEventListener('keydown', this.onKeyDown); - this.props.isSelected(true) && document.addEventListener('keydown', this.onKeyDown); + this.props.isSelected() && document.addEventListener('keydown', this.onKeyDown); }, { fireImmediately: true } ); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index a80c1e030..c828297b3 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -315,7 +315,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent this.getAnchor(true), targetCreator), e.pageX, e.pageY); }); const coordsB = this._editorView!.coordsAtPos(this._editorView!.state.selection.to); - this.props.isSelected(true) && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom); + this.props.isSelected() && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom); }; dispatchTransaction = (tx: Transaction) => { @@ -1439,7 +1439,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent self.props.isSelected(true) && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView)); + runInAction(() => self.props.isSelected() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView)); return new RichTextMenuPlugin({ editorProps: this.props }); }, }); @@ -1612,7 +1612,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { FormattedTextBoxComment.textBox = this; - if (e.button === 0 && this.props.isSelected(true) && !e.altKey && !e.ctrlKey && !e.metaKey) { + if (e.button === 0 && this.props.isSelected() && !e.altKey && !e.ctrlKey && !e.metaKey) { if (e.clientX < this.ProseRef!.getBoundingClientRect().right) { // stop propagation if not in sidebar e.stopPropagation(); // if the text box is selected, then it consumes all click events @@ -1660,7 +1660,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { // finds font sizes and families in selection getActiveAlignment() { - if (this.view && this.TextView?.props.isSelected(true)) { + if (this.view && this.TextView?.props.isSelected()) { const path = (this.view.state.selection.$from as any).path; for (let i = path.length - 3; i < path.length && i >= 0; i -= 3) { if (path[i]?.type === this.view.state.schema.nodes.paragraph || path[i]?.type === this.view.state.schema.nodes.heading) { @@ -194,7 +194,7 @@ export class RichTextMenu extends AntimodeMenu { // finds font sizes and families in selection getActiveListStyle() { - if (this.view && this.TextView?.props.isSelected(true)) { + if (this.view && this.TextView?.props.isSelected()) { const path = (this.view.state.selection.$from as any).path; for (let i = 0; i < path.length; i += 3) { if (path[i].type === this.view.state.schema.nodes.ordered_list) { @@ -214,7 +214,7 @@ export class RichTextMenu extends AntimodeMenu { const activeSizes = new Set(); const activeColors = new Set(); const activeHighlights = new Set(); - if (this.view && this.TextView?.props.isSelected(true)) { + if (this.view && this.TextView?.props.isSelected()) { const state = this.view.state; const pos = this.view.state.selection.$from; const marks: Mark[] = [...(state.storedMarks ?? [])]; @@ -249,7 +249,7 @@ export class RichTextMenu extends AntimodeMenu { //finds all active marks on selection in given group getActiveMarksOnSelection() { let activeMarks: MarkType[] = []; - if (!this.view || !this.TextView?.props.isSelected(true)) return activeMarks; + if (!this.view || !this.TextView?.props.isSelected()) return activeMarks; const markGroup = [schema.marks.noAutoLinkAnchor, schema.marks.strong, schema.marks.em, schema.marks.underline, schema.marks.strikethrough, schema.marks.superscript, schema.marks.subscript]; if (this.view.state.storedMarks) return this.view.state.storedMarks.map(mark => mark.type); @@ -286,7 +286,7 @@ export class RichTextMenu extends AntimodeMenu { } destroy() { - !this.TextView?.props.isSelected(true) && this.fadeOut(true); + !this.TextView?.props.isSelected() && this.fadeOut(true); } @action @@ -443,7 +443,7 @@ export class RichTextMenu extends AntimodeMenu { } align = (view: EditorView, dispatch: any, alignment: 'left' | 'right' | 'center') => { - if (this.TextView?.props.isSelected(true)) { + if (this.TextView?.props.isSelected()) { var tr = view.state.tr; view.state.doc.nodesBetween(view.state.selection.from, view.state.selection.to, (node, pos, parent, index) => { if ([schema.nodes.paragraph, schema.nodes.heading].includes(node.type)) { diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx index 18cf633f4..d68859e88 100644 --- a/src/client/views/pdf/AnchorMenu.tsx +++ b/src/client/views/pdf/AnchorMenu.tsx @@ -64,7 +64,7 @@ export class AnchorMenu extends AntimodeMenu { componentDidMount() { this._disposer = reaction( () => SelectionManager.Views().slice(), - selected => AnchorMenu.Instance.fadeOut(true) + sel => AnchorMenu.Instance.fadeOut(true) ); } -- cgit v1.2.3-70-g09d2 From 872dc82886f8111da1bdfd282ac2a78ec3bdc1f6 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 29 Nov 2023 11:55:44 -0500 Subject: cleaned up presElementBox and did more this.rootDoc => this.Document/layoutDoc --- src/client/documents/Documents.ts | 6 +- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/DocComponent.tsx | 8 - src/client/views/InkingStroke.tsx | 24 +- src/client/views/PropertiesView.tsx | 2 +- .../collections/collectionSchema/SchemaRowBox.tsx | 14 +- src/client/views/nodes/ColorBox.tsx | 2 +- src/client/views/nodes/EquationBox.tsx | 10 +- src/client/views/nodes/LabelBox.tsx | 18 +- src/client/views/nodes/LinkAnchorBox.tsx | 20 +- .../views/nodes/RecordingBox/RecordingBox.tsx | 3 +- src/client/views/nodes/WebBox.tsx | 54 ++-- .../views/nodes/formattedText/DashFieldView.tsx | 2 +- .../views/nodes/importBox/ImportElementBox.tsx | 4 +- src/client/views/nodes/trails/PresBox.tsx | 4 + src/client/views/nodes/trails/PresElementBox.tsx | 332 ++++++++++----------- 16 files changed, 242 insertions(+), 263 deletions(-) (limited to 'src/client/views/nodes/EquationBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 4def19384..9107bd6ab 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -168,8 +168,10 @@ type DTYPEt = DTypeInfo | string; export class DocumentOptions { // coordinate and dimensions depending on view x?: NUMt = new NumInfo('x coordinate of document in a freeform view', false); - y?: NUMt = new NumInfo('y coordinage of document in a freeform view', false); + y?: NUMt = new NumInfo('y coordinate of document in a freeform view', false); z?: NUMt = new NumInfo('whether document is in overlay (1) or not (0)', false, false, [1, 0]); + overlayX?: NUMt = new NumInfo('x coordinate of document in a overlay view', false); + overlayY?: NUMt = new NumInfo('y coordinate of document in a overlay view', false); _dimMagnitude?: NUMt = new NumInfo("magnitude of collectionMulti{row,col} element's width or height", false); _dimUnit?: DIMt = new DimInfo("units of collectionMulti{row,col} element's width or height - 'px' or '*' for pixels or relative units"); latitude?: NUMt = new NumInfo('latitude coordinate for map views', false); @@ -198,6 +200,7 @@ export class DocumentOptions { author_date?: DATEt = new DateInfo('date the document was created', true); annotationOn?: DOCt = new DocInfo('document annotated by this document', false); embedContainer?: DOCt = new DocInfo('document that displays (contains) this discument', false); + rootDocument?: DOCt = new DocInfo('document that supplies the information needed for a rendering template (eg, pres slide for PresElement)'); color?: STRt = new StrInfo('foreground color data doc', false); hidden?: BOOLt = new BoolInfo('whether the document is not rendered by its collection', false); backgroundColor?: STRt = new StrInfo('background color for data doc', false); @@ -272,6 +275,7 @@ export class DocumentOptions { icon_label?: STRt = new StrInfo('label to use for a fontIcon doc (otherwise, the title is used)', false); mediaState?: STRt = new StrInfo(`status of audio/video media document: ${media_state.PendingRecording}, ${media_state.Recording}, ${media_state.Paused}, ${media_state.Playing}`, false); recording?: BOOLt = new BoolInfo('whether WebCam is recording or not'); + slides?: DOCt = new DocInfo('presentation slide associated with video recording (bcz: should be renamed!!)'); autoPlayAnchors?: BOOLt = new BoolInfo('whether to play audio/video when an anchor is clicked in a stackedTimeline.'); dontPlayLinkOnSelect?: BOOLt = new BoolInfo('whether an audio/video should start playing when a link is followed to it.'); openFactoryLocation?: string; // an OpenWhere value to place the factory created document diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 2f2ac2a71..80ec1e7bb 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -274,7 +274,7 @@ export class CurrentUserUtils { {key: "Map", creator: opts => Docs.Create.MapDocument([], opts), opts: { _width: 800, _height: 600, _layout_fitWidth: true, }}, {key: "Screengrab", creator: Docs.Create.ScreenshotDocument, opts: { _width: 400, _height: 200 }}, {key: "WebCam", creator: opts => Docs.Create.WebCamDocument("", opts), opts: { _width: 400, _height: 200, recording:true, isSystem: true, cloneFieldFilter: new List(["isSystem"]) }}, - {key: "Button", creator: Docs.Create.ButtonDocument, opts: { _width: 150, _height: 50, _xPadding: 10, _yPadding: 10}, scripts: {onClick: FollowLinkScript()?.script.originalScript ?? ""}}, + {key: "Button", creator: Docs.Create.ButtonDocument, opts: { _width: 150, _height: 50, _xPadding: 10, _yPadding: 10, waitForDoubleClickToClick: 'never'}, scripts: {onClick: FollowLinkScript()?.script.originalScript ?? ""}}, {key: "Script", creator: opts => Docs.Create.ScriptingDocument(null, opts), opts: { _width: 200, _height: 250, }}, {key: "DataViz", creator: opts => Docs.Create.DataVizDocument("/users/rz/Downloads/addresses.csv", opts), opts: { _width: 300, _height: 300 }}, {key: "Header", creator: headerTemplate, opts: { _width: 300, _height: 70, _headerPointerEvents: "all", _headerHeight: 12, _headerFontSize: 9, _layout_autoHeight: true, treeView_HideUnrendered: true}}, diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 61b7a3bff..397ac47ab 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -26,10 +26,6 @@ export function DocComponent

() { @computed get Document() { return this.props.Document; } - // This is the "The Document" -- it encapsulates, data, layout, and any templates - @computed get rootDoc() { - return this.props.Document; - } // This is the rendering data of a document -- it may be "The Document", or it may be some template document that holds the rendering info @computed get layoutDoc() { return this.props.LayoutTemplateString ? this.props.Document : Doc.Layout(this.props.Document, this.props.LayoutTemplate?.()); @@ -63,10 +59,6 @@ export function ViewBoxBaseComponent

() { @computed get Document() { return this.props.Document; } - // This is the "The Document" -- it encapsulates, data, layout, and any templates - @computed get rootDoc() { - return Cast(this.props.Document.rootDocument, Doc, null) || this.props.Document; - } // This is the rendering data of a document -- it may be "The Document", or it may be some template document that holds the rendering info @computed get layoutDoc() { return Doc.Layout(this.props.Document); diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index cf565abc8..e081961e5 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -82,24 +82,24 @@ export class InkingStroke extends ViewBoxBaseComponent() { getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => { const subAnchor = this._subContentView?.getAnchor?.(addAsAnnotation); - if (subAnchor !== this.rootDoc && subAnchor) return subAnchor; + if (subAnchor !== this.Document && subAnchor) return subAnchor; - if (!addAsAnnotation && !pinProps) return this.rootDoc; + if (!addAsAnnotation && !pinProps) return this.Document; const anchor = Docs.Create.ConfigDocument({ - title: 'Ink anchor:' + this.rootDoc.title, + title: 'Ink anchor:' + this.Document.title, // set presentation timing for restoring shape presentation_duration: 1100, presentation_transition: 1000, - annotationOn: this.rootDoc, + annotationOn: this.Document, }); if (anchor) { anchor.backgroundColor = 'transparent'; // /* addAsAnnotation &&*/ this.addDocument(anchor); - PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), inkable: true } }, this.rootDoc); + PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), inkable: true } }, this.Document); return anchor; } - return this.rootDoc; + return this.Document; }; /** @@ -245,8 +245,8 @@ export class InkingStroke extends ViewBoxBaseComponent() { * factor for converting between ink and screen space. */ inkScaledData = () => { - const inkData = Cast(this.rootDoc[this.fieldKey], InkField)?.inkData ?? []; - const inkStrokeWidth = NumCast(this.rootDoc.stroke_width, 1); + const inkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? []; + const inkStrokeWidth = NumCast(this.layoutDoc.stroke_width, 1); const inkTop = Math.min(...inkData.map(p => p.Y)) - inkStrokeWidth / 2; const inkBottom = Math.max(...inkData.map(p => p.Y)) + inkStrokeWidth / 2; const inkLeft = Math.min(...inkData.map(p => p.X)) - inkStrokeWidth / 2; @@ -362,7 +362,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { setSubContentView = (doc: DocComponentView) => (this._subContentView = doc); @computed get fillColor() { const isInkMask = BoolCast(this.layoutDoc.stroke_isInkMask); - return isInkMask ? DashColor(StrCast(this.layoutDoc.fillColor, 'transparent')).blacken(0).rgb().toString() : this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.FillColor) ?? 'transparent'; + return isInkMask ? DashColor(StrCast(this.layoutDoc.fillColor, 'transparent')).blacken(0).rgb().toString() : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.FillColor) ?? 'transparent'; } @computed get strokeColor() { const { inkData } = this.inkScaledData(); @@ -387,7 +387,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { this.layoutDoc._height = Math.round(NumCast(this.layoutDoc._height)); }); } - const highlight = !this.controlUndo && this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Highlighting); + const highlight = !this.controlUndo && this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Highlighting); const highlightIndex = highlight?.highlightIndex; const highlightColor = !this.props.isSelected() && !isInkMask && highlight?.highlightIndex ? highlight?.highlightColor : undefined; const color = StrCast(this.layoutDoc.stroke_outlineColor, !closed && fillColor && fillColor !== 'transparent' ? StrCast(this.layoutDoc.color, 'transparent') : 'transparent'); @@ -457,7 +457,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { onContextMenu: () => { const cm = ContextMenu.Instance; !Doc.noviceMode && cm?.addItem({ description: 'Recognize Writing', event: this.analyzeStrokes, icon: 'paint-brush' }); - cm?.addItem({ description: 'Toggle Mask', event: () => InkingStroke.toggleMask(this.rootDoc), icon: 'paint-brush' }); + cm?.addItem({ description: 'Toggle Mask', event: () => InkingStroke.toggleMask(this.dataDoc), icon: 'paint-brush' }); cm?.addItem({ description: 'Edit Points', event: action(() => (InkStrokeProperties.Instance._controlButton = !InkStrokeProperties.Instance._controlButton)), icon: 'paint-brush' }); }, }; @@ -474,7 +474,7 @@ export class InkingStroke extends ViewBoxBaseComponent() { {clickableLine(this.onPointerDown, isInkMask)} {isInkMask ? null : inkLine} - {!closed || (!RTFCast(this.rootDoc.text)?.Text && (!this.props.isSelected() || Doc.UserDoc().activeInkHideTextLabels)) ? null : ( + {!closed || (!RTFCast(this.dataDoc.text)?.Text && (!this.props.isSelected() || Doc.UserDoc().activeInkHideTextLabels)) ? null : (

{ } @computed get selectedDocumentView() { if (SelectionManager.Views().length) return SelectionManager.Views()[0]; - if (PresBox.Instance?.selectedArray.size) return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc); + if (PresBox.Instance?.selectedArray.size) return DocumentManager.Instance.getDocumentView(PresBox.Instance.Document); return undefined; } @computed get isPres(): boolean { diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx index 7346c4f12..03697b40a 100644 --- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx +++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx @@ -38,11 +38,11 @@ export class SchemaRowBox extends ViewBoxBaseComponent { if (!this.schemaView) return; const lastSelected = Array.from(this.schemaView._selectedDocs).lastElement(); - if (shiftKey && lastSelected) this.schemaView.selectRows(this.rootDoc, lastSelected); + if (shiftKey && lastSelected) this.schemaView.selectRows(this.Document, lastSelected); else { this.props.select?.(ctrlKey); } @@ -107,7 +107,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent { - row && this.schemaView?.addRowRef?.(this.rootDoc, row); + row && this.schemaView?.addRowRef?.(this.Document, row); this._ref = row; }}>
{ e.stopPropagation(); - this.props.removeDocument?.(this.rootDoc); + this.props.removeDocument?.(this.Document); }, 'Delete Row') ) } @@ -145,7 +145,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent { e.stopPropagation(); - this.props.addDocTab(this.rootDoc, OpenWhere.addRight); + this.props.addDocTab(this.Document, OpenWhere.addRight); }, 'Open schema Doc preview') ) } @@ -155,7 +155,7 @@ export class SchemaRowBox extends ViewBoxBaseComponent ( () { } render() { - const scaling = Math.min(this.layoutDoc.layout_fitWidth ? 10000 : this.props.PanelHeight() / NumCast(this.rootDoc._height), this.props.PanelWidth() / NumCast(this.rootDoc._width)); + const scaling = Math.min(this.layoutDoc.layout_fitWidth ? 10000 : this.props.PanelHeight() / NumCast(this.Document._height), this.props.PanelWidth() / NumCast(this.Document._width)); return (
() { _ref: React.RefObject = React.createRef(); componentDidMount() { this.props.setContentView?.(this); - if (EquationBox.SelectOnLoad === this.rootDoc[Id] && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.props.docViewPath()))) { + if (EquationBox.SelectOnLoad === this.Document[Id] && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.props.docViewPath()))) { this.props.select(false); this._ref.current!.mathField.focus(); - this.rootDoc.text === 'x' && this._ref.current!.mathField.select(); + this.dataDoc.text === 'x' && this._ref.current!.mathField.select(); EquationBox.SelectOnLoad = ''; } reaction( @@ -66,7 +66,7 @@ export class EquationBox extends ViewBoxBaseComponent() { e.stopPropagation(); } if (e.key === 'Tab') { - const graph = Docs.Create.FunctionPlotDocument([this.rootDoc], { + const graph = Docs.Create.FunctionPlotDocument([this.Document], { x: NumCast(this.layoutDoc.x) + NumCast(this.layoutDoc._width), y: NumCast(this.layoutDoc.y), _width: 400, @@ -76,7 +76,7 @@ export class EquationBox extends ViewBoxBaseComponent() { this.props.addDocument?.(graph); e.stopPropagation(); } - if (e.key === 'Backspace' && !this.dataDoc.text) this.props.removeDocument?.(this.rootDoc); + if (e.key === 'Backspace' && !this.dataDoc.text) this.props.removeDocument?.(this.Document); }; @undoBatch onChange = (str: string) => (this.dataDoc.text = str); @@ -111,7 +111,7 @@ export class EquationBox extends ViewBoxBaseComponent() { width: 'fit-content', // `${100 / scale}%`, height: `${100 / scale}%`, pointerEvents: !this.props.isSelected() ? 'none' : undefined, - fontSize: StrCast(this.rootDoc._text_fontSize), + fontSize: StrCast(this.layoutDoc._text_fontSize), }} onKeyDown={e => e.stopPropagation()}> diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index 4439be0cd..0d7b2b0a4 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -37,7 +37,7 @@ export class LabelBox extends ViewBoxBaseComponent { @@ -81,16 +81,16 @@ export class LabelBox extends ViewBoxBaseComponent { - const singleLine = BoolCast(this.rootDoc._singleLine, true); + const singleLine = BoolCast(this.layoutDoc._singleLine, true); const params = { rotateText: null, fontSizeFactor: 1, - minimumFontSize: NumCast(this.rootDoc._label_minFontSize, 8), - maximumFontSize: NumCast(this.rootDoc._label_maxFontSize, 1000), + minimumFontSize: NumCast(this.layoutDoc._label_minFontSize, 8), + maximumFontSize: NumCast(this.layoutDoc._label_maxFontSize, 1000), limitingDimension: 'both', horizontalAlign: 'center', verticalAlign: 'center', @@ -137,10 +137,10 @@ export class LabelBox extends ViewBoxBaseComponent() { } @computed get linkSource() { - return this.props.docViewPath()[this.props.docViewPath().length - 2].rootDoc; // this.props.styleProvider?.(this.dataDoc, this.props, StyleProp.LinkSource); + return this.props.docViewPath()[this.props.docViewPath().length - 2].Document; // this.props.styleProvider?.(this.dataDoc, this.props, StyleProp.LinkSource); } onPointerDown = (e: React.PointerEvent) => { setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, (e, doubleTap) => { - if (doubleTap) LinkFollower.FollowLink(this.rootDoc, this.linkSource, false); + if (doubleTap) LinkFollower.FollowLink(this.Document, this.linkSource, false); else this.props.select(false); }); }; @@ -49,15 +49,15 @@ export class LinkAnchorBox extends ViewBoxBaseComponent() { const pt = Utils.getNearestPointInPerimeter(bounds.left, bounds.top, bounds.width, bounds.height, e.clientX, e.clientY); const separation = Math.sqrt((pt[0] - e.clientX) * (pt[0] - e.clientX) + (pt[1] - e.clientY) * (pt[1] - e.clientY)); if (separation > 100) { - const dragData = new DragManager.DocumentDragData([this.rootDoc]); + const dragData = new DragManager.DocumentDragData([this.Document]); dragData.dropAction = 'embed'; dragData.dropPropertiesToRemove = ['link_anchor_1_x', 'link_anchor_1_y', 'link_anchor_2_x', 'link_anchor_2_y', 'onClick']; DragManager.StartDocumentDrag([this._ref.current!], dragData, pt[0], pt[1]); return true; } else { - this.rootDoc[this.fieldKey + '_x'] = ((pt[0] - bounds.left) / bounds.width) * 100; - this.rootDoc[this.fieldKey + '_y'] = ((pt[1] - bounds.top) / bounds.height) * 100; - this.rootDoc.link_autoMoveAnchors = false; + this.layoutDoc[this.fieldKey + '_x'] = ((pt[0] - bounds.left) / bounds.width) * 100; + this.layoutDoc[this.fieldKey + '_y'] = ((pt[1] - bounds.top) / bounds.height) * 100; + this.layoutDoc.link_autoMoveAnchors = false; } } return false; @@ -68,8 +68,8 @@ export class LinkAnchorBox extends ViewBoxBaseComponent() { render() { TraceMobx(); const small = this.props.PanelWidth() <= 1; // this happens when rendered in a treeView - const x = NumCast(this.rootDoc[this.fieldKey + '_x'], 100); - const y = NumCast(this.rootDoc[this.fieldKey + '_y'], 100); + const x = NumCast(this.layoutDoc[this.fieldKey + '_x'], 100); + const y = NumCast(this.layoutDoc[this.fieldKey + '_y'], 100); const background = this.props.styleProvider?.(this.dataDoc, this.props, StyleProp.BackgroundColor + ':anchor'); const anchor = this.fieldKey === 'link_anchor_1' ? 'link_anchor_2' : 'link_anchor_1'; const anchorScale = !this.dataDoc[this.fieldKey + '_useSmallAnchor'] && (x === 0 || x === 100 || y === 0 || y === 100) ? 1 : 0.25; @@ -88,7 +88,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent() { LinkDocPreview.SetLinkInfo({ docProps: this.props, linkSrc: this.linkSource, - linkDoc: this.rootDoc, + linkDoc: this.Document, showHeader: true, location: [e.clientX, e.clientY + 20], noPreview: false, @@ -97,7 +97,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent() { onPointerDown={this.onPointerDown} onContextMenu={this.specificContextMenu} style={{ - border: selView && this.rootDoc[selView] === this.rootDoc[this.fieldKey] ? `solid ${globalCssVariables.MEDIUM_GRAY} 2px` : undefined, + border: selView && this.dataDoc[selView] === this.dataDoc[this.fieldKey] ? `solid ${globalCssVariables.MEDIUM_GRAY} 2px` : undefined, background, left: `calc(${x}% - ${small ? 2.5 : 7.5}px)`, top: `calc(${y}% - ${small ? 2.5 : 7.5}px)`, diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 3838ce4ee..f01642236 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -13,7 +13,6 @@ import { DocumentType } from '../../../documents/DocumentTypes'; import { DocumentManager } from '../../../util/DocumentManager'; import { DragManager } from '../../../util/DragManager'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; -import { SelectionManager } from '../../../util/SelectionManager'; import { Presentation } from '../../../util/TrackMovements'; import { undoBatch } from '../../../util/UndoManager'; import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView'; @@ -193,7 +192,7 @@ export class RecordingBox extends ViewBoxBaseComponent() { render() { return ( -
+
{!this.result && ( a.text_inlineAnnotations); } @computed get webField() { - return Cast(this.rootDoc[this.props.fieldKey], WebField)?.url; + return Cast(this.Document[this.props.fieldKey], WebField)?.url; } constructor(props: any) { @@ -145,7 +145,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { if (data_url.includes(' setTimeout( action(() => { - this.rootDoc.thumbLockout = false; + this.Document.thumbLockout = false; this.layoutDoc.thumb = new ImageField(returnedfilename); this.layoutDoc.thumbScrollTop = scrollTop; this.layoutDoc.thumbNativeWidth = nativeWidth; @@ -185,11 +185,11 @@ export class WebBox extends ViewBoxAnnotatableComponent WebCast(this.rootDoc.data), + () => WebCast(this.dataDoc.data), url => this.submitURL(false, false) ); this._disposers.titling = reaction( - () => StrCast(this.rootDoc.title), + () => StrCast(this.Document.title), url => { url.startsWith('www') && this.setData('http://' + url); url.startsWith('http') && this.setData(url); @@ -251,7 +251,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { if (this._mainCont.current && selRange) { - if (this.rootDoc[this.props.fieldKey] instanceof HtmlField) this._mainCont.current.style.transform = `rotate(${NumCast(this.props.DocumentView!().screenToLocalTransform().RotateDeg)}deg)`; + if (this.dataDoc[this.props.fieldKey] instanceof HtmlField) this._mainCont.current.style.transform = `rotate(${NumCast(this.props.DocumentView!().screenToLocalTransform().RotateDeg)}deg)`; const clientRects = selRange.getClientRects(); for (let i = 0; i < clientRects.length; i++) { const rect = clientRects.item(i); @@ -281,7 +281,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { - if (anchor !== this.rootDoc && this._outerRef.current) { + if (anchor !== this.Document && this._outerRef.current) { const windowHeight = this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1); const scrollTo = Utils.scrollIntoView(NumCast(anchor.y), NumCast(anchor._height), NumCast(this.layoutDoc._layout_scrollTop), windowHeight, windowHeight * 0.1, Math.max(NumCast(anchor.y) + NumCast(anchor._height), this._scrollHeight)); if (scrollTo !== undefined) { @@ -298,8 +298,8 @@ export class WebBox extends ViewBoxAnnotatableComponent { - if (Doc.AreProtosEqual(doc, this.rootDoc)) return new Promise>(res => res(this.props.DocumentView?.())); - if (this.rootDoc.layout_fieldKey === 'layout_icon') this.props.DocumentView?.().iconify(); + if (Doc.AreProtosEqual(doc, this.Document)) return new Promise>(res => res(this.props.DocumentView?.())); + if (this.Document.layout_fieldKey === 'layout_icon') this.props.DocumentView?.().iconify(); const webUrl = WebCast(doc.config_data)?.url; if (this._url && webUrl && webUrl.href !== this._url) this.setData(webUrl.href); if (this._sidebarRef?.current?.makeDocUnfiltered(doc) && !this.SidebarShown) this.toggleSidebar(false); @@ -326,11 +326,11 @@ export class WebBox extends ViewBoxAnnotatableComponent { this.props.select(false); const locpt = { - x: (e.clientX / NumCast(this.rootDoc.nativeWidth)) * this.props.PanelWidth(), - y: ((e.clientY - NumCast(this.rootDoc.layout_scrollTop))/ NumCast(this.rootDoc.nativeHeight)) * this.props.PanelHeight() }; // prettier-ignore + x: (e.clientX / NumCast(this.Document.nativeWidth)) * this.props.PanelWidth(), + y: ((e.clientY - NumCast(this.layoutDoc.layout_scrollTop))/ NumCast(this.Document.nativeHeight)) * this.props.PanelHeight() }; // prettier-ignore const scrclick = this.props.DocumentView?.().props.ScreenToLocalTransform().inverse().transformPoint(locpt.x, locpt.y)!; const scrcent = this.props .DocumentView?.() .props.ScreenToLocalTransform() .inverse() - .transformPoint(NumCast(this.rootDoc.width) / 2, NumCast(this.rootDoc.height) / 2)!; + .transformPoint(NumCast(this.Document.width) / 2, NumCast(this.Document.height) / 2)!; const theclickoff = Utils.rotPt(scrclick[0] - scrcent[0], scrclick[1] - scrcent[1], -this.props.ScreenToLocalTransform().Rotate); const theclick = [theclickoff.x + scrcent[0], theclickoff.y + scrcent[1]]; MarqueeAnnotator.clearAnnotations(this._savedAnnotations); @@ -488,15 +488,15 @@ export class WebBox extends ViewBoxAnnotatableComponent { this._scrollHeight = Math.max(this._scrollHeight, iframeContent.body.scrollHeight || 0); if (this._scrollHeight) { - this.rootDoc.nativeHeight = Math.min(NumCast(this.rootDoc.nativeHeight), this._scrollHeight); + this.Document.nativeHeight = Math.min(NumCast(this.Document.nativeHeight), this._scrollHeight); this.layoutDoc.height = Math.min(NumCast(this.layoutDoc._height), (NumCast(this.layoutDoc._width) * NumCast(this.rootDoc.nativeHeight)) / NumCast(this.rootDoc.nativeWidth)); } }; const swidth = Math.max(NumCast(this.layoutDoc.nativeWidth), iframeContent.body.scrollWidth || 0); if (swidth) { - const aspectResize = swidth / NumCast(this.rootDoc.nativeWidth); - this.rootDoc.nativeWidth = swidth; - this.rootDoc.nativeHeight = NumCast(this.rootDoc.nativeHeight) * aspectResize; + const aspectResize = swidth / NumCast(this.Document.nativeWidth); + this.Document.nativeWidth = swidth; + this.Document.nativeHeight = NumCast(this.Document.nativeHeight) * aspectResize; this.layoutDoc.height = NumCast(this.layoutDoc._height) * aspectResize; } initHeights(); @@ -586,8 +586,8 @@ export class WebBox extends ViewBoxAnnotatableComponent { - const future = Cast(this.rootDoc[this.fieldKey + '_future'], listSpec('string'), []); - const history = Cast(this.rootDoc[this.fieldKey + '_history'], listSpec('string'), []); + const future = Cast(this.dataDoc[this.fieldKey + '_future'], listSpec('string'), []); + const history = Cast(this.dataDoc[this.fieldKey + '_history'], listSpec('string'), []); if (checkAvailable) return future.length; runInAction(() => { if (future.length) { @@ -760,7 +760,7 @@ export class WebBox extends ViewBoxAnnotatableComponent { var nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']); if (!nativeWidth) { - const defaultNativeWidth = NumCast(this.rootDoc.nativeWidth, this.rootDoc[this.fieldKey] instanceof WebField ? 850 : NumCast(this.Document._width)); + const defaultNativeWidth = NumCast(this.Document.nativeWidth, this.dataDoc[this.fieldKey] instanceof WebField ? 850 : NumCast(this.Document._width)); Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(this.dataDoc) || defaultNativeWidth); Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(this.dataDoc) || (NumCast(this.Document._height) / NumCast(this.Document._width)) * defaultNativeWidth); nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']); @@ -1096,7 +1096,7 @@ export class WebBox extends ViewBoxAnnotatableComponent -
+
dashDoc instanceof Doc && (this._dashDoc = dashDoc))); } else { - this._dashDoc = this.props.tbox.rootDoc; + this._dashDoc = this.props.tbox.Document; } } componentWillUnmount() { diff --git a/src/client/views/nodes/importBox/ImportElementBox.tsx b/src/client/views/nodes/importBox/ImportElementBox.tsx index 58f0b29e4..170626cd2 100644 --- a/src/client/views/nodes/importBox/ImportElementBox.tsx +++ b/src/client/views/nodes/importBox/ImportElementBox.tsx @@ -22,7 +22,7 @@ export class ImportElementBox extends ViewBoxBaseComponent() { () { ); } render() { - return !(this.rootDoc instanceof Doc) ? null : this.mainItem; + return !(this.Document instanceof Doc) ? null : this.mainItem; } } diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index bb0ed0943..71c585c38 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -36,6 +36,7 @@ import { FieldView, FieldViewProps } from '../FieldView'; import { ScriptingBox } from '../ScriptingBox'; import './PresBox.scss'; import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './PresEnums'; +import _ = require('lodash'); const { Howl } = require('howler'); export interface pinDataTypes { @@ -1075,6 +1076,7 @@ export class PresBox extends ViewBoxBaseComponent() { }); return true; }; + childLayoutTemplate = () => Docs.Create.PresElementBoxDocument(); removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.Document, this.fieldKey, doc); getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65); // listBox padding-left and pres-box-cont minHeight @@ -2549,6 +2551,8 @@ export class PresBox extends ViewBoxBaseComponent() { } }; + SlideIndex = (slideDoc: Doc) => DocListCast(this.dataDoc[this.presFieldKey]).indexOf(slideDoc); + RemFromMap = (treeViewDoc: Doc, index: number[]) => { if (!treeViewDoc.presentation_targetDoc) return this.childDocs; // if treeViewDoc is not a pres elements, then it's a sub-bullet of a progressivized slide which isn't added to the linearized list of pres elements since it's not really a pres element. if (!this._unmounting && this.isTree) { diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index f5faeb611..6a8edee0d 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -34,37 +34,53 @@ export class PresElementBox extends ViewBoxBaseComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresElementBox, fieldKey); } - _heightDisposer: IReactionDisposer | undefined; + private _itemRef: React.RefObject = React.createRef(); + private _dragRef: React.RefObject = React.createRef(); + private _titleRef: React.RefObject = React.createRef(); + private _heightDisposer: IReactionDisposer | undefined; + readonly expandViewHeight = 100; + readonly collapsedHeight = 35; @observable _dragging = false; - // Idea: this boolean will determine whether to automatically show the video when this preselement is selected. - // @observable static showVideo: boolean = false; - @computed get indexInPres() { - return DocListCast(this.presBox?.[StrCast(this.presBox.presFieldKey, 'data')]).indexOf(this.rootDoc); - } // the index field is where this document is in the presBox display list (since this value is different for each presentation element, the value can't be stored on the layout template which is used by all display elements) - @computed get expandViewHeight() { - return 100; - } - @computed get collapsedHeight() { - return 35; - } // the collapsed height changes depending on the state of the presBox. We could store this on the presentation element template if it's used by only one presentation - but if it's shared by multiple, then this value must be looked up - @computed get selectedArray() { - return this.presBoxView?.selectedArray; - } + + // the presentation view that renders this slide @computed get presBoxView() { return this.props.DocumentView?.()?.props.docViewPath().lastElement()?.ComponentView as PresBox; } + + // the presentation view document that renders this slide @computed get presBox() { - return this.props.DocumentView?.().props.docViewPath().lastElement()?.Document; + return this.presBoxView?.Document; } + + // Since this node is being rendered with a template, this method retrieves + // the actual slide being rendered from the auto-generated rendering template + @computed get slideDoc() { + return Cast(this.Document.rootDocument, Doc, null) || this.props.Document; + } + + // this is the document in the workspaces that is targeted by the slide @computed get targetDoc() { - return Cast(this.rootDoc.presentation_targetDoc, Doc, null) || this.rootDoc; + return Cast(this.slideDoc.presentation_targetDoc, Doc, null) || this.slideDoc; + } + + // computes index of this presentation slide in the presBox list + @computed get indexInPres() { + return this.presBoxView?.SlideIndex(this.slideDoc); + } + + @computed get selectedArray() { + return this.presBoxView?.selectedArray; + } + + @computed get videoRecordingIsInOverlay() { + return Doc.MyOverlayDocs.some(doc => doc.slides === this.slideDoc); } componentDidMount() { this.layoutDoc.layout_hideLinkButton = true; this._heightDisposer = reaction( - () => ({ expand: this.rootDoc.presentation_expandInlineButton, height: this.collapsedHeight }), + () => ({ expand: this.slideDoc.presentation_expandInlineButton, height: this.collapsedHeight }), ({ expand, height }) => (this.layoutDoc._height = height + (expand ? this.expandViewHeight : 0)), { fireImmediately: true } ); @@ -73,31 +89,21 @@ export class PresElementBox extends ViewBoxBaseComponent() { this._heightDisposer?.(); } - /** - * Returns a local transformed coordinate array for given coordinates. - */ - ScreenToLocalListTransform = (xCord: number, yCord: number) => [xCord, yCord]; - - @action - presExpandDocumentClick = () => (this.rootDoc.presentation_expandInlineButton = !this.rootDoc.presentation_expandInlineButton); - - embedHeight = (): number => this.collapsedHeight + this.expandViewHeight; - // embedWidth = () => this.props.PanelWidth(); - // embedHeight = () => Math.min(this.props.PanelWidth() - 20, this.props.PanelHeight() - this.collapsedHeight); - embedWidth = (): number => this.props.PanelWidth() / 2; + presExpandDocumentClick = () => (this.slideDoc.presentation_expandInlineButton = !this.slideDoc.presentation_expandInlineButton); + embedHeight = () => this.collapsedHeight + this.expandViewHeight; + embedWidth = () => this.props.PanelWidth() / 2; styleProvider = (doc: Doc | undefined, props: Opt, property: string): any => { - if (property === StyleProp.Opacity) return 1; - return this.props.styleProvider?.(doc, props, property); + return property === StyleProp.Opacity ? 1 : this.props.styleProvider?.(doc, props, property); }; /** * The function that is responsible for rendering a preview or not for this * presentation element. */ @computed get renderEmbeddedInline() { - return !this.rootDoc.presentation_expandInlineButton || !this.targetDoc ? null : ( + return !this.slideDoc.presentation_expandInlineButton || !this.targetDoc ? null : (
() { pinToPres={returnFalse} bringToFront={returnFalse} /> - {/*
*/}
); } @@ -158,26 +163,22 @@ export class PresElementBox extends ViewBoxBaseComponent() { @computed get transition() { let transitionInS: number; - if (this.rootDoc.presentation_transition) transitionInS = NumCast(this.rootDoc.presentation_transition) / 1000; + if (this.slideDoc.presentation_transition) transitionInS = NumCast(this.slideDoc.presentation_transition) / 1000; else transitionInS = 0.5; - return this.rootDoc.presentation_movement === PresMovement.Jump || this.rootDoc.presentation_movement === PresMovement.None ? null : 'M: ' + transitionInS + 's'; + return this.slideDoc.presentation_movement === PresMovement.Jump || this.slideDoc.presentation_movement === PresMovement.None ? null : 'M: ' + transitionInS + 's'; } - private _itemRef: React.RefObject = React.createRef(); - private _dragRef: React.RefObject = React.createRef(); - private _titleRef: React.RefObject = React.createRef(); - @action headerDown = (e: React.PointerEvent) => { const element = e.target as any; e.stopPropagation(); e.preventDefault(); if (element && !(e.ctrlKey || e.metaKey || e.button === 2)) { - this.presBoxView?.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, true, false); + this.presBoxView?.regularSelect(this.slideDoc, this._itemRef.current!, this._dragRef.current!, true, false); setupMoveUpEvents(this, e, this.startDrag, emptyFunction, e => { e.stopPropagation(); e.preventDefault(); - this.presBoxView?.modifierSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, e.shiftKey || e.ctrlKey || e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey); + this.presBoxView?.modifierSelect(this.slideDoc, this._itemRef.current!, this._dragRef.current!, e.shiftKey || e.ctrlKey || e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey); this.presBoxView?.activeItem && this.showRecording(this.presBoxView?.activeItem); }); } @@ -188,10 +189,10 @@ export class PresElementBox extends ViewBoxBaseComponent() { */ startDrag = (e: PointerEvent) => { const miniView: boolean = this.toolbarWidth <= 100; - const activeItem = this.rootDoc; + const activeItem = this.slideDoc; const dragArray = this.presBoxView?._dragArray ?? []; const dragData = new DragManager.DocumentDragData(this.presBoxView?.sortArray() ?? []); - if (!dragData.draggedDocuments.length) dragData.draggedDocuments.push(this.rootDoc); + if (!dragData.draggedDocuments.length) dragData.draggedDocuments.push(this.slideDoc); dragData.treeViewDoc = this.presBox?._type_collection === CollectionViewType.Tree ? this.presBox : undefined; // this.props.DocumentView?.()?.props.treeViewDoc; dragData.moveDocument = this.props.moveDocument; const dragItem: HTMLElement[] = []; @@ -237,7 +238,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { }; onPointerMove = (e: PointerEvent) => { - const slide = this._itemRef.current!; + const slide = this._itemRef.current; const dragIsPresItem = DragManager.docsBeingDragged.some(d => d.presentation_targetDoc); if (slide && dragIsPresItem) { const rect = slide.getBoundingClientRect(); @@ -256,35 +257,42 @@ export class PresElementBox extends ViewBoxBaseComponent() { }; onPointerLeave = (e: any) => { - this._itemRef.current!.style.borderTop = '0px'; - this._itemRef.current!.style.borderBottom = '0px'; + const slide = this._itemRef.current; + if (slide) { + slide.style.borderTop = '0px'; + slide.style.borderBottom = '0px'; + } document.removeEventListener('pointermove', this.onPointerMove); }; @action toggleProperties = () => { if (SettingsManager.propertiesWidth < 5) { - action(() => (SettingsManager.propertiesWidth = 250)); + SettingsManager.propertiesWidth = 250; } }; - removePresentationItem = undoable((e: React.MouseEvent) => { - e.stopPropagation(); - if (this.presBox && this.indexInPres < (this.presBoxView?.itemIndex || 0)) { - runInAction(() => (this.presBox!.itemIndex = (this.presBoxView?.itemIndex || 0) - 1)); - } - this.props.removeDocument?.(this.rootDoc); - this.presBoxView?.removeFromSelectedArray(this.rootDoc); - this.removeAllRecordingInOverlay(); - }, 'Remove doc from pres trail'); - - // set the value/title of the individual pres element - @undoBatch - @action - onSetValue = (value: string) => { - this.rootDoc.title = !value.trim().length ? '-untitled-' : value; - return true; - }; + removePresentationItem = undoable( + action((e: React.MouseEvent) => { + e.stopPropagation(); + if (this.presBox && this.indexInPres < (this.presBoxView?.itemIndex || 0)) { + this.presBox.itemIndex = (this.presBoxView?.itemIndex || 0) - 1; + } + this.props.removeDocument?.(this.slideDoc); + this.presBoxView?.removeFromSelectedArray(this.slideDoc); + this.removeAllRecordingInOverlay(); + }), + 'Remove doc from pres trail' + ); + + // set title of the individual pres slide + onSetValue = undoable( + action((value: string) => { + this.slideDoc.title = !value.trim().length ? '-untitled-' : value; + return true; + }), + 'set title of pres element' + ); /** * Method called for updating the view of the currently selected document @@ -305,128 +313,100 @@ export class PresElementBox extends ViewBoxBaseComponent() { // activeItem.config_pinLayout = true; }; - //wait i dont think i have to do anything here since by default it'll revert to the previously saved if I don't save - //so basically, don't have an onClick for this, just let it do nada for now - @undoBatch - @action - revertToPreviouslySaved = (presTargetDoc: Doc, activeItem: Doc) => { - const target = DocCast(activeItem.annotationOn) ?? activeItem; - PresBox.reversePin(activeItem, target); - }; - /** * Method called for updating the view of the currently selected document * * @param presTargetDoc * @param activeItem */ - @undoBatch - @action - updateCapturedViewContents = (presTargetDoc: Doc, activeItem: Doc) => { - const target = DocCast(presTargetDoc.annotationOn) ?? presTargetDoc; - PresBox.pinDocView(activeItem, { pinData: PresBox.pinDataTypes(target) }, target); - }; - - @computed get recordingIsInOverlay() { - return Doc.MyOverlayDocs.some(doc => doc.slides === this.rootDoc); - } + updateCapturedViewContents = undoable( + action((presTargetDoc: Doc, activeItem: Doc) => { + const target = DocCast(presTargetDoc.annotationOn) ?? presTargetDoc; + PresBox.pinDocView(activeItem, { pinData: PresBox.pinDataTypes(target) }, target); + }), + 'updated captured view contents' + ); // a previously recorded video will have timecode defined - static videoIsRecorded = (activeItem: Opt) => { - const casted = Cast(activeItem?.recording, Doc, null); - return casted && 'layout_currentTimecode' in casted; - }; + static videoIsRecorded = (activeItem: Opt) => 'layout_currentTimecode' in (DocCast(activeItem?.recording) ?? {}); - removeAllRecordingInOverlay = () => { - Doc.MyOverlayDocs.filter(doc => doc.slides === this.rootDoc).forEach(Doc.RemFromMyOverlay); - }; + removeAllRecordingInOverlay = () => Doc.MyOverlayDocs.filter(doc => doc.slides === this.slideDoc).forEach(Doc.RemFromMyOverlay); + /// remove all videos that have been recorded from overlay (leave videso that are being recorded to avoid losing data) static removeEveryExistingRecordingInOverlay = () => { - // Remove every recording that already exists in overlay view - Doc.MyOverlayDocs.forEach(doc => { - if (doc.slides !== null) { - // if it's a recording video, don't remove from overlay (user can lose data) - if (PresElementBox.videoIsRecorded(DocCast(doc.slides))) { - Doc.RemFromMyOverlay(doc); - } - } - }); - }; - - @undoBatch - @action - hideRecording = (e: React.MouseEvent, iconClick: boolean = false) => { - e.stopPropagation(); - this.removeAllRecordingInOverlay(); - // if (iconClick) PresElementBox.showVideo = false; - }; - - @undoBatch - @action - showRecording = (activeItem: Doc, iconClick: boolean = false) => { - // remove the overlays on switch *IF* not opened from the specific icon - if (!iconClick) PresElementBox.removeEveryExistingRecordingInOverlay(); - - if (activeItem.recording) { - Doc.AddToMyOverlay(DocCast(activeItem.recording)); - } + Doc.MyOverlayDocs.filter(doc => doc.slides !== null && PresElementBox.videoIsRecorded(DocCast(doc.slides))) // + .forEach(Doc.RemFromMyOverlay); }; - @undoBatch - @action - startRecording = (e: React.MouseEvent, activeItem: Doc) => { - e.stopPropagation(); - if (PresElementBox.videoIsRecorded(activeItem)) { - // if we already have an existing recording - this.showRecording(activeItem, true); - // // if we already have an existing recording - // Doc.AddToMyOverlay(Cast(activeItem.recording, Doc, null)); - } else { - // Remove every recording that already exists in overlay view - // this is a design decision to clear to focus in on the recoding mode - PresElementBox.removeEveryExistingRecordingInOverlay(); - - // if we dont have any recording - const recording = Docs.Create.WebCamDocument('', { - _width: 384, - _height: 216, - layout_hideDocumentButtonBar: true, - layout_hideDecorationTitle: true, - layout_hideOpenButton: true, - // hideDeleteButton: true, - cloneFieldFilter: new List(['isSystem']), - }); - - // attach the recording to the slide, and attach the slide to the recording - recording.slides = activeItem; - activeItem.recording = recording; - - // make recording box appear in the bottom right corner of the screen - recording.overlayX = window.innerWidth - NumCast(recording._width) - 20; - recording.overlayY = window.innerHeight - NumCast(recording._height) - 20; - Doc.AddToMyOverlay(recording); - } - }; + hideRecording = undoable( + action((e: React.MouseEvent, iconClick: boolean = false) => { + e.stopPropagation(); + this.removeAllRecordingInOverlay(); + }), + 'hide video recording' + ); + + showRecording = undoable( + action((activeItem: Doc, iconClick: boolean = false) => { + // remove the overlays on switch *IF* not opened from the specific icon + if (!iconClick) PresElementBox.removeEveryExistingRecordingInOverlay(); + + activeItem.recording && Doc.AddToMyOverlay(DocCast(activeItem.recording)); + }), + 'show video recording' + ); + + startRecording = undoable( + action((e: React.MouseEvent, activeItem: Doc) => { + e.stopPropagation(); + if (PresElementBox.videoIsRecorded(activeItem)) { + // if we already have an existing recording + this.showRecording(activeItem, true); + // // if we already have an existing recording + // Doc.AddToMyOverlay(Cast(activeItem.recording, Doc, null)); + } else { + // we dont have any recording + // Remove every recording that already exists in overlay view + // this is a design decision to clear to focus in on the recoding mode + PresElementBox.removeEveryExistingRecordingInOverlay(); + + // create and add a recording to the slide + // make recording box appear in the bottom right corner of the screen + Doc.AddToMyOverlay( + (activeItem.recording = Docs.Create.WebCamDocument('', { + _width: 384, + _height: 216, + overlayX: window.innerWidth - 384 - 20, + overlayY: window.innerHeight - 216 - 20, + layout_hideDocumentButtonBar: true, + layout_hideDecorationTitle: true, + layout_hideOpenButton: true, + cloneFieldFilter: new List(['isSystem']), + slides: activeItem, // attach the slide to the recording + })) + ); + } + }), + 'start video recording' + ); @undoBatch @action lfg = (e: React.MouseEvent) => { e.stopPropagation(); // TODO: fix this bug - const { toggleChildrenRun } = this.rootDoc; - TreeView.ToggleChildrenRun.get(this.rootDoc)?.(); + const { toggleChildrenRun } = this.slideDoc; + TreeView.ToggleChildrenRun.get(this.slideDoc)?.(); - // call this.rootDoc.recurChildren() to get all the children + // call this.slideDoc.recurChildren() to get all the children // if (iconClick) PresElementBox.showVideo = false; }; @computed get toolbarWidth(): number { const presBoxDocView = DocumentManager.Instance.getDocumentView(this.presBox); - let width: number = NumCast(this.presBox?._width); - if (presBoxDocView) width = presBoxDocView.props.PanelWidth(); - if (width === 0) width = 300; - return width; + const width = NumCast(this.presBox?._width); + return presBoxDocView ? presBoxDocView.props.PanelWidth() : width ? width : 300; } @computed get presButtons() { @@ -434,8 +414,8 @@ export class PresElementBox extends ViewBoxBaseComponent() { const presBoxColor = StrCast(presBox?._backgroundColor); const presColorBool = presBoxColor ? presBoxColor !== Colors.WHITE && presBoxColor !== 'transparent' : false; const targetDoc = this.targetDoc; - const activeItem = this.rootDoc; - const hasChildren = BoolCast(this.rootDoc?.hasChildren); + const activeItem = this.slideDoc; + const hasChildren = BoolCast(this.slideDoc?.hasChildren); const items: JSX.Element[] = []; @@ -460,9 +440,9 @@ export class PresElementBox extends ViewBoxBaseComponent() { ); items.push( - {this.recordingIsInOverlay ? 'Hide Recording' : `${PresElementBox.videoIsRecorded(activeItem) ? 'Show' : 'Start'} recording`}
}> -
(this.recordingIsInOverlay ? this.hideRecording(e, true) : this.startRecording(e, activeItem))} style={{ fontWeight: 700 }}> - e.stopPropagation()} /> + {this.videoRecordingIsInOverlay ? 'Hide Recording' : `${PresElementBox.videoIsRecorded(activeItem) ? 'Show' : 'Start'} recording`}
}> +
(this.videoRecordingIsInOverlay ? this.hideRecording(e, true) : this.startRecording(e, activeItem))} style={{ fontWeight: 700 }}> + e.stopPropagation()} />
); @@ -498,14 +478,14 @@ export class PresElementBox extends ViewBoxBaseComponent() { ); } items.push( - {this.rootDoc.presentation_expandInlineButton ? 'Minimize' : 'Expand'}
}> + {this.slideDoc.presentation_expandInlineButton ? 'Minimize' : 'Expand'}
}>
{ e.stopPropagation(); this.presExpandDocumentClick(); }}> - e.stopPropagation()} /> + e.stopPropagation()} />
); @@ -536,18 +516,18 @@ export class PresElementBox extends ViewBoxBaseComponent() { } @computed get mainItem() { - const isSelected: boolean = this.selectedArray?.has(this.rootDoc) ? true : false; + const isSelected: boolean = this.selectedArray?.has(this.slideDoc) ? true : false; const isCurrent: boolean = this.presBox?._itemIndex === this.indexInPres; const miniView: boolean = this.toolbarWidth <= 110; const presBox = this.presBox; //presBox const presBoxColor: string = StrCast(presBox?._backgroundColor); const presColorBool: boolean = presBoxColor ? presBoxColor !== Colors.WHITE && presBoxColor !== 'transparent' : false; - const activeItem: Doc = this.rootDoc; + const activeItem: Doc = this.slideDoc; return (
() { }} onDoubleClick={action(e => { this.toggleProperties(); - this.presBoxView?.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, false); + this.presBoxView?.regularSelect(this.slideDoc, this._itemRef.current!, this._dragRef.current!, false); })} onPointerOver={this.onPointerOver} onPointerLeave={this.onPointerLeave} @@ -571,7 +551,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { ) : (
() { style={{ display: 'inline-flex', pointerEvents: isSelected ? undefined : 'none', - width: `calc(100% ${this.rootDoc.presentation_expandInlineButton ? '- 50%' : ''} - ${this.presButtons.length * 22}px`, + width: `calc(100% ${this.slideDoc.presentation_expandInlineButton ? '- 50%' : ''} - ${this.presButtons.length * 22}px`, cursor: isSelected ? 'text' : 'grab', }}>
() { } render() { - return !(this.rootDoc instanceof Doc) || this.targetDoc instanceof Promise ? null : this.mainItem; + return !(this.slideDoc instanceof Doc) || this.targetDoc instanceof Promise ? null : this.mainItem; } } -- cgit v1.2.3-70-g09d2 From 6d38096db5f0d550866d82d954436447d0c36a65 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 6 Dec 2023 19:03:26 -0500 Subject: converted equationEditor from a npm module to a local file. commented out old google-maps code. --- package-lock.json | 362 +----- package.json | 8 +- src/client/views/nodes/EquationBox.tsx | 2 +- src/client/views/nodes/MapBox/MapBox.tsx | 11 - src/client/views/nodes/MapBox/MapBox2.tsx | 1194 ++++++++++---------- src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx | 184 +-- .../views/nodes/formattedText/EquationEditor.tsx | 87 ++ .../views/nodes/formattedText/EquationView.tsx | 2 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 2 +- 9 files changed, 815 insertions(+), 1037 deletions(-) create mode 100644 src/client/views/nodes/formattedText/EquationEditor.tsx (limited to 'src/client/views/nodes/EquationBox.tsx') diff --git a/package-lock.json b/package-lock.json index f02c8c678..76d33eaee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,7 +74,6 @@ "D": "^1.0.0", "d3": "^7.8.5", "depcheck": "^1.4.7", - "equation-editor-react": "^0.0.10", "exif": "^0.6.0", "exifr": "^7.1.3", "express": "^4.18.2", @@ -95,7 +94,6 @@ "function-plot": "^1.23.3", "golden-layout": "^2.6.0", "google-auth-library": "^9.4.1", - "google-maps-react": "^2.0.6", "googleapis": "^129.0.0", "googlephotos": "^0.3.5", "got": "^14.0.0", @@ -117,6 +115,7 @@ "jszip": "^3.10.1", "lodash": "^4.17.21", "material-ui": "^0.20.2", + "mathquill": "^0.10.1-a", "md5-file": "^5.0.0", "memorystream": "^0.3.1", "mobile-detect": "^1.4.5", @@ -130,7 +129,7 @@ "nodemailer": "^6.9.7", "nodemon": "^3.0.2", "normalize.css": "^8.0.1", - "npm": "^10.2.4", + "npm": "^10.2.5", "openai": "^4.20.1", "p-limit": "^5.0.0", "passport": "^0.7.0", @@ -143,7 +142,6 @@ "probe-image-size": "^7.2.3", "process": "^0.11.10", "prosemirror-commands": "^1.5.2", - "prosemirror-dev-tools": "^4.0.0", "prosemirror-find-replace": "^0.9.0", "prosemirror-history": "^1.3.2", "prosemirror-inputrules": "^1.3.0", @@ -235,7 +233,6 @@ "@types/express-session": "^1.17.10", "@types/express-validator": "^3.0.0", "@types/file-saver": "^2.0.7", - "@types/google-maps-react": "^2.0.5", "@types/jquery": "^3.5.29", "@types/libxmljs": "^0.18.12", "@types/lodash": "^4.14.202", @@ -250,7 +247,6 @@ "@types/passport-local": "^1.0.38", "@types/pdfjs-dist": "^2.10.378", "@types/prosemirror-commands": "^1.0.4", - "@types/prosemirror-dev-tools": "^3.0.6", "@types/prosemirror-history": "^1.0.3", "@types/prosemirror-inputrules": "^1.0.4", "@types/prosemirror-keymap": "^1.0.4", @@ -679,17 +675,6 @@ "node": ">=6.9.0" } }, - "node_modules/@compiled/react": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/@compiled/react/-/react-0.11.4.tgz", - "integrity": "sha512-mtnEUFM7w/5xABWWWj3wW0vjS/cHSg0PAttJC+hOpQ5z5qGZCwk43Gy8Hfjruxvll73igJ5DSMzcAyek6DMKjw==", - "dependencies": { - "csstype": "^3.1.1" - }, - "peerDependencies": { - "react": ">= 16.12.0" - } - }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -2503,11 +2488,6 @@ "integrity": "sha512-8iHVLHsCCOBKjCF2KwFe0p9Z3rfM9mL+sSP8btyR5vTjJRAqpBYD28/ZLgXPf0pjG1VxOvtCV/BgXkQbpSe8Hw==", "dev": true }, - "node_modules/@types/base16": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/base16/-/base16-1.0.5.tgz", - "integrity": "sha512-OzOWrTluG9cwqidEzC/Q6FAmIPcnZfm8BFRlIx0+UIUqnuAmi5OS88O0RpT3Yz6qdmqObvUhasrbNsCofE4W9A==" - }, "node_modules/@types/bcrypt-nodejs": { "version": "0.0.31", "resolved": "https://registry.npmjs.org/@types/bcrypt-nodejs/-/bcrypt-nodejs-0.0.31.tgz", @@ -3031,16 +3011,6 @@ "@types/google.maps": "*" } }, - "node_modules/@types/google-maps-react": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/google-maps-react/-/google-maps-react-2.0.5.tgz", - "integrity": "sha512-qcsYlHiNH169Vf7jmkEwbzBDqBfqqzYkTgK1vL7qkWVZI04wFESADYVITuQunrZ9swY/SG+tTWUIXMlY4W8byw==", - "deprecated": "This is a stub types definition. google-maps-react provides its own type definitions, so you do not need this installed.", - "dev": true, - "dependencies": { - "google-maps-react": "*" - } - }, "node_modules/@types/google.maps": { "version": "3.53.5", "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.53.5.tgz", @@ -3121,7 +3091,8 @@ "node_modules/@types/lodash": { "version": "4.14.202", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", - "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==" + "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", + "dev": true }, "node_modules/@types/mdast": { "version": "4.0.3", @@ -3328,15 +3299,6 @@ "prosemirror-commands": "*" } }, - "node_modules/@types/prosemirror-dev-tools": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/prosemirror-dev-tools/-/prosemirror-dev-tools-3.0.6.tgz", - "integrity": "sha512-zARROV118nwc+sX7W+0ea4cffqUeRNOSac0jttSpJ921aS6w++Be+RakAgGiTqoRpPV+J+wKomMR/RuKBAlEMg==", - "dev": true, - "dependencies": { - "prosemirror-view": "^1.24.0" - } - }, "node_modules/@types/prosemirror-history": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@types/prosemirror-history/-/prosemirror-history-1.3.0.tgz", @@ -5158,11 +5120,6 @@ "node": ">= 0.4" } }, - "node_modules/base16": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz", - "integrity": "sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==" - }, "node_modules/Base64": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/Base64/-/Base64-0.2.1.tgz", @@ -9196,34 +9153,6 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, "node_modules/confusing-browser-globals": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", @@ -10936,11 +10865,6 @@ "node": ">=0.3.1" } }, - "node_modules/diff-match-patch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", - "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==" - }, "node_modules/digest-fetch": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz", @@ -11314,19 +11238,6 @@ "node": ">=4" } }, - "node_modules/equation-editor-react": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/equation-editor-react/-/equation-editor-react-0.0.10.tgz", - "integrity": "sha512-m1fBISnB1Z9OO9QzrwoOiTO6y/psA8+1Bc+s2bkRhG0hQAmMK5NKrr8ommAka0sDp7+OvXs+pqJfZdq4o3X+wA==", - "dependencies": { - "jquery": "^3.4.1", - "mathquill": "^0.10.1-a" - }, - "peerDependencies": { - "react": "^16.0.0", - "react-dom": "^16.0.0" - } - }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -14966,15 +14877,6 @@ "node": ">=14" } }, - "node_modules/google-maps-react": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/google-maps-react/-/google-maps-react-2.0.6.tgz", - "integrity": "sha512-M8Eo9WndfQEfxcmm6yRq03qdJgw1x6rQmJ9DN+a+xPQ3K7yNDGkVDbinrf4/8vcox7nELbeopbm4bpefKewWfQ==", - "peerDependencies": { - "react": "~0.14.8 || ^15.0.0 || ^16.0.0", - "react-dom": "~0.14.8 || ^15.0.0 || ^16.0.0" - } - }, "node_modules/googleapis": { "version": "129.0.0", "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-129.0.0.tgz", @@ -15514,17 +15416,6 @@ "util-deprecate": "~1.0.1" } }, - "node_modules/html": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/html/-/html-1.0.0.tgz", - "integrity": "sha1-pUT6nqVJK/s6LMqCEKEL57WvH2E=", - "dependencies": { - "concat-stream": "^1.4.7" - }, - "bin": { - "html": "bin/html.js" - } - }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", @@ -17194,63 +17085,6 @@ "regenerator-runtime": "^0.13.3" } }, - "node_modules/jotai": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/jotai/-/jotai-1.13.1.tgz", - "integrity": "sha512-RUmH1S4vLsG3V6fbGlKzGJnLrDcC/HNb5gH2AeA9DzuJknoVxSGvvg8OBB7lke+gDc4oXmdVsaKn/xDUhWZ0vw==", - "engines": { - "node": ">=12.20.0" - }, - "peerDependencies": { - "@babel/core": "*", - "@babel/template": "*", - "jotai-devtools": "*", - "jotai-immer": "*", - "jotai-optics": "*", - "jotai-redux": "*", - "jotai-tanstack-query": "*", - "jotai-urql": "*", - "jotai-valtio": "*", - "jotai-xstate": "*", - "jotai-zustand": "*", - "react": ">=16.8" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@babel/template": { - "optional": true - }, - "jotai-devtools": { - "optional": true - }, - "jotai-immer": { - "optional": true - }, - "jotai-optics": { - "optional": true - }, - "jotai-redux": { - "optional": true - }, - "jotai-tanstack-query": { - "optional": true - }, - "jotai-urql": { - "optional": true - }, - "jotai-valtio": { - "optional": true - }, - "jotai-xstate": { - "optional": true - }, - "jotai-zustand": { - "optional": true - } - } - }, "node_modules/jpeg-js": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", @@ -17490,21 +17324,6 @@ "json5": "lib/cli.js" } }, - "node_modules/jsondiffpatch": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/jsondiffpatch/-/jsondiffpatch-0.4.1.tgz", - "integrity": "sha512-t0etAxTUk1w5MYdNOkZBZ8rvYYN5iL+2dHCCx/DpkFm/bW28M6y5nUS83D4XdZiHy35Fpaw6LBb+F88fHZnVCw==", - "dependencies": { - "chalk": "^2.3.0", - "diff-match-patch": "^1.0.0" - }, - "bin": { - "jsondiffpatch": "bin/jsondiffpatch" - }, - "engines": { - "node": ">=8.17.0" - } - }, "node_modules/jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", @@ -17894,16 +17713,6 @@ "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=" }, - "node_modules/lodash.curry": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz", - "integrity": "sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -20157,11 +19966,6 @@ "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==" }, - "node_modules/nanoid": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz", - "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==" - }, "node_modules/nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -20491,9 +20295,9 @@ "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==" }, "node_modules/npm": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.2.4.tgz", - "integrity": "sha512-umEuYneVEYO9KoEEI8n2sSGmNQeqco/3BSeacRlqIkCzw4E7XGtYSWMeJobxzr6hZ2n9cM+u5TsMTcC5bAgoWA==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.2.5.tgz", + "integrity": "sha512-lXdZ7titEN8CH5YJk9C/aYRU9JeDxQ4d8rwIIDsvH3SMjLjHTukB2CFstMiB30zXs4vCrPN2WH6cDq1yHBeJAw==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -20579,7 +20383,7 @@ "@sigstore/tuf": "^2.2.0", "abbrev": "^2.0.0", "archy": "~1.0.0", - "cacache": "^18.0.0", + "cacache": "^18.0.1", "chalk": "^5.3.0", "ci-info": "^4.0.0", "cli-columns": "^4.0.0", @@ -20593,7 +20397,7 @@ "ini": "^4.1.1", "init-package-json": "^6.0.0", "is-cidr": "^5.0.3", - "json-parse-even-better-errors": "^3.0.0", + "json-parse-even-better-errors": "^3.0.1", "libnpmaccess": "^8.0.1", "libnpmdiff": "^6.0.3", "libnpmexec": "^7.0.4", @@ -20622,7 +20426,7 @@ "npm-user-validate": "^2.0.0", "npmlog": "^7.0.1", "p-map": "^4.0.0", - "pacote": "^17.0.4", + "pacote": "^17.0.5", "parse-conflict-json": "^3.0.1", "proc-log": "^3.0.0", "qrcode-terminal": "^0.12.0", @@ -20742,7 +20546,7 @@ } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "7.2.1", + "version": "7.2.2", "inBundle": true, "license": "ISC", "dependencies": { @@ -20788,7 +20592,7 @@ } }, "node_modules/npm/node_modules/@npmcli/config": { - "version": "8.0.2", + "version": "8.0.3", "inBundle": true, "license": "ISC", "dependencies": { @@ -21217,7 +21021,7 @@ } }, "node_modules/npm/node_modules/cacache": { - "version": "18.0.0", + "version": "18.0.1", "inBundle": true, "license": "ISC", "dependencies": { @@ -21226,7 +21030,7 @@ "glob": "^10.2.2", "lru-cache": "^10.0.1", "minipass": "^7.0.3", - "minipass-collect": "^1.0.2", + "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^4.0.0", @@ -21745,7 +21549,7 @@ "license": "BSD-3-Clause" }, "node_modules/npm/node_modules/ignore-walk": { - "version": "6.0.3", + "version": "6.0.4", "inBundle": true, "license": "ISC", "dependencies": { @@ -21870,7 +21674,7 @@ } }, "node_modules/npm/node_modules/json-parse-even-better-errors": { - "version": "3.0.0", + "version": "3.0.1", "inBundle": true, "license": "MIT", "engines": { @@ -21904,7 +21708,7 @@ "license": "MIT" }, "node_modules/npm/node_modules/libnpmaccess": { - "version": "8.0.1", + "version": "8.0.2", "inBundle": true, "license": "ISC", "dependencies": { @@ -21916,7 +21720,7 @@ } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "6.0.3", + "version": "6.0.4", "inBundle": true, "license": "ISC", "dependencies": { @@ -21935,7 +21739,7 @@ } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "7.0.4", + "version": "7.0.5", "inBundle": true, "license": "ISC", "dependencies": { @@ -21956,7 +21760,7 @@ } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "5.0.1", + "version": "5.0.2", "inBundle": true, "license": "ISC", "dependencies": { @@ -21967,7 +21771,7 @@ } }, "node_modules/npm/node_modules/libnpmhook": { - "version": "10.0.0", + "version": "10.0.1", "inBundle": true, "license": "ISC", "dependencies": { @@ -21979,7 +21783,7 @@ } }, "node_modules/npm/node_modules/libnpmorg": { - "version": "6.0.1", + "version": "6.0.2", "inBundle": true, "license": "ISC", "dependencies": { @@ -21991,7 +21795,7 @@ } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "6.0.3", + "version": "6.0.4", "inBundle": true, "license": "ISC", "dependencies": { @@ -22005,7 +21809,7 @@ } }, "node_modules/npm/node_modules/libnpmpublish": { - "version": "9.0.2", + "version": "9.0.3", "inBundle": true, "license": "ISC", "dependencies": { @@ -22023,7 +21827,7 @@ } }, "node_modules/npm/node_modules/libnpmsearch": { - "version": "7.0.0", + "version": "7.0.1", "inBundle": true, "license": "ISC", "dependencies": { @@ -22034,7 +21838,7 @@ } }, "node_modules/npm/node_modules/libnpmteam": { - "version": "6.0.0", + "version": "6.0.1", "inBundle": true, "license": "ISC", "dependencies": { @@ -22046,7 +21850,7 @@ } }, "node_modules/npm/node_modules/libnpmversion": { - "version": "5.0.1", + "version": "5.0.2", "inBundle": true, "license": "ISC", "dependencies": { @@ -22061,12 +21865,9 @@ } }, "node_modules/npm/node_modules/lru-cache": { - "version": "10.0.2", + "version": "10.1.0", "inBundle": true, "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, "engines": { "node": "14 || >=16.14" } @@ -22115,25 +21916,14 @@ } }, "node_modules/npm/node_modules/minipass-collect": { - "version": "1.0.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minipass-collect/node_modules/minipass": { - "version": "3.3.6", + "version": "2.0.1", "inBundle": true, "license": "ISC", "dependencies": { - "yallist": "^4.0.0" + "minipass": "^7.0.3" }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, "node_modules/npm/node_modules/minipass-fetch": { @@ -22397,11 +22187,11 @@ } }, "node_modules/npm/node_modules/npm-packlist": { - "version": "8.0.0", + "version": "8.0.1", "inBundle": true, "license": "ISC", "dependencies": { - "ignore-walk": "^6.0.0" + "ignore-walk": "^6.0.4" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -22487,7 +22277,7 @@ } }, "node_modules/npm/node_modules/pacote": { - "version": "17.0.4", + "version": "17.0.5", "inBundle": true, "license": "ISC", "dependencies": { @@ -24544,30 +24334,6 @@ "prosemirror-transform": "^1.0.0" } }, - "node_modules/prosemirror-dev-tools": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/prosemirror-dev-tools/-/prosemirror-dev-tools-4.0.0.tgz", - "integrity": "sha512-fF1AqJJa/ojVJTtc6WvygVQWFQI1zo37dewn0BQEKNLUfdJ4PRbqIYIFfh30wQhe8XcWw7J1ZidHZHz0a8VoYQ==", - "dependencies": { - "@babel/runtime": "^7.18.6", - "@compiled/react": "^0.11.1", - "html": "^1.0.0", - "jotai": "^1.10.0", - "jsondiffpatch": "^0.4.1", - "nanoid": "^2.1.11", - "prosemirror-model": ">=1.0.0", - "prosemirror-state": ">=1.0.0", - "react-dock": "^0.6.0", - "react-json-tree": "^0.17.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, "node_modules/prosemirror-find-replace": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/prosemirror-find-replace/-/prosemirror-find-replace-0.9.0.tgz", @@ -25060,29 +24826,6 @@ "react": ">=16.3.0" } }, - "node_modules/react-base16-styling": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/react-base16-styling/-/react-base16-styling-0.9.1.tgz", - "integrity": "sha512-1s0CY1zRBOQ5M3T61wetEpvQmsYSNtWEcdYzyZNxKa8t7oDvaOn9d21xrGezGAHFWLM7SHcktPuPTrvoqxSfKw==", - "dependencies": { - "@babel/runtime": "^7.16.7", - "@types/base16": "^1.0.2", - "@types/lodash": "^4.14.178", - "base16": "^1.0.0", - "color": "^3.2.1", - "csstype": "^3.0.10", - "lodash.curry": "^4.1.1" - } - }, - "node_modules/react-base16-styling/node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, "node_modules/react-color": { "version": "2.19.3", "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.19.3.tgz", @@ -25151,22 +24894,6 @@ "react-dom": "^16.9.0 || ^17 || ^18" } }, - "node_modules/react-dock": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/react-dock/-/react-dock-0.6.0.tgz", - "integrity": "sha512-jEOhv1s+pqRQ4JxgUw4XUotnprOehZ23mqchf3whxYXnvNgTQOXCxh6bpcqW8P6OybIk2bYO18r3qimZ3ypCbg==", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@types/lodash": "^4.14.182", - "@types/prop-types": "^15.7.5", - "lodash.debounce": "^4.0.8", - "prop-types": "^15.8.1" - }, - "peerDependencies": { - "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "react": "^16.3.0 || ^17.0.0 || ^18.0.0" - } - }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -25264,22 +24991,6 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, - "node_modules/react-json-tree": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/react-json-tree/-/react-json-tree-0.17.0.tgz", - "integrity": "sha512-hcWjibI/fAvsKnfYk+lka5OrE1Lvb1jH5pSnFhIU5T8cCCxB85r6h/NOzDPggSSgErjmx4rl3+2EkeclIKBOhg==", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@types/lodash": "^4.14.182", - "@types/prop-types": "^15.7.5", - "prop-types": "^15.8.1", - "react-base16-styling": "^0.9.1" - }, - "peerDependencies": { - "@types/react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "react": "^16.3.0 || ^17.0.0 || ^18.0.0" - } - }, "node_modules/react-jsx-parser": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/react-jsx-parser/-/react-jsx-parser-1.29.0.tgz", @@ -28953,11 +28664,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, "node_modules/typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", diff --git a/package.json b/package.json index 92d5ef856..7bf0bba05 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,6 @@ "@types/express-session": "^1.17.10", "@types/express-validator": "^3.0.0", "@types/file-saver": "^2.0.7", - "@types/google-maps-react": "^2.0.5", "@types/jquery": "^3.5.29", "@types/libxmljs": "^0.18.12", "@types/lodash": "^4.14.202", @@ -56,7 +55,6 @@ "@types/passport-local": "^1.0.38", "@types/pdfjs-dist": "^2.10.378", "@types/prosemirror-commands": "^1.0.4", - "@types/prosemirror-dev-tools": "^3.0.6", "@types/prosemirror-history": "^1.0.3", "@types/prosemirror-inputrules": "^1.0.4", "@types/prosemirror-keymap": "^1.0.4", @@ -182,7 +180,6 @@ "D": "^1.0.0", "d3": "^7.8.5", "depcheck": "^1.4.7", - "equation-editor-react": "^0.0.10", "exif": "^0.6.0", "exifr": "^7.1.3", "express": "^4.18.2", @@ -203,7 +200,6 @@ "function-plot": "^1.23.3", "golden-layout": "^2.6.0", "google-auth-library": "^9.4.1", - "google-maps-react": "^2.0.6", "googleapis": "^129.0.0", "googlephotos": "^0.3.5", "got": "^14.0.0", @@ -225,6 +221,7 @@ "jszip": "^3.10.1", "lodash": "^4.17.21", "material-ui": "^0.20.2", + "mathquill": "^0.10.1-a", "md5-file": "^5.0.0", "memorystream": "^0.3.1", "mobile-detect": "^1.4.5", @@ -238,7 +235,7 @@ "nodemailer": "^6.9.7", "nodemon": "^3.0.2", "normalize.css": "^8.0.1", - "npm": "^10.2.4", + "npm": "^10.2.5", "openai": "^4.20.1", "p-limit": "^5.0.0", "passport": "^0.7.0", @@ -251,7 +248,6 @@ "probe-image-size": "^7.2.3", "process": "^0.11.10", "prosemirror-commands": "^1.5.2", - "prosemirror-dev-tools": "^4.0.0", "prosemirror-find-replace": "^0.9.0", "prosemirror-history": "^1.3.2", "prosemirror-inputrules": "^1.3.0", diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx index cd263f82a..23413b9d1 100644 --- a/src/client/views/nodes/EquationBox.tsx +++ b/src/client/views/nodes/EquationBox.tsx @@ -1,4 +1,4 @@ -import EquationEditor from 'equation-editor-react'; +import EquationEditor from './formattedText/EquationEditor'; import { action, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 398d1255e..69723b171 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -794,17 +794,6 @@ export class MapBox extends ViewBoxAnnotatableComponent ))}
- {/* */}
{/* */}
diff --git a/src/client/views/nodes/MapBox/MapBox2.tsx b/src/client/views/nodes/MapBox/MapBox2.tsx index a77bfc50a..39ed6a47e 100644 --- a/src/client/views/nodes/MapBox/MapBox2.tsx +++ b/src/client/views/nodes/MapBox/MapBox2.tsx @@ -1,597 +1,597 @@ -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Autocomplete, GoogleMap, GoogleMapProps, Marker } from '@react-google-maps/api'; -import { action, computed, IReactionDisposer, observable, ObservableMap, runInAction } from 'mobx'; -import { observer } from 'mobx-react'; -import * as React from 'react'; -import { Doc, DocListCast, Opt } from '../../../../fields/Doc'; -import { Id } from '../../../../fields/FieldSymbols'; -import { NumCast, StrCast } from '../../../../fields/Types'; -import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils'; -import { Docs } from '../../../documents/Documents'; -import { DragManager } from '../../../util/DragManager'; -import { SnappingManager } from '../../../util/SnappingManager'; -import { UndoManager } from '../../../util/UndoManager'; -import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm'; -import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent'; -import { Colors } from '../../global/globalEnums'; -import { AnchorMenu } from '../../pdf/AnchorMenu'; -import { Annotation } from '../../pdf/Annotation'; -import { SidebarAnnos } from '../../SidebarAnnos'; -import { FieldView, FieldViewProps } from '../FieldView'; -import { PinProps } from '../trails'; -import './MapBox2.scss'; -import { MapBoxInfoWindow } from './MapBoxInfoWindow'; - -/** - * MapBox2 architecture: - * Main component: MapBox2.tsx - * Supporting Components: SidebarAnnos, CollectionStackingView - * - * MapBox2 is a node that extends the ViewBoxAnnotatableComponent. Similar to PDFBox and WebBox, it supports interaction between sidebar content and document content. - * The main body of MapBox2 uses Google Maps API to allow location retrieval, adding map markers, pan and zoom, and open street view. - * Dash Document architecture is integrated with Maps API: When drag and dropping documents with ExifData (gps Latitude and Longitude information) available, - * sidebarAddDocument function checks if the document contains lat & lng information, if it does, then the document is added to both the sidebar and the infowindow (a pop up corresponding to a map marker--pin on map). - * The lat and lng field of the document is filled when importing (spec see ConvertDMSToDD method and processFileUpload method in Documents.ts). - * A map marker is considered a document that contains a collection with stacking view of documents, it has a lat, lng location, which is passed to Maps API's custom marker (red pin) to be rendered on the google maps - */ - -// const _global = (window /* browser */ || global /* node */) as any; - -const mapContainerStyle = { - height: '100%', -}; - -const defaultCenter = { - lat: 42.360081, - lng: -71.058884, -}; - -const mapOptions = { - fullscreenControl: false, -}; - -const apiKey = process.env.GOOGLE_MAPS; - -const script = document.createElement('script'); -script.defer = true; -script.async = true; -script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places,drawing`; -console.log(script.src); -document.head.appendChild(script); - -/** - * Consider integrating later: allows for drawing, circling, making shapes on map - */ -// const drawingManager = new window.google.maps.drawing.DrawingManager({ -// drawingControl: true, -// drawingControlOptions: { -// position: google.maps.ControlPosition.TOP_RIGHT, -// drawingModes: [ -// google.maps.drawing.OverlayType.MARKER, -// // currently we are not supporting the following drawing mode on map, a thought for future development -// google.maps.drawing.OverlayType.CIRCLE, -// google.maps.drawing.OverlayType.POLYLINE, -// ], -// }, -// }); - -// options for searchbox in Google Maps Places Autocomplete API -const options = { - fields: ['formatted_address', 'geometry', 'name'], // note: level of details is charged by item per retrieval, not recommended to return all fields - strictBounds: false, - types: ['establishment'], // type pf places, subject of change according to user need -} as google.maps.places.AutocompleteOptions; - -@observer -export class MapBox2 extends ViewBoxAnnotatableComponent>() { - private _dropDisposer?: DragManager.DragDropDisposer; - private _disposers: { [name: string]: IReactionDisposer } = {}; - private _annotationLayer: React.RefObject = React.createRef(); - @observable private _overlayAnnoInfo: Opt; - showInfo = action((anno: Opt) => (this._overlayAnnoInfo = anno)); - public static LayoutString(fieldKey: string) { - return FieldView.LayoutString(MapBox2, fieldKey); - } - public get SidebarKey() { - return this.fieldKey + '_sidebar'; - } - private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean, doc: Opt) => void); - @computed get inlineTextAnnotations() { - return this.allMapMarkers.filter(a => a.text_inlineAnnotations); - } - - @observable private _map: google.maps.Map = null as unknown as google.maps.Map; - @observable private selectedPlace: Doc | undefined; - @observable private markerMap: { [id: string]: google.maps.Marker } = {}; - @observable private center = navigator.geolocation ? navigator.geolocation.getCurrentPosition : defaultCenter; - @observable private inputRef = React.createRef(); - @observable private searchMarkers: google.maps.Marker[] = []; - @observable private searchBox = new window.google.maps.places.Autocomplete(this.inputRef.current!, options); - @observable private _savedAnnotations = new ObservableMap(); - @computed get allSidebarDocs() { - return DocListCast(this.dataDoc[this.SidebarKey]); - } - @computed get allMapMarkers() { - return DocListCast(this.dataDoc[this.annotationKey]); - } - @observable private toggleAddMarker = false; - - @observable _showSidebar = false; - @computed get SidebarShown() { - return this._showSidebar || this.layoutDoc._layout_showSidebar ? true : false; - } - - static _canAnnotate = true; - static _hadSelection: boolean = false; - private _sidebarRef = React.createRef(); - private _ref: React.RefObject = React.createRef(); - - componentDidMount() { - this.props.setContentView?.(this); - } - - @action - private setSearchBox = (searchBox: any) => { - this.searchBox = searchBox; - }; - - // iterate allMarkers to size, center, and zoom map to contain all markers - private fitBounds = (map: google.maps.Map) => { - const curBounds = map.getBounds() ?? new window.google.maps.LatLngBounds(); - const isFitting = this.allMapMarkers.reduce((fits, place) => fits && curBounds?.contains({ lat: NumCast(place.lat), lng: NumCast(place.lng) }), true as boolean); - !isFitting && map.fitBounds(this.allMapMarkers.reduce((bounds, place) => bounds.extend({ lat: NumCast(place.lat), lng: NumCast(place.lng) }), new window.google.maps.LatLngBounds())); - }; - - /** - * Custom control for add marker button - * @param controlDiv - * @param map - */ - private CenterControl = () => { - const controlDiv = document.createElement('div'); - controlDiv.className = 'MapBox2-addMarker'; - // Set CSS for the control border. - const controlUI = document.createElement('div'); - controlUI.style.backgroundColor = '#fff'; - controlUI.style.borderRadius = '3px'; - controlUI.style.cursor = 'pointer'; - controlUI.style.marginTop = '10px'; - controlUI.style.borderRadius = '4px'; - controlUI.style.marginBottom = '22px'; - controlUI.style.textAlign = 'center'; - controlUI.style.position = 'absolute'; - controlUI.style.width = '32px'; - controlUI.style.height = '32px'; - controlUI.title = 'Click to toggle marker mode. In marker mode, click on map to place a marker.'; - - const plIcon = document.createElement('img'); - plIcon.src = 'https://cdn4.iconfinder.com/data/icons/wirecons-free-vector-icons/32/add-256.png'; - plIcon.style.color = 'rgb(25,25,25)'; - plIcon.style.fontFamily = 'Roboto,Arial,sans-serif'; - plIcon.style.fontSize = '16px'; - plIcon.style.lineHeight = '32px'; - plIcon.style.left = '18'; - plIcon.style.top = '15'; - plIcon.style.position = 'absolute'; - plIcon.width = 14; - plIcon.height = 14; - plIcon.innerHTML = 'Add'; - controlUI.appendChild(plIcon); - - // Set CSS for the control interior. - const markerIcon = document.createElement('img'); - markerIcon.src = 'https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678111-map-marker-1024.png'; - markerIcon.style.color = 'rgb(25,25,25)'; - markerIcon.style.fontFamily = 'Roboto,Arial,sans-serif'; - markerIcon.style.fontSize = '16px'; - markerIcon.style.lineHeight = '32px'; - markerIcon.style.left = '-2'; - markerIcon.style.top = '1'; - markerIcon.width = 30; - markerIcon.height = 30; - markerIcon.style.position = 'absolute'; - markerIcon.innerHTML = 'Add'; - controlUI.appendChild(markerIcon); - - // Setup the click event listeners - controlUI.addEventListener('click', () => { - if (this.toggleAddMarker === true) { - this.toggleAddMarker = false; - console.log('add marker button status:' + this.toggleAddMarker); - controlUI.style.backgroundColor = '#fff'; - markerIcon.style.color = 'rgb(25,25,25)'; - } else { - this.toggleAddMarker = true; - console.log('add marker button status:' + this.toggleAddMarker); - controlUI.style.backgroundColor = '#4476f7'; - markerIcon.style.color = 'rgb(255,255,255)'; - } - }); - controlDiv.appendChild(controlUI); - return controlDiv; - }; - - /** - * Place the marker on google maps & store the empty marker as a MapMarker Document in allMarkers list - * @param position - the LatLng position where the marker is placed - * @param map - */ - @action - private placeMarker = (position: google.maps.LatLng, map: google.maps.Map) => { - const marker = new google.maps.Marker({ - position: position, - map: map, - }); - map.panTo(position); - const mapMarker = Docs.Create.PushpinDocument(NumCast(position.lat()), NumCast(position.lng()), false, [], {}); - this.addDocument(mapMarker, this.annotationKey); - }; - - _loadPending = true; - /** - * store a reference to google map instance - * setup the drawing manager on the top right corner of map - * fit map bounds to contain all markers - * @param map - */ - @action - private loadHandler = (map: google.maps.Map) => { - this._map = map; - this._loadPending = true; - const centerControlDiv = this.CenterControl(); - map.controls[google.maps.ControlPosition.TOP_RIGHT].push(centerControlDiv); - //drawingManager.setMap(map); - // if (navigator.geolocation) { - // navigator.geolocation.getCurrentPosition( - // (position: Position) => { - // const pos = { - // lat: position.coords.latitude, - // lng: position.coords.longitude, - // }; - // this._map.setCenter(pos); - // } - // ); - // } else { - // alert("Your geolocation is not supported by browser.") - // }; - map.setZoom(NumCast(this.dataDoc.map_zoom, 2.5)); - map.setCenter(new google.maps.LatLng(NumCast(this.dataDoc.mapLat), NumCast(this.dataDoc.mapLng))); - setTimeout(() => { - if (this._loadPending && this._map.getBounds()) { - this._loadPending = false; - this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map); - } - }, 250); - // listener to addmarker event - this._map.addListener('click', (e: MouseEvent) => { - if (this.toggleAddMarker === true) { - this.placeMarker((e as any).latLng, map); - } - }); - }; - - @action - centered = () => { - if (this._loadPending && this._map.getBounds()) { - this._loadPending = false; - this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map); - } - this.dataDoc.mapLat = this._map.getCenter()?.lat(); - this.dataDoc.mapLng = this._map.getCenter()?.lng(); - }; - - @action - zoomChanged = () => { - if (this._loadPending && this._map.getBounds()) { - this._loadPending = false; - this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map); - } - this.dataDoc.map_zoom = this._map.getZoom(); - }; - - /** - * Load and render all map markers - * @param marker - * @param place - */ - @action - private markerLoadHandler = (marker: google.maps.Marker, place: Doc) => { - place[Id] ? (this.markerMap[place[Id]] = marker) : null; - }; - - /** - * on clicking the map marker, set the selected place to the marker document & set infowindowopen to be true - * @param e - * @param place - */ - @action - private markerClickHandler = (e: google.maps.MapMouseEvent, place: Doc) => { - // set which place was clicked - this.selectedPlace = place; - place.infoWindowOpen = true; - }; - - /** - * Called when dragging documents into map sidebar or directly into infowindow; to create a map marker, ref to MapMarkerDocument in Documents.ts - * @param doc - * @param sidebarKey - * @returns - */ - sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => { - console.log('print all sidebar Docs'); - if (!this.layoutDoc._layout_showSidebar) this.toggleSidebar(); - const docs = doc instanceof Doc ? [doc] : doc; - docs.forEach(doc => { - if (doc.lat !== undefined && doc.lng !== undefined) { - const existingMarker = this.allMapMarkers.find(marker => marker.lat === doc.lat && marker.lng === doc.lng); - if (existingMarker) { - Doc.AddDocToList(existingMarker, 'data', doc); - } else { - const marker = Docs.Create.PushpinDocument(NumCast(doc.lat), NumCast(doc.lng), false, [doc], {}); - this.addDocument(marker, this.annotationKey); - } - } - }); //add to annotation list - - return this.addDocument(doc, sidebarKey); // add to sidebar list - }; - - /** - * Removing documents from the sidebar - * @param doc - * @param sidebarKey - * @returns - */ - sidebarRemoveDocument = (doc: Doc | Doc[], sidebarKey?: string) => { - if (this.layoutDoc._layout_showSidebar) this.toggleSidebar(); - const docs = doc instanceof Doc ? [doc] : doc; - return this.removeDocument(doc, sidebarKey); - }; - - /** - * Toggle sidebar onclick the tiny comment button on the top right corner - * @param e - */ - sidebarBtnDown = (e: React.PointerEvent) => { - setupMoveUpEvents( - this, - e, - (e, down, delta) => - runInAction(() => { - const localDelta = this.props - .ScreenToLocalTransform() - .scale(this.props.NativeDimScaling?.() || 1) - .transformDirection(delta[0], delta[1]); - const fullWidth = NumCast(this.layoutDoc._width); - const mapWidth = fullWidth - this.sidebarWidth(); - if (this.sidebarWidth() + localDelta[0] > 0) { - this._showSidebar = true; - this.layoutDoc._width = fullWidth + localDelta[0]; - this.layoutDoc._layout_sidebarWidthPercent = ((100 * (this.sidebarWidth() + localDelta[0])) / (fullWidth + localDelta[0])).toString() + '%'; - } else { - this._showSidebar = false; - this.layoutDoc._width = mapWidth; - this.layoutDoc._layout_sidebarWidthPercent = '0%'; - } - return false; - }), - emptyFunction, - () => UndoManager.RunInBatch(this.toggleSidebar, 'toggle sidebar map') - ); - }; - - sidebarWidth = () => (Number(this.layout_sidebarWidthPercent.substring(0, this.layout_sidebarWidthPercent.length - 1)) / 100) * this.props.PanelWidth(); - @computed get layout_sidebarWidthPercent() { - return StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%'); - } - @computed get sidebarColor() { - return StrCast(this.layoutDoc.sidebar_color, StrCast(this.layoutDoc[this.props.fieldKey + '_backgroundColor'], '#e4e4e4')); - } - - /** - * function that reads the place inputed from searchbox, then zoom in on the location that's been autocompleted; - * add a customized temporary marker on the map - */ - @action - private handlePlaceChanged = () => { - const place = this.searchBox.getPlace(); - - if (!place.geometry || !place.geometry.location) { - // user entered the name of a place that wasn't suggested & pressed the enter key, or place details request failed - window.alert("No details available for input: '" + place.name + "'"); - return; - } - - // zoom in on the location of the search result - if (place.geometry.viewport) { - this._map.fitBounds(place.geometry.viewport); - } else { - this._map.setCenter(place.geometry.location); - this._map.setZoom(17); - } - - // customize icon => customized icon for the nature of the location selected - const icon = { - url: place.icon as string, - size: new google.maps.Size(71, 71), - origin: new google.maps.Point(0, 0), - anchor: new google.maps.Point(17, 34), - scaledSize: new google.maps.Size(25, 25), - }; - - // put temporary cutomized marker on searched location - this.searchMarkers.forEach(marker => { - marker.setMap(null); - }); - this.searchMarkers = []; - this.searchMarkers.push( - new window.google.maps.Marker({ - map: this._map, - icon, - title: place.name, - position: place.geometry.location, - }) - ); - }; - - /** - * Handles toggle of sidebar on click the little comment button - */ - @computed get sidebarHandle() { - return ( -
- -
- ); - } - - // TODO: Adding highlight box layer to Maps - @action - toggleSidebar = () => { - //1.2 * w * ? = .2 * w .2/1.2 - const prevWidth = this.sidebarWidth(); - this.layoutDoc._layout_showSidebar = (this.layoutDoc._layout_sidebarWidthPercent = StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%') === '0%' ? `${(100 * 0.2) / 1.2}%` : '0%') !== '0%'; - this.layoutDoc._width = this.layoutDoc._layout_showSidebar ? NumCast(this.layoutDoc._width) * 1.2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth); - }; - - sidebarDown = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, () => setTimeout(this.toggleSidebar), true); - }; - sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => { - const bounds = this._ref.current!.getBoundingClientRect(); - this.layoutDoc._layout_sidebarWidthPercent = '' + 100 * Math.max(0, 1 - (e.clientX - bounds.left) / bounds.width) + '%'; - this.layoutDoc._layout_showSidebar = this.layoutDoc._layout_sidebarWidthPercent !== '0%'; - e.preventDefault(); - return false; - }; - - setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean) => void) => (this._setPreviewCursor = func); - - addDocumentWrapper = (doc: Doc | Doc[], annotationKey?: string) => { - return this.addDocument(doc, annotationKey); - }; - - pointerEvents = () => { - return this.props.isContentActive() === false ? 'none' : this.props.isContentActive() && this.props.pointerEvents?.() !== 'none' && !MarqueeOptionsMenu.Instance.isShown() ? 'all' : SnappingManager.GetIsDragging() ? undefined : 'none'; - }; - @computed get annotationLayer() { - return ( -
- {this.inlineTextAnnotations - .sort((a, b) => NumCast(a.y) - NumCast(b.y)) - .map(anno => ( - - ))} -
- ); - } - - getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => AnchorMenu.Instance?.GetAnchor(this._savedAnnotations, addAsAnnotation) ?? this.Document; - - /** - * render contents in allMapMarkers (e.g. images with exifData) into google maps as map marker - * @returns - */ - private renderMarkers = () => { - return this.allMapMarkers.map(place => ( - this.markerLoadHandler(marker, place)} onClick={(e: google.maps.MapMouseEvent) => this.markerClickHandler(e, place)} /> - )); - }; - - // TODO: auto center on select a document in the sidebar - private handleMapCenter = (map: google.maps.Map) => { - // console.log("print the selected views in selectionManager:") - // if (SelectionManager.Views().lastElement()) { - // console.log(SelectionManager.Views().lastElement()); - // } - }; - - panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth(); - panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1); - scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); - transparentFilter = () => [...this.props.childFilters(), Utils.TransparentBackgroundFilter]; - opaqueFilter = () => [...this.props.childFilters(), Utils.OpaqueBackgroundFilter]; - infoWidth = () => this.props.PanelWidth() / 5; - infoHeight = () => this.props.PanelHeight() / 5; - anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; - savedAnnotations = () => this._savedAnnotations; - - get MicrosoftMaps() { - return (window as any).Microsoft.Maps; - } - render() { - const renderAnnotations = (childFilters?: () => string[]) => null; - return ( -
-
e.stopPropagation()} - onPointerDown={async e => { - e.button === 0 && !e.ctrlKey && e.stopPropagation(); - }} - style={{ width: `calc(100% - ${this.layout_sidebarWidthPercent})`, pointerEvents: this.pointerEvents() }}> -
{renderAnnotations(this.transparentFilter)}
- {renderAnnotations(this.opaqueFilter)} - {SnappingManager.GetIsDragging() ? null : renderAnnotations()} - {this.annotationLayer} - -
- - - e.stopPropagation()} placeholder="Enter location" /> - - - {this.renderMarkers()} - {this.allMapMarkers - .filter(marker => marker.infoWindowOpen) - .map(marker => ( - - ))} - {/* {this.handleMapCenter(this._map)} */} - -
-
- {/* */} -
- -
- {this.sidebarHandle} -
- ); - } -} +// import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +// import { Autocomplete, GoogleMap, GoogleMapProps, Marker } from '@react-google-maps/api'; +// import { action, computed, IReactionDisposer, observable, ObservableMap, runInAction } from 'mobx'; +// import { observer } from 'mobx-react'; +// import * as React from 'react'; +// import { Doc, DocListCast, Opt } from '../../../../fields/Doc'; +// import { Id } from '../../../../fields/FieldSymbols'; +// import { NumCast, StrCast } from '../../../../fields/Types'; +// import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils'; +// import { Docs } from '../../../documents/Documents'; +// import { DragManager } from '../../../util/DragManager'; +// import { SnappingManager } from '../../../util/SnappingManager'; +// import { UndoManager } from '../../../util/UndoManager'; +// import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm'; +// import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent'; +// import { Colors } from '../../global/globalEnums'; +// import { AnchorMenu } from '../../pdf/AnchorMenu'; +// import { Annotation } from '../../pdf/Annotation'; +// import { SidebarAnnos } from '../../SidebarAnnos'; +// import { FieldView, FieldViewProps } from '../FieldView'; +// import { PinProps } from '../trails'; +// import './MapBox2.scss'; +// import { MapBoxInfoWindow } from './MapBoxInfoWindow'; + +// /** +// * MapBox2 architecture: +// * Main component: MapBox2.tsx +// * Supporting Components: SidebarAnnos, CollectionStackingView +// * +// * MapBox2 is a node that extends the ViewBoxAnnotatableComponent. Similar to PDFBox and WebBox, it supports interaction between sidebar content and document content. +// * The main body of MapBox2 uses Google Maps API to allow location retrieval, adding map markers, pan and zoom, and open street view. +// * Dash Document architecture is integrated with Maps API: When drag and dropping documents with ExifData (gps Latitude and Longitude information) available, +// * sidebarAddDocument function checks if the document contains lat & lng information, if it does, then the document is added to both the sidebar and the infowindow (a pop up corresponding to a map marker--pin on map). +// * The lat and lng field of the document is filled when importing (spec see ConvertDMSToDD method and processFileUpload method in Documents.ts). +// * A map marker is considered a document that contains a collection with stacking view of documents, it has a lat, lng location, which is passed to Maps API's custom marker (red pin) to be rendered on the google maps +// */ + +// // const _global = (window /* browser */ || global /* node */) as any; + +// const mapContainerStyle = { +// height: '100%', +// }; + +// const defaultCenter = { +// lat: 42.360081, +// lng: -71.058884, +// }; + +// const mapOptions = { +// fullscreenControl: false, +// }; + +// const apiKey = process.env.GOOGLE_MAPS; + +// const script = document.createElement('script'); +// script.defer = true; +// script.async = true; +// script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places,drawing`; +// console.log(script.src); +// document.head.appendChild(script); + +// /** +// * Consider integrating later: allows for drawing, circling, making shapes on map +// */ +// // const drawingManager = new window.google.maps.drawing.DrawingManager({ +// // drawingControl: true, +// // drawingControlOptions: { +// // position: google.maps.ControlPosition.TOP_RIGHT, +// // drawingModes: [ +// // google.maps.drawing.OverlayType.MARKER, +// // // currently we are not supporting the following drawing mode on map, a thought for future development +// // google.maps.drawing.OverlayType.CIRCLE, +// // google.maps.drawing.OverlayType.POLYLINE, +// // ], +// // }, +// // }); + +// // options for searchbox in Google Maps Places Autocomplete API +// const options = { +// fields: ['formatted_address', 'geometry', 'name'], // note: level of details is charged by item per retrieval, not recommended to return all fields +// strictBounds: false, +// types: ['establishment'], // type pf places, subject of change according to user need +// } as google.maps.places.AutocompleteOptions; + +// @observer +// export class MapBox2 extends ViewBoxAnnotatableComponent>() { +// private _dropDisposer?: DragManager.DragDropDisposer; +// private _disposers: { [name: string]: IReactionDisposer } = {}; +// private _annotationLayer: React.RefObject = React.createRef(); +// @observable private _overlayAnnoInfo: Opt; +// showInfo = action((anno: Opt) => (this._overlayAnnoInfo = anno)); +// public static LayoutString(fieldKey: string) { +// return FieldView.LayoutString(MapBox2, fieldKey); +// } +// public get SidebarKey() { +// return this.fieldKey + '_sidebar'; +// } +// private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean, doc: Opt) => void); +// @computed get inlineTextAnnotations() { +// return this.allMapMarkers.filter(a => a.text_inlineAnnotations); +// } + +// @observable private _map: google.maps.Map = null as unknown as google.maps.Map; +// @observable private selectedPlace: Doc | undefined; +// @observable private markerMap: { [id: string]: google.maps.Marker } = {}; +// @observable private center = navigator.geolocation ? navigator.geolocation.getCurrentPosition : defaultCenter; +// @observable private inputRef = React.createRef(); +// @observable private searchMarkers: google.maps.Marker[] = []; +// @observable private searchBox = new window.google.maps.places.Autocomplete(this.inputRef.current!, options); +// @observable private _savedAnnotations = new ObservableMap(); +// @computed get allSidebarDocs() { +// return DocListCast(this.dataDoc[this.SidebarKey]); +// } +// @computed get allMapMarkers() { +// return DocListCast(this.dataDoc[this.annotationKey]); +// } +// @observable private toggleAddMarker = false; + +// @observable _showSidebar = false; +// @computed get SidebarShown() { +// return this._showSidebar || this.layoutDoc._layout_showSidebar ? true : false; +// } + +// static _canAnnotate = true; +// static _hadSelection: boolean = false; +// private _sidebarRef = React.createRef(); +// private _ref: React.RefObject = React.createRef(); + +// componentDidMount() { +// this.props.setContentView?.(this); +// } + +// @action +// private setSearchBox = (searchBox: any) => { +// this.searchBox = searchBox; +// }; + +// // iterate allMarkers to size, center, and zoom map to contain all markers +// private fitBounds = (map: google.maps.Map) => { +// const curBounds = map.getBounds() ?? new window.google.maps.LatLngBounds(); +// const isFitting = this.allMapMarkers.reduce((fits, place) => fits && curBounds?.contains({ lat: NumCast(place.lat), lng: NumCast(place.lng) }), true as boolean); +// !isFitting && map.fitBounds(this.allMapMarkers.reduce((bounds, place) => bounds.extend({ lat: NumCast(place.lat), lng: NumCast(place.lng) }), new window.google.maps.LatLngBounds())); +// }; + +// /** +// * Custom control for add marker button +// * @param controlDiv +// * @param map +// */ +// private CenterControl = () => { +// const controlDiv = document.createElement('div'); +// controlDiv.className = 'MapBox2-addMarker'; +// // Set CSS for the control border. +// const controlUI = document.createElement('div'); +// controlUI.style.backgroundColor = '#fff'; +// controlUI.style.borderRadius = '3px'; +// controlUI.style.cursor = 'pointer'; +// controlUI.style.marginTop = '10px'; +// controlUI.style.borderRadius = '4px'; +// controlUI.style.marginBottom = '22px'; +// controlUI.style.textAlign = 'center'; +// controlUI.style.position = 'absolute'; +// controlUI.style.width = '32px'; +// controlUI.style.height = '32px'; +// controlUI.title = 'Click to toggle marker mode. In marker mode, click on map to place a marker.'; + +// const plIcon = document.createElement('img'); +// plIcon.src = 'https://cdn4.iconfinder.com/data/icons/wirecons-free-vector-icons/32/add-256.png'; +// plIcon.style.color = 'rgb(25,25,25)'; +// plIcon.style.fontFamily = 'Roboto,Arial,sans-serif'; +// plIcon.style.fontSize = '16px'; +// plIcon.style.lineHeight = '32px'; +// plIcon.style.left = '18'; +// plIcon.style.top = '15'; +// plIcon.style.position = 'absolute'; +// plIcon.width = 14; +// plIcon.height = 14; +// plIcon.innerHTML = 'Add'; +// controlUI.appendChild(plIcon); + +// // Set CSS for the control interior. +// const markerIcon = document.createElement('img'); +// markerIcon.src = 'https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678111-map-marker-1024.png'; +// markerIcon.style.color = 'rgb(25,25,25)'; +// markerIcon.style.fontFamily = 'Roboto,Arial,sans-serif'; +// markerIcon.style.fontSize = '16px'; +// markerIcon.style.lineHeight = '32px'; +// markerIcon.style.left = '-2'; +// markerIcon.style.top = '1'; +// markerIcon.width = 30; +// markerIcon.height = 30; +// markerIcon.style.position = 'absolute'; +// markerIcon.innerHTML = 'Add'; +// controlUI.appendChild(markerIcon); + +// // Setup the click event listeners +// controlUI.addEventListener('click', () => { +// if (this.toggleAddMarker === true) { +// this.toggleAddMarker = false; +// console.log('add marker button status:' + this.toggleAddMarker); +// controlUI.style.backgroundColor = '#fff'; +// markerIcon.style.color = 'rgb(25,25,25)'; +// } else { +// this.toggleAddMarker = true; +// console.log('add marker button status:' + this.toggleAddMarker); +// controlUI.style.backgroundColor = '#4476f7'; +// markerIcon.style.color = 'rgb(255,255,255)'; +// } +// }); +// controlDiv.appendChild(controlUI); +// return controlDiv; +// }; + +// /** +// * Place the marker on google maps & store the empty marker as a MapMarker Document in allMarkers list +// * @param position - the LatLng position where the marker is placed +// * @param map +// */ +// @action +// private placeMarker = (position: google.maps.LatLng, map: google.maps.Map) => { +// const marker = new google.maps.Marker({ +// position: position, +// map: map, +// }); +// map.panTo(position); +// const mapMarker = Docs.Create.PushpinDocument(NumCast(position.lat()), NumCast(position.lng()), false, [], {}); +// this.addDocument(mapMarker, this.annotationKey); +// }; + +// _loadPending = true; +// /** +// * store a reference to google map instance +// * setup the drawing manager on the top right corner of map +// * fit map bounds to contain all markers +// * @param map +// */ +// @action +// private loadHandler = (map: google.maps.Map) => { +// this._map = map; +// this._loadPending = true; +// const centerControlDiv = this.CenterControl(); +// map.controls[google.maps.ControlPosition.TOP_RIGHT].push(centerControlDiv); +// //drawingManager.setMap(map); +// // if (navigator.geolocation) { +// // navigator.geolocation.getCurrentPosition( +// // (position: Position) => { +// // const pos = { +// // lat: position.coords.latitude, +// // lng: position.coords.longitude, +// // }; +// // this._map.setCenter(pos); +// // } +// // ); +// // } else { +// // alert("Your geolocation is not supported by browser.") +// // }; +// map.setZoom(NumCast(this.dataDoc.map_zoom, 2.5)); +// map.setCenter(new google.maps.LatLng(NumCast(this.dataDoc.mapLat), NumCast(this.dataDoc.mapLng))); +// setTimeout(() => { +// if (this._loadPending && this._map.getBounds()) { +// this._loadPending = false; +// this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map); +// } +// }, 250); +// // listener to addmarker event +// this._map.addListener('click', (e: MouseEvent) => { +// if (this.toggleAddMarker === true) { +// this.placeMarker((e as any).latLng, map); +// } +// }); +// }; + +// @action +// centered = () => { +// if (this._loadPending && this._map.getBounds()) { +// this._loadPending = false; +// this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map); +// } +// this.dataDoc.mapLat = this._map.getCenter()?.lat(); +// this.dataDoc.mapLng = this._map.getCenter()?.lng(); +// }; + +// @action +// zoomChanged = () => { +// if (this._loadPending && this._map.getBounds()) { +// this._loadPending = false; +// this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map); +// } +// this.dataDoc.map_zoom = this._map.getZoom(); +// }; + +// /** +// * Load and render all map markers +// * @param marker +// * @param place +// */ +// @action +// private markerLoadHandler = (marker: google.maps.Marker, place: Doc) => { +// place[Id] ? (this.markerMap[place[Id]] = marker) : null; +// }; + +// /** +// * on clicking the map marker, set the selected place to the marker document & set infowindowopen to be true +// * @param e +// * @param place +// */ +// @action +// private markerClickHandler = (e: google.maps.MapMouseEvent, place: Doc) => { +// // set which place was clicked +// this.selectedPlace = place; +// place.infoWindowOpen = true; +// }; + +// /** +// * Called when dragging documents into map sidebar or directly into infowindow; to create a map marker, ref to MapMarkerDocument in Documents.ts +// * @param doc +// * @param sidebarKey +// * @returns +// */ +// sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => { +// console.log('print all sidebar Docs'); +// if (!this.layoutDoc._layout_showSidebar) this.toggleSidebar(); +// const docs = doc instanceof Doc ? [doc] : doc; +// docs.forEach(doc => { +// if (doc.lat !== undefined && doc.lng !== undefined) { +// const existingMarker = this.allMapMarkers.find(marker => marker.lat === doc.lat && marker.lng === doc.lng); +// if (existingMarker) { +// Doc.AddDocToList(existingMarker, 'data', doc); +// } else { +// const marker = Docs.Create.PushpinDocument(NumCast(doc.lat), NumCast(doc.lng), false, [doc], {}); +// this.addDocument(marker, this.annotationKey); +// } +// } +// }); //add to annotation list + +// return this.addDocument(doc, sidebarKey); // add to sidebar list +// }; + +// /** +// * Removing documents from the sidebar +// * @param doc +// * @param sidebarKey +// * @returns +// */ +// sidebarRemoveDocument = (doc: Doc | Doc[], sidebarKey?: string) => { +// if (this.layoutDoc._layout_showSidebar) this.toggleSidebar(); +// const docs = doc instanceof Doc ? [doc] : doc; +// return this.removeDocument(doc, sidebarKey); +// }; + +// /** +// * Toggle sidebar onclick the tiny comment button on the top right corner +// * @param e +// */ +// sidebarBtnDown = (e: React.PointerEvent) => { +// setupMoveUpEvents( +// this, +// e, +// (e, down, delta) => +// runInAction(() => { +// const localDelta = this.props +// .ScreenToLocalTransform() +// .scale(this.props.NativeDimScaling?.() || 1) +// .transformDirection(delta[0], delta[1]); +// const fullWidth = NumCast(this.layoutDoc._width); +// const mapWidth = fullWidth - this.sidebarWidth(); +// if (this.sidebarWidth() + localDelta[0] > 0) { +// this._showSidebar = true; +// this.layoutDoc._width = fullWidth + localDelta[0]; +// this.layoutDoc._layout_sidebarWidthPercent = ((100 * (this.sidebarWidth() + localDelta[0])) / (fullWidth + localDelta[0])).toString() + '%'; +// } else { +// this._showSidebar = false; +// this.layoutDoc._width = mapWidth; +// this.layoutDoc._layout_sidebarWidthPercent = '0%'; +// } +// return false; +// }), +// emptyFunction, +// () => UndoManager.RunInBatch(this.toggleSidebar, 'toggle sidebar map') +// ); +// }; + +// sidebarWidth = () => (Number(this.layout_sidebarWidthPercent.substring(0, this.layout_sidebarWidthPercent.length - 1)) / 100) * this.props.PanelWidth(); +// @computed get layout_sidebarWidthPercent() { +// return StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%'); +// } +// @computed get sidebarColor() { +// return StrCast(this.layoutDoc.sidebar_color, StrCast(this.layoutDoc[this.props.fieldKey + '_backgroundColor'], '#e4e4e4')); +// } + +// /** +// * function that reads the place inputed from searchbox, then zoom in on the location that's been autocompleted; +// * add a customized temporary marker on the map +// */ +// @action +// private handlePlaceChanged = () => { +// const place = this.searchBox.getPlace(); + +// if (!place.geometry || !place.geometry.location) { +// // user entered the name of a place that wasn't suggested & pressed the enter key, or place details request failed +// window.alert("No details available for input: '" + place.name + "'"); +// return; +// } + +// // zoom in on the location of the search result +// if (place.geometry.viewport) { +// this._map.fitBounds(place.geometry.viewport); +// } else { +// this._map.setCenter(place.geometry.location); +// this._map.setZoom(17); +// } + +// // customize icon => customized icon for the nature of the location selected +// const icon = { +// url: place.icon as string, +// size: new google.maps.Size(71, 71), +// origin: new google.maps.Point(0, 0), +// anchor: new google.maps.Point(17, 34), +// scaledSize: new google.maps.Size(25, 25), +// }; + +// // put temporary cutomized marker on searched location +// this.searchMarkers.forEach(marker => { +// marker.setMap(null); +// }); +// this.searchMarkers = []; +// this.searchMarkers.push( +// new window.google.maps.Marker({ +// map: this._map, +// icon, +// title: place.name, +// position: place.geometry.location, +// }) +// ); +// }; + +// /** +// * Handles toggle of sidebar on click the little comment button +// */ +// @computed get sidebarHandle() { +// return ( +//
+// +//
+// ); +// } + +// // TODO: Adding highlight box layer to Maps +// @action +// toggleSidebar = () => { +// //1.2 * w * ? = .2 * w .2/1.2 +// const prevWidth = this.sidebarWidth(); +// this.layoutDoc._layout_showSidebar = (this.layoutDoc._layout_sidebarWidthPercent = StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%') === '0%' ? `${(100 * 0.2) / 1.2}%` : '0%') !== '0%'; +// this.layoutDoc._width = this.layoutDoc._layout_showSidebar ? NumCast(this.layoutDoc._width) * 1.2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth); +// }; + +// sidebarDown = (e: React.PointerEvent) => { +// setupMoveUpEvents(this, e, this.sidebarMove, emptyFunction, () => setTimeout(this.toggleSidebar), true); +// }; +// sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => { +// const bounds = this._ref.current!.getBoundingClientRect(); +// this.layoutDoc._layout_sidebarWidthPercent = '' + 100 * Math.max(0, 1 - (e.clientX - bounds.left) / bounds.width) + '%'; +// this.layoutDoc._layout_showSidebar = this.layoutDoc._layout_sidebarWidthPercent !== '0%'; +// e.preventDefault(); +// return false; +// }; + +// setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean) => void) => (this._setPreviewCursor = func); + +// addDocumentWrapper = (doc: Doc | Doc[], annotationKey?: string) => { +// return this.addDocument(doc, annotationKey); +// }; + +// pointerEvents = () => { +// return this.props.isContentActive() === false ? 'none' : this.props.isContentActive() && this.props.pointerEvents?.() !== 'none' && !MarqueeOptionsMenu.Instance.isShown() ? 'all' : SnappingManager.GetIsDragging() ? undefined : 'none'; +// }; +// @computed get annotationLayer() { +// return ( +//
+// {this.inlineTextAnnotations +// .sort((a, b) => NumCast(a.y) - NumCast(b.y)) +// .map(anno => ( +// +// ))} +//
+// ); +// } + +// getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => AnchorMenu.Instance?.GetAnchor(this._savedAnnotations, addAsAnnotation) ?? this.Document; + +// /** +// * render contents in allMapMarkers (e.g. images with exifData) into google maps as map marker +// * @returns +// */ +// private renderMarkers = () => { +// return this.allMapMarkers.map(place => ( +// this.markerLoadHandler(marker, place)} onClick={(e: google.maps.MapMouseEvent) => this.markerClickHandler(e, place)} /> +// )); +// }; + +// // TODO: auto center on select a document in the sidebar +// private handleMapCenter = (map: google.maps.Map) => { +// // console.log("print the selected views in selectionManager:") +// // if (SelectionManager.Views().lastElement()) { +// // console.log(SelectionManager.Views().lastElement()); +// // } +// }; + +// panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth(); +// panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1); +// scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop)); +// transparentFilter = () => [...this.props.childFilters(), Utils.TransparentBackgroundFilter]; +// opaqueFilter = () => [...this.props.childFilters(), Utils.OpaqueBackgroundFilter]; +// infoWidth = () => this.props.PanelWidth() / 5; +// infoHeight = () => this.props.PanelHeight() / 5; +// anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; +// savedAnnotations = () => this._savedAnnotations; + +// get MicrosoftMaps() { +// return (window as any).Microsoft.Maps; +// } +// render() { +// const renderAnnotations = (childFilters?: () => string[]) => null; +// return ( +//
+//
e.stopPropagation()} +// onPointerDown={async e => { +// e.button === 0 && !e.ctrlKey && e.stopPropagation(); +// }} +// style={{ width: `calc(100% - ${this.layout_sidebarWidthPercent})`, pointerEvents: this.pointerEvents() }}> +//
{renderAnnotations(this.transparentFilter)}
+// {renderAnnotations(this.opaqueFilter)} +// {SnappingManager.GetIsDragging() ? null : renderAnnotations()} +// {this.annotationLayer} + +//
+// +// +// e.stopPropagation()} placeholder="Enter location" /> +// + +// {this.renderMarkers()} +// {this.allMapMarkers +// .filter(marker => marker.infoWindowOpen) +// .map(marker => ( +// +// ))} +// {/* {this.handleMapCenter(this._map)} */} +// +//
+//
+// {/* */} +//
+// +//
+// {this.sidebarHandle} +//
+// ); +// } +// } diff --git a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx index 415a9d776..a9c6ba22c 100644 --- a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx +++ b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx @@ -1,95 +1,95 @@ -import { InfoWindow } from '@react-google-maps/api'; -import { action } from 'mobx'; -import { observer } from 'mobx-react'; -import * as React from 'react'; -import { Doc } from '../../../../fields/Doc'; -import { Id } from '../../../../fields/FieldSymbols'; -import { emptyFunction, returnAll, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents } from '../../../../Utils'; -import { Docs } from '../../../documents/Documents'; -import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; -import { CollectionNoteTakingView } from '../../collections/CollectionNoteTakingView'; -import { CollectionStackingView } from '../../collections/CollectionStackingView'; -import { ViewBoxAnnotatableProps } from '../../DocComponent'; -import { FieldViewProps } from '../FieldView'; -import { FormattedTextBox } from '../formattedText/FormattedTextBox'; -import './MapBox.scss'; +// import { InfoWindow } from '@react-google-maps/api'; +// import { action } from 'mobx'; +// import { observer } from 'mobx-react'; +// import * as React from 'react'; +// import { Doc } from '../../../../fields/Doc'; +// import { Id } from '../../../../fields/FieldSymbols'; +// import { emptyFunction, returnAll, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents } from '../../../../Utils'; +// import { Docs } from '../../../documents/Documents'; +// import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; +// import { CollectionNoteTakingView } from '../../collections/CollectionNoteTakingView'; +// import { CollectionStackingView } from '../../collections/CollectionStackingView'; +// import { ViewBoxAnnotatableProps } from '../../DocComponent'; +// import { FieldViewProps } from '../FieldView'; +// import { FormattedTextBox } from '../formattedText/FormattedTextBox'; +// import './MapBox.scss'; -interface MapBoxInfoWindowProps { - place: Doc; - renderDepth: number; - markerMap: { [id: string]: google.maps.Marker }; - isAnyChildContentActive: () => boolean; -} -@observer -export class MapBoxInfoWindow extends React.Component { - @action - private handleInfoWindowClose = () => { - if (this.props.place.infoWindowOpen) { - this.props.place.infoWindowOpen = false; - } - this.props.place.infoWindowOpen = false; - }; +// interface MapBoxInfoWindowProps { +// place: Doc; +// renderDepth: number; +// markerMap: { [id: string]: google.maps.Marker }; +// isAnyChildContentActive: () => boolean; +// } +// @observer +// export class MapBoxInfoWindow extends React.Component { +// @action +// private handleInfoWindowClose = () => { +// if (this.props.place.infoWindowOpen) { +// this.props.place.infoWindowOpen = false; +// } +// this.props.place.infoWindowOpen = false; +// }; - addNoteClick = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => { - const newDoc = Docs.Create.TextDocument('Note', { _layout_autoHeight: true }); - FormattedTextBox.SetSelectOnLoad(newDoc); // 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.props.place, 'data', newDoc); - this._stack?.scrollToBottom(); - e.stopPropagation(); - e.preventDefault(); - }); - }; +// addNoteClick = (e: React.PointerEvent) => { +// setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => { +// const newDoc = Docs.Create.TextDocument('Note', { _layout_autoHeight: true }); +// FormattedTextBox.SetSelectOnLoad(newDoc); // 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.props.place, 'data', newDoc); +// this._stack?.scrollToBottom(); +// e.stopPropagation(); +// e.preventDefault(); +// }); +// }; - _stack: CollectionStackingView | CollectionNoteTakingView | null | undefined; - childLayoutFitWidth = (doc: Doc) => doc.type === DocumentType.RTF; - addDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((p, d) => p && Doc.AddDocToList(this.props.place, 'data', d), true as boolean); - removeDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((p, d) => p && Doc.RemoveDocFromList(this.props.place, 'data', d), true as boolean); - render() { - return ( - -
-
- (this._stack = r)} - {...this.props} - setContentView={emptyFunction} - Document={this.props.place} - TemplateDataDocument={undefined} - fieldKey="data" - NativeWidth={returnZero} - NativeHeight={returnZero} - childFilters={returnEmptyFilter} - setHeight={emptyFunction} - isAnnotationOverlay={false} - select={emptyFunction} - NativeDimScaling={returnOne} - isContentActive={returnTrue} - chromeHidden={true} - childHideResizeHandles={true} - childHideDecorationTitle={true} - childLayoutFitWidth={this.childLayoutFitWidth} - // childDocumentsActive={returnFalse} - removeDocument={this.removeDoc} - addDocument={this.addDoc} - renderDepth={this.props.renderDepth + 1} - type_collection={CollectionViewType.Stacking} - pointerEvents={returnAll} - /> -
-
-
{ - e.stopPropagation(); - e.preventDefault(); - }}> - Add Note -
-
-
- ); - } -} +// _stack: CollectionStackingView | CollectionNoteTakingView | null | undefined; +// childLayoutFitWidth = (doc: Doc) => doc.type === DocumentType.RTF; +// addDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((p, d) => p && Doc.AddDocToList(this.props.place, 'data', d), true as boolean); +// removeDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((p, d) => p && Doc.RemoveDocFromList(this.props.place, 'data', d), true as boolean); +// render() { +// return ( +// +//
+//
+// (this._stack = r)} +// {...this.props} +// setContentView={emptyFunction} +// Document={this.props.place} +// TemplateDataDocument={undefined} +// fieldKey="data" +// NativeWidth={returnZero} +// NativeHeight={returnZero} +// childFilters={returnEmptyFilter} +// setHeight={emptyFunction} +// isAnnotationOverlay={false} +// select={emptyFunction} +// NativeDimScaling={returnOne} +// isContentActive={returnTrue} +// chromeHidden={true} +// childHideResizeHandles={true} +// childHideDecorationTitle={true} +// childLayoutFitWidth={this.childLayoutFitWidth} +// // childDocumentsActive={returnFalse} +// removeDocument={this.removeDoc} +// addDocument={this.addDoc} +// renderDepth={this.props.renderDepth + 1} +// type_collection={CollectionViewType.Stacking} +// pointerEvents={returnAll} +// /> +//
+//
+//
{ +// e.stopPropagation(); +// e.preventDefault(); +// }}> +// Add Note +//
+//
+//
+// ); +// } +// } diff --git a/src/client/views/nodes/formattedText/EquationEditor.tsx b/src/client/views/nodes/formattedText/EquationEditor.tsx new file mode 100644 index 000000000..bde6c1315 --- /dev/null +++ b/src/client/views/nodes/formattedText/EquationEditor.tsx @@ -0,0 +1,87 @@ +import React, { Component, createRef } from 'react'; + +// Import JQuery, required for the functioning of the equation editor +import $ from 'jquery'; + +// Import the styles from the Mathquill editor +import 'mathquill/build/mathquill.css'; + +// 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'); + +type EquationEditorProps = { + onChange(latex: string): void; + value: string; + spaceBehavesLikeTab?: boolean; + autoCommands: string; + autoOperatorNames: string; + onEnter?(): void; +}; + +/** + * @typedef {EquationEditorProps} props + * @prop {Function} onChange Triggered when content of the equation editor changes + * @prop {string} value Content of the equation handler + * @prop {boolean}[false] spaceBehavesLikeTab Whether spacebar should simulate tab behavior + * @prop {string} autoCommands List of commands for which you only have to type the name of the + * command with a \ in front of it. Examples: pi theta rho sum + * @prop {string} autoOperatorNames List of operators for which you only have to type the name of the + * operator with a \ in front of it. Examples: sin cos tan + * @prop {Function} onEnter Triggered when enter is pressed in the equation editor + * @extends {Component} + */ +class EquationEditor extends Component { + element: any; + mathField: any; + ignoreEditEvents: number; + + // Element needs to be in the class format and thus requires a constructor. The steps that are run + // in the constructor is to make sure that React can succesfully communicate with the equation + // editor. + constructor(props: EquationEditorProps) { + super(props); + + this.element = createRef(); + this.mathField = null; + + // MathJax apparently fire 2 edit events on startup. + this.ignoreEditEvents = 2; + } + + componentDidMount() { + const { onChange, value, spaceBehavesLikeTab, autoCommands, autoOperatorNames, onEnter } = this.props; + + const config = { + handlers: { + edit: () => { + if (this.ignoreEditEvents > 0) { + this.ignoreEditEvents -= 1; + return; + } + if (this.mathField.latex() !== value) { + onChange(this.mathField.latex()); + } + }, + enter: onEnter, + }, + spaceBehavesLikeTab, + autoCommands, + autoOperatorNames, + }; + + // @ts-ignore + this.mathField = (MathQuill as any).MathField(this.element.current, config); + this.mathField.latex(value || ''); + } + + render() { + return ; + } +} + +export default EquationEditor; diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx index 75238a6ce..5ee5d25c3 100644 --- a/src/client/views/nodes/formattedText/EquationView.tsx +++ b/src/client/views/nodes/formattedText/EquationView.tsx @@ -1,4 +1,4 @@ -import EquationEditor from 'equation-editor-react'; +import EquationEditor from './EquationEditor'; import { IReactionDisposer, trace } from 'mobx'; import { observer } from 'mobx-react'; import { TextSelection } from 'prosemirror-state'; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 0f9dd6f8b..4f8e8769a 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -70,7 +70,7 @@ import { RichTextMenu, RichTextMenuPlugin } from './RichTextMenu'; import { RichTextRules } from './RichTextRules'; import { schema } from './schema_rts'; import { SummaryView } from './SummaryView'; -import * as applyDevTools from 'prosemirror-dev-tools'; +// import * as applyDevTools from 'prosemirror-dev-tools'; import * as React from 'react'; export const GoogleRef = 'googleDocId'; type PullHandler = (exportState: Opt, dataDoc: Doc) => void; -- cgit v1.2.3-70-g09d2 From 380ee1acac1c0b7972d7d423cf804af146dc0edf Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 10 Dec 2023 20:19:27 -0500 Subject: massive changes to use mobx 6 which means not accessing props directly in @computed functions. --- package-lock.json | 2762 +++++++++++++++++--- package.json | 13 +- src/.babelrc | 3 + src/Utils.ts | 7 + src/client/DocServer.ts | 2 +- src/client/documents/DocumentTypes.ts | 1 - src/client/documents/Documents.ts | 13 +- src/client/util/DocumentManager.ts | 11 +- .../util/Import & Export/DirectoryImportBox.tsx | 3 +- src/client/util/LinkManager.ts | 14 +- src/client/util/RTFMarkup.tsx | 2 +- src/client/util/SelectionManager.ts | 20 +- src/client/util/ServerStats.tsx | 6 +- src/client/util/SettingsManager.tsx | 8 +- src/client/util/SharingManager.tsx | 4 +- src/client/util/SnappingManager.ts | 2 +- src/client/views/AntimodeMenu.tsx | 19 +- src/client/views/AudioWaveform.scss | 17 - src/client/views/AudioWaveform.tsx | 117 - src/client/views/ContextMenu.tsx | 99 +- src/client/views/ContextMenuItem.tsx | 20 +- src/client/views/DocComponent.tsx | 61 +- src/client/views/DocumentButtonBar.tsx | 61 +- src/client/views/DocumentDecorations.tsx | 74 +- src/client/views/EditableView.tsx | 111 +- src/client/views/InkStrokeProperties.ts | 2 +- src/client/views/InkingStroke.tsx | 4 +- src/client/views/MainView.tsx | 19 +- src/client/views/MainViewModal.tsx | 2 - src/client/views/MarqueeAnnotator.tsx | 19 +- src/client/views/PreviewCursor.tsx | 135 +- src/client/views/PropertiesView.tsx | 53 +- src/client/views/StyleProvider.tsx | 4 +- .../views/collections/CollectionDockingView.tsx | 45 +- .../collections/CollectionMasonryViewFieldRow.tsx | 101 +- src/client/views/collections/CollectionMenu.tsx | 45 +- .../views/collections/CollectionNoteTakingView.tsx | 1 - .../views/collections/CollectionPileView.tsx | 2 +- .../collections/CollectionStackedTimeline.tsx | 217 +- .../views/collections/CollectionStackingView.tsx | 187 +- .../CollectionStackingViewFieldColumn.tsx | 139 +- src/client/views/collections/CollectionSubView.tsx | 92 +- .../views/collections/CollectionTreeView.tsx | 192 +- src/client/views/collections/CollectionView.tsx | 53 +- src/client/views/collections/TabDocView.tsx | 91 +- src/client/views/collections/TreeView.tsx | 505 ++-- .../CollectionFreeFormInfoState.tsx | 16 +- .../CollectionFreeFormInfoUI.tsx | 38 +- .../CollectionFreeFormLinkView.tsx | 4 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 376 +-- .../collections/collectionFreeForm/MarqueeView.tsx | 142 +- .../collectionGrid/CollectionGridView.tsx | 2 - .../collectionLinear/CollectionLinearView.tsx | 44 +- .../CollectionMulticolumnView.tsx | 1 - .../CollectionMultirowView.tsx | 1 - .../collectionSchema/CollectionSchemaView.tsx | 10 +- .../collectionSchema/SchemaColumnHeader.tsx | 2 +- .../collections/collectionSchema/SchemaRowBox.tsx | 4 +- .../collectionSchema/SchemaTableCell.tsx | 141 +- src/client/views/global/globalScripts.ts | 8 +- src/client/views/linking/LinkMenu.tsx | 8 +- src/client/views/linking/LinkMenuItem.tsx | 96 +- src/client/views/nodes/AudioBox.tsx | 75 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 109 +- src/client/views/nodes/ColorBox.scss | 22 - src/client/views/nodes/ColorBox.tsx | 88 - .../views/nodes/DataVizBox/components/TableBox.tsx | 4 +- src/client/views/nodes/DocumentContentsView.tsx | 60 +- src/client/views/nodes/DocumentLinksButton.tsx | 106 +- src/client/views/nodes/DocumentView.tsx | 419 +-- src/client/views/nodes/EquationBox.tsx | 34 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 32 +- src/client/views/nodes/FunctionPlotBox.tsx | 37 +- src/client/views/nodes/ImageBox.tsx | 198 +- src/client/views/nodes/KeyValueBox.tsx | 38 +- src/client/views/nodes/KeyValuePair.tsx | 37 +- src/client/views/nodes/LabelBox.tsx | 29 +- src/client/views/nodes/LinkBox.tsx | 2 +- src/client/views/nodes/LinkDocPreview.tsx | 4 +- src/client/views/nodes/LoadingBox.tsx | 14 +- src/client/views/nodes/MapBox/MapBox.tsx | 84 +- src/client/views/nodes/MapBox/MapBox2.tsx | 2 +- src/client/views/nodes/MapBox/MapPushpinBox.tsx | 14 +- src/client/views/nodes/PDFBox.tsx | 95 +- src/client/views/nodes/ScreenshotBox.tsx | 2 +- src/client/views/nodes/VideoBox.tsx | 123 +- src/client/views/nodes/WebBox.tsx | 4 +- src/client/views/nodes/audio/AudioWaveform.scss | 17 + src/client/views/nodes/audio/AudioWaveform.tsx | 127 + src/client/views/nodes/audio/WaveCanvas.tsx | 100 + .../views/nodes/formattedText/DashDocView.tsx | 2 +- .../views/nodes/formattedText/DashFieldView.tsx | 14 +- .../views/nodes/formattedText/EquationEditor.scss | 468 ++++ .../views/nodes/formattedText/EquationEditor.tsx | 8 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 213 +- .../views/nodes/formattedText/RichTextMenu.tsx | 48 +- src/client/views/nodes/trails/PresBox.tsx | 61 +- src/client/views/nodes/trails/PresElementBox.tsx | 64 +- src/client/views/pdf/AnchorMenu.tsx | 24 +- src/client/views/pdf/PDFViewer.tsx | 151 +- src/client/views/topbar/TopBar.tsx | 1 - src/fields/Doc.ts | 40 +- src/fields/List.ts | 5 +- src/fields/util.ts | 2 +- src/server/ApiManagers/GooglePhotosManager.ts | 155 +- src/server/DashUploadUtils.ts | 27 +- tsconfig.json | 2 +- webpack.config.js | 7 +- 108 files changed, 6103 insertions(+), 3316 deletions(-) create mode 100644 src/.babelrc delete mode 100644 src/client/views/AudioWaveform.scss delete mode 100644 src/client/views/AudioWaveform.tsx delete mode 100644 src/client/views/nodes/ColorBox.scss delete mode 100644 src/client/views/nodes/ColorBox.tsx create mode 100644 src/client/views/nodes/audio/AudioWaveform.scss create mode 100644 src/client/views/nodes/audio/AudioWaveform.tsx create mode 100644 src/client/views/nodes/audio/WaveCanvas.tsx create mode 100644 src/client/views/nodes/formattedText/EquationEditor.scss (limited to 'src/client/views/nodes/EquationBox.tsx') diff --git a/package-lock.json b/package-lock.json index 8cbd29629..9afc22828 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,8 @@ "version": "1.0.0", "dependencies": { "@azure/storage-blob": "^12.17.0", + "@babel/preset-env": "^7.23.5", + "@babel/preset-react": "^7.23.3", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@ffmpeg/core": "0.12.4", @@ -41,6 +43,7 @@ "async": "^3.2.5", "axios": "^1.6.2", "babel": "^6.23.0", + "babel-loader": "^9.1.3", "bcrypt-nodejs": "0.0.3", "bezier-curve": "^1.0.0", "bezier-js": "^6.1.4", @@ -55,7 +58,6 @@ "canvas": "^2.11.2", "chart.js": "^4.4.0", "child_process": "^1.0.2", - "chrome": "^0.1.0", "class-transformer": "^0.5.1", "color": "^4.2.3", "colors": "^1.4.0", @@ -105,6 +107,7 @@ "image-size": "^1.0.2", "image-size-stream": "^1.1.0", "jimp": "^0.22.10", + "jpeg-autorotate": "^9.0.0", "jquery": "^3.7.1", "js-datepicker": "^5.18.2", "jsonschema": "^1.4.1", @@ -114,9 +117,9 @@ "md5-file": "^5.0.0", "memorystream": "^0.3.1", "mobile-detect": "^1.4.5", - "mobx": "^5.15.7", - "mobx-react": "^5.4.4", - "mobx-utils": "^5.6.2", + "mobx": "^6.12.0", + "mobx-react": "^9.1.0", + "mobx-utils": "^6.0.8", "mongodb": "^6.3.0", "mongoose": "^8.0.2", "node-stream-zip": "^1.15.0", @@ -151,7 +154,6 @@ "raw-loader": "^4.0.2", "rc-switch": "^4.1.0", "react": "^18.2.0", - "react-audio-waveform": "0.0.5", "react-autosuggest": "^10.1.0", "react-color": "^2.19.3", "react-compound-slider": "^3.4.0", @@ -164,7 +166,6 @@ "react-markdown": "^9.0.1", "react-measure": "^2.5.2", "react-resizable": "^3.0.5", - "react-reveal": "^1.2.2", "react-select": "^5.8.0", "readline": "^1.3.0", "recharts": "^2.10.3", @@ -288,271 +289,1867 @@ "node": ">=0.10.0" } }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@azure/abort-controller": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.1.0.tgz", "integrity": "sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==", "dependencies": { - "tslib": "^2.2.0" + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.4.0.tgz", + "integrity": "sha512-HFrcTgmuSuukRf/EdPmqBrc5l6Q5Uu+2TbuhaKbgaCpP2TfAeiNaQPAadxO+CYBRHGUzIDteMAjFspFLDLnKVQ==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-http": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-3.0.2.tgz", + "integrity": "sha512-o1wR9JrmoM0xEAa0Ue7Sp8j+uJvmqYaGoHOCT5qaVYmvgmnZDC0OvQimPA/JR3u77Sz6D1y3Xmk1y69cDU9q9A==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.3.0", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/core-util": "^1.1.1", + "@azure/logger": "^1.0.0", + "@types/node-fetch": "^2.5.0", + "@types/tunnel": "^0.0.3", + "form-data": "^4.0.0", + "node-fetch": "^2.6.7", + "process": "^0.11.10", + "tslib": "^2.2.0", + "tunnel": "^0.0.6", + "uuid": "^8.3.0", + "xml2js": "^0.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@azure/core-http/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@azure/core-http/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@azure/core-lro": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.5.3.tgz", + "integrity": "sha512-ubkOf2YCnVtq7KqEJQqAI8dDD5rH1M6OP5kW0KO/JQyTaxLA0N0pjFWvvaysCj9eHMNBcuuoZXhhl0ypjod2DA==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-util": "^1.2.0", + "@azure/logger": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@azure/core-paging": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.5.0.tgz", + "integrity": "sha512-zqWdVIt+2Z+3wqxEOGzR5hXFZ8MGKK52x4vFLw8n58pR6ZfKRx3EXYTxTaYxYHc/PexPUTyimcTWFJbji9Z6Iw==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@azure/core-tracing": { + "version": "1.0.0-preview.13", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", + "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", + "dependencies": { + "@opentelemetry/api": "^1.0.1", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@azure/core-util": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.3.2.tgz", + "integrity": "sha512-2bECOUh88RvL1pMZTcc6OzfobBeWDBf5oBbhjIhT1MV9otMVWCzpOJkkiKtrnO88y5GGBelgY8At73KGAdbkeQ==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@azure/logger": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.4.tgz", + "integrity": "sha512-ustrPY8MryhloQj7OWGe+HrYx+aoiOxzbXTtgblbV3xwCqpzUK36phH3XNHQKj3EPonyFUuDTfR3qFhTEAuZEg==", + "dependencies": { + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@azure/storage-blob": { + "version": "12.17.0", + "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.17.0.tgz", + "integrity": "sha512-sM4vpsCpcCApagRW5UIjQNlNylo02my2opgp0Emi8x888hZUvJ3dN69Oq20cEGXkMUWnoCrBaB0zyS3yeB87sQ==", + "dependencies": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-http": "^3.0.0", + "@azure/core-lro": "^2.2.0", + "@azure/core-paging": "^1.1.1", + "@azure/core-tracing": "1.0.0-preview.13", + "@azure/logger": "^1.0.0", + "events": "^3.0.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", + "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", + "peer": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.5", + "@babel/parser": "^7.23.5", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "peer": true + }, + "node_modules/@babel/core/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "peer": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/core/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "peer": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/core/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "peer": true + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", + "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", + "dependencies": { + "@babel/types": "^7.23.5", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.5.tgz", + "integrity": "sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz", + "integrity": "sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "dependencies": { + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", + "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", + "peer": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", + "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", + "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", + "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz", + "integrity": "sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", + "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz", + "integrity": "sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", + "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", + "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", + "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.5.tgz", + "integrity": "sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", + "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", + "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", + "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", + "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", + "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz", + "integrity": "sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", + "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", + "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", + "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz", + "integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==", + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", + "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", + "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", + "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", + "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", + "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", + "dependencies": { + "@babel/compat-data": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", + "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "engines": { - "node": ">=12.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@azure/core-auth": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.4.0.tgz", - "integrity": "sha512-HFrcTgmuSuukRf/EdPmqBrc5l6Q5Uu+2TbuhaKbgaCpP2TfAeiNaQPAadxO+CYBRHGUzIDteMAjFspFLDLnKVQ==", + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", + "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", "dependencies": { - "@azure/abort-controller": "^1.0.0", - "tslib": "^2.2.0" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { - "node": ">=12.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@azure/core-http": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-3.0.2.tgz", - "integrity": "sha512-o1wR9JrmoM0xEAa0Ue7Sp8j+uJvmqYaGoHOCT5qaVYmvgmnZDC0OvQimPA/JR3u77Sz6D1y3Xmk1y69cDU9q9A==", + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", "dependencies": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/core-util": "^1.1.1", - "@azure/logger": "^1.0.0", - "@types/node-fetch": "^2.5.0", - "@types/tunnel": "^0.0.3", - "form-data": "^4.0.0", - "node-fetch": "^2.6.7", - "process": "^0.11.10", - "tslib": "^2.2.0", - "tunnel": "^0.0.6", - "uuid": "^8.3.0", - "xml2js": "^0.5.0" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { - "node": ">=14.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@azure/core-http/node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", + "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { - "node": ">= 6" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@azure/core-http/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", + "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@azure/core-lro": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.5.3.tgz", - "integrity": "sha512-ubkOf2YCnVtq7KqEJQqAI8dDD5rH1M6OP5kW0KO/JQyTaxLA0N0pjFWvvaysCj9eHMNBcuuoZXhhl0ypjod2DA==", + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", "dependencies": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-util": "^1.2.0", - "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { - "node": ">=14.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@azure/core-paging": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.5.0.tgz", - "integrity": "sha512-zqWdVIt+2Z+3wqxEOGzR5hXFZ8MGKK52x4vFLw8n58pR6ZfKRx3EXYTxTaYxYHc/PexPUTyimcTWFJbji9Z6Iw==", + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", + "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", "dependencies": { - "tslib": "^2.2.0" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { - "node": ">=14.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@azure/core-tracing": { - "version": "1.0.0-preview.13", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", - "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", + "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", "dependencies": { - "@opentelemetry/api": "^1.0.1", - "tslib": "^2.2.0" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/types": "^7.23.4" }, "engines": { - "node": ">=12.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@azure/core-util": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.3.2.tgz", - "integrity": "sha512-2bECOUh88RvL1pMZTcc6OzfobBeWDBf5oBbhjIhT1MV9otMVWCzpOJkkiKtrnO88y5GGBelgY8At73KGAdbkeQ==", + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", + "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", "dependencies": { - "@azure/abort-controller": "^1.0.0", - "tslib": "^2.2.0" + "@babel/plugin-transform-react-jsx": "^7.22.5" }, "engines": { - "node": ">=14.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@azure/logger": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.4.tgz", - "integrity": "sha512-ustrPY8MryhloQj7OWGe+HrYx+aoiOxzbXTtgblbV3xwCqpzUK36phH3XNHQKj3EPonyFUuDTfR3qFhTEAuZEg==", + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz", + "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==", "dependencies": { - "tslib": "^2.2.0" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { - "node": ">=14.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@azure/storage-blob": { - "version": "12.17.0", - "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.17.0.tgz", - "integrity": "sha512-sM4vpsCpcCApagRW5UIjQNlNylo02my2opgp0Emi8x888hZUvJ3dN69Oq20cEGXkMUWnoCrBaB0zyS3yeB87sQ==", + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", + "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", "dependencies": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-http": "^3.0.0", - "@azure/core-lro": "^2.2.0", - "@azure/core-paging": "^1.1.1", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/logger": "^1.0.0", - "events": "^3.0.0", - "tslib": "^2.2.0" + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" }, "engines": { - "node": ">=14.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", + "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/generator": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", - "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", "dependencies": { - "@babel/types": "^7.23.5", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "node_modules/@babel/plugin-transform-spread": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", + "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", + "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", + "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", + "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", + "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", + "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/parser": { + "node_modules/@babel/preset-env": { "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.5.tgz", + "integrity": "sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A==", + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.3", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.23.3", + "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.23.3", + "@babel/plugin-transform-async-generator-functions": "^7.23.4", + "@babel/plugin-transform-async-to-generator": "^7.23.3", + "@babel/plugin-transform-block-scoped-functions": "^7.23.3", + "@babel/plugin-transform-block-scoping": "^7.23.4", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-class-static-block": "^7.23.4", + "@babel/plugin-transform-classes": "^7.23.5", + "@babel/plugin-transform-computed-properties": "^7.23.3", + "@babel/plugin-transform-destructuring": "^7.23.3", + "@babel/plugin-transform-dotall-regex": "^7.23.3", + "@babel/plugin-transform-duplicate-keys": "^7.23.3", + "@babel/plugin-transform-dynamic-import": "^7.23.4", + "@babel/plugin-transform-exponentiation-operator": "^7.23.3", + "@babel/plugin-transform-export-namespace-from": "^7.23.4", + "@babel/plugin-transform-for-of": "^7.23.3", + "@babel/plugin-transform-function-name": "^7.23.3", + "@babel/plugin-transform-json-strings": "^7.23.4", + "@babel/plugin-transform-literals": "^7.23.3", + "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", + "@babel/plugin-transform-member-expression-literals": "^7.23.3", + "@babel/plugin-transform-modules-amd": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-modules-systemjs": "^7.23.3", + "@babel/plugin-transform-modules-umd": "^7.23.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.23.3", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", + "@babel/plugin-transform-numeric-separator": "^7.23.4", + "@babel/plugin-transform-object-rest-spread": "^7.23.4", + "@babel/plugin-transform-object-super": "^7.23.3", + "@babel/plugin-transform-optional-catch-binding": "^7.23.4", + "@babel/plugin-transform-optional-chaining": "^7.23.4", + "@babel/plugin-transform-parameters": "^7.23.3", + "@babel/plugin-transform-private-methods": "^7.23.3", + "@babel/plugin-transform-private-property-in-object": "^7.23.4", + "@babel/plugin-transform-property-literals": "^7.23.3", + "@babel/plugin-transform-regenerator": "^7.23.3", + "@babel/plugin-transform-reserved-words": "^7.23.3", + "@babel/plugin-transform-shorthand-properties": "^7.23.3", + "@babel/plugin-transform-spread": "^7.23.3", + "@babel/plugin-transform-sticky-regex": "^7.23.3", + "@babel/plugin-transform-template-literals": "^7.23.3", + "@babel/plugin-transform-typeof-symbol": "^7.23.3", + "@babel/plugin-transform-unicode-escapes": "^7.23.3", + "@babel/plugin-transform-unicode-property-regex": "^7.23.3", + "@babel/plugin-transform-unicode-regex": "^7.23.3", + "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.6", + "babel-plugin-polyfill-corejs3": "^0.8.5", + "babel-plugin-polyfill-regenerator": "^0.5.3", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "bin": { - "parser": "bin/babel-parser.js" + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz", + "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-transform-react-display-name": "^7.23.3", + "@babel/plugin-transform-react-jsx": "^7.22.15", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@babel/plugin-transform-react-pure-annotations": "^7.23.3" }, "engines": { - "node": ">=6.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, "node_modules/@babel/runtime": { "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz", @@ -3215,9 +4812,9 @@ } }, "node_modules/@types/react": { - "version": "18.2.42", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.42.tgz", - "integrity": "sha512-c1zEr96MjakLYus/wPnuWDo1/zErfdU9rNsIGmE+NV71nx88FG9Ttgo5dqorXTu/LImX2f63WBP986gJkMPNbA==", + "version": "18.2.43", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.43.tgz", + "integrity": "sha512-nvOV01ZdBdd/KW6FahSbcNplt2jCJfyWdTos61RYHV+FVv5L/g9AOX1bmbVcWcLFL8+KHQfh1zVIQrud6ihyQA==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -4231,6 +5828,23 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" }, + "node_modules/array-batcher/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/array-batcher/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/array-batcher/node_modules/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", @@ -4306,6 +5920,15 @@ "node": ">=6" } }, + "node_modules/array-batcher/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, "node_modules/array-buffer-byte-length": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", @@ -4422,13 +6045,13 @@ } }, "node_modules/array.prototype.reduce": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", - "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.6.tgz", + "integrity": "sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg==", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-array-method-boxes-properly": "^1.0.0", "is-string": "^1.0.7" }, @@ -4765,6 +6388,115 @@ "node": ">=4" } }, + "node_modules/babel-loader": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", + "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-loader/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/babel-loader/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/babel-loader/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/babel-loader/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz", + "integrity": "sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.3", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz", + "integrity": "sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.3", + "core-js-compat": "^3.33.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz", + "integrity": "sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.3" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, "node_modules/babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -8037,9 +9769,9 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" }, "node_modules/browserslist": { - "version": "4.21.9", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", - "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", "funding": [ { "type": "opencollective", @@ -8055,10 +9787,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001503", - "electron-to-chromium": "^1.4.431", - "node-releases": "^2.0.12", - "update-browserslist-db": "^1.0.11" + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -8268,11 +10000,11 @@ } }, "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", "engines": { - "node": ">=6" + "node": ">=4" } }, "node_modules/camelize": { @@ -8284,9 +10016,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001514", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001514.tgz", - "integrity": "sha512-ENcIpYBmwAAOm/V2cXgM7rZUrKKaqisZl4ZAI520FIkqGXUxJjmaIssbRW5HVVR5tyV6ygTLIm15aU8LUmQSaQ==", + "version": "1.0.30001566", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", + "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", "funding": [ { "type": "opencollective", @@ -8479,18 +10211,6 @@ "node": ">=10" } }, - "node_modules/chrome": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/chrome/-/chrome-0.1.0.tgz", - "integrity": "sha512-6KYl20U4Taj6YipylsWr2etUvp9AElJKfGNSBmyGTymYmancnOb041ZNadolEZi2nboLXH7jMSqUmm4kpuTzfg==", - "dependencies": { - "exeq": "^2.2.0", - "plist": "^1.1.0" - }, - "bin": { - "chrome": "index.js" - } - }, "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -8583,22 +10303,6 @@ "yargs-parser": "^7.0.0" } }, - "node_modules/cliss/node_modules/camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/cliss/node_modules/yargs-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha512-WhzC+xgstid9MbVUktco/bf+KJG+Uu6vMX0LN1sLJvwmbCQVxb4D8LzogobonKycNasCZLdOzTAk1SK7+K7swg==", - "dependencies": { - "camelcase": "^4.1.0" - } - }, "node_modules/cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -8793,6 +10497,11 @@ "node": ">= 12" } }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + }, "node_modules/component-emitter": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", @@ -9025,14 +10734,6 @@ "node": ">= 0.10" } }, - "node_modules/cookie-session/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, "node_modules/cookie-session/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -9087,6 +10788,18 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/core-js-compat": { + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.34.0.tgz", + "integrity": "sha512-4ZIyeNbW/Cn1wkMMDy+mvrRUxrwFNjKwbhCfQpDd+eLgYipDqp8oGFGtLmhh18EDPKA0g3VUBYOxQGGwvWLVpA==", + "dependencies": { + "browserslist": "^4.22.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/core-js-pure": { "version": "3.28.0", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.28.0.tgz", @@ -9439,9 +11152,9 @@ } }, "node_modules/csv-stringify": { - "version": "6.4.4", - "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.4.4.tgz", - "integrity": "sha512-NDshLupGa7gp4UG4sSNIqwYJqgSwvds0SvENntxoVoVvTzXcrHvd5gG2MWpbRpSNvk59dlmIe1IwNvSxN4IVmg==" + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.4.5.tgz", + "integrity": "sha512-SPu1Vnh8U5EnzpNOi1NDBL5jU5Rx7DVHr15DNg9LXDTAbQlAVAmEbVt16wZvEW9Fu9Qt4Ji8kmeCJ2B1+4rFTQ==" }, "node_modules/custom-event": { "version": "1.0.1", @@ -9912,10 +11625,9 @@ } }, "node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dependencies": { "ms": "^2.1.1" } @@ -9923,7 +11635,7 @@ "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "engines": { "node": ">=0.10.0" } @@ -10093,18 +11805,6 @@ "node": ">=10.17.0" } }, - "node_modules/default-gateway/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/default-gateway/node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -10756,9 +12456,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "node_modules/electron-to-chromium": { - "version": "1.4.454", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.454.tgz", - "integrity": "sha512-pmf1rbAStw8UEQ0sr2cdJtWl48ZMuPD9Sto8HVQOq9vx9j2WgDEN6lYoaqFvqEHYOmGA9oRGn7LqWI9ta0YugQ==" + "version": "1.4.609", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.609.tgz", + "integrity": "sha512-ihiCP7PJmjoGNuLpl7TjNA8pCQWu09vGyjlPYw1Rqww4gvNuCcmvl+44G+2QyJ6S2K4o+wbTS++Xz0YN8Q9ERw==" }, "node_modules/emoji-regex": { "version": "7.0.3", @@ -11957,15 +13657,6 @@ "resolve": "^1.22.4" } }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, "node_modules/eslint-module-utils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", @@ -11983,15 +13674,6 @@ } } }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, "node_modules/eslint-plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/eslint-plugin-babel/-/eslint-plugin-babel-5.3.1.tgz", @@ -12081,15 +13763,6 @@ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, "node_modules/eslint-plugin-import/node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -12840,18 +14513,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/exeq": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/exeq/-/exeq-2.4.0.tgz", - "integrity": "sha1-Td8qaEZIxCeteZNJzzO9dTWPiEo=", - "dependencies": { - "bluebird": "^3.0.3", - "native-or-bluebird": "^1.2.0" - }, - "engines": { - "node": ">= 0.10.0" - } - }, "node_modules/exif": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/exif/-/exif-0.6.0.tgz", @@ -13491,6 +15152,111 @@ "traverse-chain": "~0.1.0" } }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/find-cache-dir/node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/find-in-files": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/find-in-files/-/find-in-files-0.5.0.tgz", @@ -14140,9 +15906,9 @@ } }, "node_modules/function-plot": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/function-plot/-/function-plot-1.23.3.tgz", - "integrity": "sha512-YvV517ZNrc93SBlLux3LfNZUEil7DiZGHerKGk5tU/iqIzFYedyw3u7ZeAcrll3qzhKTs84M8XxUiESE7Mlzdw==", + "version": "1.23.4", + "resolved": "https://registry.npmjs.org/function-plot/-/function-plot-1.23.4.tgz", + "integrity": "sha512-CMu6k8MDPpOOvnFBRhahtqm0UKzxhxxFYkp1p5Xd06iTDenhpvVh1s0/uR6GTymJX8Hdgwr4iWsEUWXOhgtJUQ==", "dependencies": { "built-in-math-eval": "^0.3.0", "clamp": "^1.0.1", @@ -14154,6 +15920,7 @@ "d3-selection": "^3.0.0", "d3-shape": "^3.1.0", "d3-zoom": "^3.0.0", + "events": "^3.3.0", "interval-arithmetic-eval": "^0.5.1" } }, @@ -14305,32 +16072,48 @@ "node": ">= 14" } }, - "node_modules/gaxios/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/gaxios/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/gcp-metadata": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", - "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz", + "integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==", + "optional": true, + "peer": true, "dependencies": { - "gaxios": "^6.0.0", + "gaxios": "^5.0.0", "json-bigint": "^1.0.0" }, "engines": { - "node": ">=14" + "node": ">=12" + } + }, + "node_modules/gcp-metadata/node_modules/gaxios": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.1.3.tgz", + "integrity": "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==", + "optional": true, + "peer": true, + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "peer": true, + "engines": { + "node": ">=6.9.0" } }, "node_modules/get-caller-file": { @@ -14550,6 +16333,18 @@ "node": ">=14" } }, + "node_modules/google-auth-library/node_modules/gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "dependencies": { + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/googleapis": { "version": "129.0.0", "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-129.0.0.tgz", @@ -15676,14 +17471,6 @@ "url": "https://www.buymeacoffee.com/2tmRKi9" } }, - "node_modules/infobox-parser/node_modules/camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "engines": { - "node": ">=4" - } - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -16483,6 +18270,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -16718,6 +18516,31 @@ "regenerator-runtime": "^0.13.3" } }, + "node_modules/jpeg-autorotate": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jpeg-autorotate/-/jpeg-autorotate-9.0.0.tgz", + "integrity": "sha512-bMzp1iIOpqF2dWiMwb3Mc9MfexYuiBmznNIeVtnedqFrfVql3Ueptg7Cefz6ZJuJais8sb+mBGQD/hw3Ud8eRA==", + "dependencies": { + "glob": "^7.2.0", + "jpeg-js": "^0.4.3", + "piexifjs": "^1.0.6", + "yargs-parser": "^20.2.9" + }, + "bin": { + "jpeg-autorotate": "src/cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jpeg-autorotate/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, "node_modules/jpeg-js": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", @@ -17341,6 +19164,11 @@ "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=" }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -18665,33 +20493,68 @@ "integrity": "sha512-yc0LhH6tItlvfLBugVUEtgawwFU2sIe+cSdmRJJCTMZ5GEJyLxNyC/NIOAOGk67Fa8GNpOttO3Xz/1bHpXFD/g==" }, "node_modules/mobx": { - "version": "5.15.7", - "resolved": "https://registry.npmjs.org/mobx/-/mobx-5.15.7.tgz", - "integrity": "sha512-wyM3FghTkhmC+hQjyPGGFdpehrcX1KOXsDuERhfK2YbJemkUhEB+6wzEN639T21onxlfYBmriA1PFnvxTUhcKw==", + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.12.0.tgz", + "integrity": "sha512-Mn6CN6meXEnMa0a5u6a5+RKrqRedHBhZGd15AWLk9O6uFY4KYHzImdt8JI8WODo1bjTSRnwXhJox+FCUZhCKCQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mobx" } }, "node_modules/mobx-react": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-5.4.4.tgz", - "integrity": "sha512-2mTzpyEjVB/RGk2i6KbcmP4HWcAUFox5ZRCrGvSyz49w20I4C4qql63grPpYrS9E9GKwgydBHQlA4y665LuRCQ==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-9.1.0.tgz", + "integrity": "sha512-DeDRTYw4AlgHw8xEXtiZdKKEnp+c5/jeUgTbTQXEqnAzfkrgYRWP3p3Nv3Whc2CEcM/mDycbDWGjxKokQdlffg==", + "dependencies": { + "mobx-react-lite": "^4.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mobx" + }, + "peerDependencies": { + "mobx": "^6.9.0", + "react": "^16.8.0 || ^17 || ^18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/mobx-react-lite": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-4.0.5.tgz", + "integrity": "sha512-StfB2wxE8imKj1f6T8WWPf4lVMx3cYH9Iy60bbKXEs21+HQ4tvvfIBZfSmMXgQAefi8xYEwQIz4GN9s0d2h7dg==", "dependencies": { - "hoist-non-react-statics": "^3.0.0", - "react-lifecycles-compat": "^3.0.2" + "use-sync-external-store": "^1.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mobx" }, "peerDependencies": { - "mobx": "^4.0.0 || ^5.0.0", - "react": "^0.13.0 || ^0.14.0 || ^15.0.0 || ^16.0.0" + "mobx": "^6.9.0", + "react": "^16.8.0 || ^17 || ^18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } } }, "node_modules/mobx-utils": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/mobx-utils/-/mobx-utils-5.6.2.tgz", - "integrity": "sha512-a/WlXyGkp6F12b01sTarENpxbmlRgPHFyR1Xv2bsSjQBm5dcOtd16ONb40/vOqck8L99NHpI+C9MXQ+SZ8f+yw==", + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/mobx-utils/-/mobx-utils-6.0.8.tgz", + "integrity": "sha512-fPNt0vJnHwbQx9MojJFEnJLfM3EMGTtpy4/qOOW6xueh1mPofMajrbYAUvByMYAvCJnpy1A5L0t+ZVB5niKO4g==", "peerDependencies": { - "mobx": "^4.13.1 || ^5.13.1" + "mobx": "^6.0.0" } }, "node_modules/mocha": { @@ -19609,12 +21472,6 @@ "node": ">=0.10.0" } }, - "node_modules/native-or-bluebird": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/native-or-bluebird/-/native-or-bluebird-1.2.0.tgz", - "integrity": "sha1-OcR7/Xgl0fuf+tMiEK4l2q3xAck=", - "deprecated": "'native-or-bluebird' is deprecated. Please use 'any-promise' instead." - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -19745,9 +21602,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, "node_modules/node-stream-zip": { "version": "1.15.0", @@ -22823,14 +24680,15 @@ } }, "node_modules/object.getownpropertydescriptors": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz", - "integrity": "sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.7.tgz", + "integrity": "sha512-PrJz0C2xJ58FNn11XV2lr4Jt5Gzl94qpy9Lu0JlfEj14z88sqbSBJCBEzdlNUCzY2gburhbrwOZ5BHCmuNUy0g==", "dependencies": { - "array.prototype.reduce": "^1.0.5", + "array.prototype.reduce": "^1.0.6", "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "safe-array-concat": "^1.0.0" }, "engines": { "node": ">= 0.8" @@ -23553,6 +25411,11 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/piexifjs": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/piexifjs/-/piexifjs-1.0.6.tgz", + "integrity": "sha512-0wVyH0cKohzBQ5Gi2V1BuxYpxWfxF3cSqfFXfPIpl5tl9XLS5z4ogqhUCD20AbHi0h9aJkqXNJnkVev6gwh2ag==" + }, "node_modules/pipe-functions": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/pipe-functions/-/pipe-functions-1.3.0.tgz", @@ -23644,25 +25507,6 @@ "semver-compare": "^1.0.0" } }, - "node_modules/plist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/plist/-/plist-1.2.0.tgz", - "integrity": "sha512-dL9Xc2Aj3YyBnwvCNuHmFl2LWvQacm/HEAsoVwLiuu0POboMChETt5wexpU1P6F6MnibIucXlVsMFFgNUT2IyA==", - "dependencies": { - "base64-js": "0.0.8", - "util-deprecate": "1.0.2", - "xmlbuilder": "4.0.0", - "xmldom": "0.1.x" - } - }, - "node_modules/plist/node_modules/base64-js": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", - "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/pngjs": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", @@ -23805,9 +25649,9 @@ } }, "node_modules/prettier": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz", - "integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz", + "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -23899,6 +25743,13 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/prosemirror": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/prosemirror/-/prosemirror-0.11.1.tgz", + "integrity": "sha512-IZ35mmexuo3DNkMXs2A3bAm1jdlAJRVPor/bX1AWT+TdAR9fv6igUjRUFtQDCRUKwxH7ufwL1p6Um/MdgcbVIw==", + "deprecated": "This library has been split up into separate modules. This is the old monolithic package, which is no longer maintained. Use prosemirror-view, prosemirror-model, etc instead.", + "peer": true + }, "node_modules/prosemirror-commands": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.5.2.tgz", @@ -24365,15 +26216,6 @@ "node": ">=0.10.0" } }, - "node_modules/react-audio-waveform": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/react-audio-waveform/-/react-audio-waveform-0.0.5.tgz", - "integrity": "sha512-4dJwhl+LQRuywzmmjuhWT5GueT3Ai2ZhB+loVxg0sRdhplyDp96xAu10/V/+J25Cl7YqNtl2DWSxvSoI/i6l6w==", - "peerDependencies": { - "react": "^15.5.4", - "react-dom": "^15.4.1" - } - }, "node_modules/react-autosuggest": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/react-autosuggest/-/react-autosuggest-10.1.0.tgz", @@ -24675,17 +26517,6 @@ "react": ">= 16.3" } }, - "node_modules/react-reveal": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/react-reveal/-/react-reveal-1.2.2.tgz", - "integrity": "sha512-JCv3fAoU6Z+Lcd8U48bwzm4pMZ79qsedSXYwpwt6lJNtj/v5nKJYZZbw3yhaQPPgYePo3Y0NOCoYOq/jcsisuw==", - "dependencies": { - "prop-types": "^15.5.10" - }, - "peerDependencies": { - "react": "^15.3.0 || ^16.0.0" - } - }, "node_modules/react-select": { "version": "5.8.0", "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.8.0.tgz", @@ -24956,11 +26787,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, "node_modules/regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -25024,6 +26879,41 @@ "url": "https://github.com/sponsors/mysticatea" } }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "bin": { + "jsesc": "bin/jsesc" + } + }, "node_modules/rehype-raw": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", @@ -25629,18 +27519,6 @@ "node": ">=10.17.0" } }, - "node_modules/run-applescript/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/run-applescript/node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -28159,7 +30037,6 @@ "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -28174,9 +30051,9 @@ "integrity": "sha512-7sI4e/bZijOzyURng88oOFZCISQPTHozfE2sUu5AviFYk5QV7fYGb6YiDl+vKjF/pICA354JImBImL9XJWUvdQ==" }, "node_modules/typescript-language-server": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/typescript-language-server/-/typescript-language-server-4.1.3.tgz", - "integrity": "sha512-miJcwsS5ZGuYlix9mbGZDF96ynzgxAZbCeQO2MpgaVahmnRjoZ3dI6hnnsvBbdTrpHAAEqdigOnVezoOzcXSag==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/typescript-language-server/-/typescript-language-server-4.2.0.tgz", + "integrity": "sha512-1yKDqKeWLTQkN4mN+CT84aBr7ckp6sNVb8DZg+eXl0TDl14edn6Yh1wPqPA1rQ4AGVJc02fYbXTFsklaVYy4Uw==", "bin": { "typescript-language-server": "lib/cli.mjs" }, @@ -28229,6 +30106,42 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "engines": { + "node": ">=4" + } + }, "node_modules/unicode-trie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-0.3.1.tgz", @@ -28453,9 +30366,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "funding": [ { "type": "opencollective", @@ -28608,6 +30521,14 @@ } } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/utif2": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/utif2/-/utif2-4.1.0.tgz", @@ -29454,9 +31375,9 @@ } }, "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" }, "node_modules/which-typed-array": { "version": "1.1.13", @@ -29785,37 +31706,12 @@ "node": ">=4.0" } }, - "node_modules/xmlbuilder": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.0.0.tgz", - "integrity": "sha1-mLj2UcowqmJANvEn0RzGbce5B6M=", - "dependencies": { - "lodash": "^3.5.0" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/xmlbuilder/node_modules/lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha512-9mDDwqVIma6OZX79ZlDACZl8sBm0TEnkf99zV3iMA4GzkIT/9hiqP5mY0HoT1iNLCrKc/R1HByV+yJfRWVJryQ==" - }, "node_modules/xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, - "node_modules/xmldom": { - "version": "0.1.31", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz", - "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==", - "deprecated": "Deprecated due to CVE-2021-21366 resolved in 0.5.0", - "engines": { - "node": ">=0.1" - } - }, "node_modules/xmlhttprequest-ssl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", @@ -29881,12 +31777,11 @@ } }, "node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha512-WhzC+xgstid9MbVUktco/bf+KJG+Uu6vMX0LN1sLJvwmbCQVxb4D8LzogobonKycNasCZLdOzTAk1SK7+K7swg==", "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "camelcase": "^4.1.0" } }, "node_modules/yargs-unparser": { @@ -29910,6 +31805,14 @@ "node": ">=6" } }, + "node_modules/yargs/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, "node_modules/yargs/node_modules/string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -29934,6 +31837,15 @@ "node": ">=6" } }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/package.json b/package.json index 151e45124..42b3c1ce2 100644 --- a/package.json +++ b/package.json @@ -95,6 +95,8 @@ }, "dependencies": { "@azure/storage-blob": "^12.17.0", + "@babel/preset-env": "^7.23.5", + "@babel/preset-react": "^7.23.3", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@ffmpeg/core": "0.12.4", @@ -127,6 +129,7 @@ "async": "^3.2.5", "axios": "^1.6.2", "babel": "^6.23.0", + "babel-loader": "^9.1.3", "bcrypt-nodejs": "0.0.3", "bezier-curve": "^1.0.0", "bezier-js": "^6.1.4", @@ -141,7 +144,6 @@ "canvas": "^2.11.2", "chart.js": "^4.4.0", "child_process": "^1.0.2", - "chrome": "^0.1.0", "class-transformer": "^0.5.1", "color": "^4.2.3", "colors": "^1.4.0", @@ -191,6 +193,7 @@ "image-size": "^1.0.2", "image-size-stream": "^1.1.0", "jimp": "^0.22.10", + "jpeg-autorotate": "^9.0.0", "jquery": "^3.7.1", "js-datepicker": "^5.18.2", "jsonschema": "^1.4.1", @@ -200,9 +203,9 @@ "md5-file": "^5.0.0", "memorystream": "^0.3.1", "mobile-detect": "^1.4.5", - "mobx": "^5.15.7", - "mobx-react": "^5.4.4", - "mobx-utils": "^5.6.2", + "mobx": "^6.12.0", + "mobx-react": "^9.1.0", + "mobx-utils": "^6.0.8", "mongodb": "^6.3.0", "mongoose": "^8.0.2", "node-stream-zip": "^1.15.0", @@ -237,7 +240,6 @@ "raw-loader": "^4.0.2", "rc-switch": "^4.1.0", "react": "^18.2.0", - "react-audio-waveform": "0.0.5", "react-autosuggest": "^10.1.0", "react-color": "^2.19.3", "react-compound-slider": "^3.4.0", @@ -250,7 +252,6 @@ "react-markdown": "^9.0.1", "react-measure": "^2.5.2", "react-resizable": "^3.0.5", - "react-reveal": "^1.2.2", "react-select": "^5.8.0", "readline": "^1.3.0", "recharts": "^2.10.3", diff --git a/src/.babelrc b/src/.babelrc new file mode 100644 index 000000000..86ef21087 --- /dev/null +++ b/src/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["@babel/preset-env", "@babel/preset-react"] +} diff --git a/src/Utils.ts b/src/Utils.ts index 26514622c..d54760100 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -7,6 +7,7 @@ import { DocumentType } from './client/documents/DocumentTypes'; import { Colors } from './client/views/global/globalEnums'; import { Message } from './server/Message'; import * as Color from 'color'; +import { action, makeObservable } from 'mobx'; export namespace Utils { export let CLICK_TIME = 300; @@ -439,6 +440,12 @@ export namespace Utils { socket.on(message, (room: any) => handler(socket, room)); } } +export function copyProps(thing: { _prevProps: any; props: any; _props: any }) { + Object.keys(thing._prevProps).forEach(action(pkey => + (thing._prevProps as any)[pkey] !== (thing.props as any)[pkey] && + ((thing._props as any)[pkey] = (thing.props as any)[pkey]))); // prettier-ignore + thing._prevProps = thing.props; +} export function OmitKeys(obj: any, keys: string[], pattern?: string, addKeyFunc?: (dup: any) => void): { omit: any; extract: any } { const omit: any = { ...obj }; diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index df92fe50e..6217cf04b 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -57,7 +57,7 @@ export namespace DocServer { Doc.AddDocToList(Doc.MyRecentlyClosed, undefined, link); } }); - LinkManager.userLinkDBs.forEach(linkDb => Doc.FindReferences(linkDb, references, undefined)); + LinkManager.Instance.userLinkDBs.forEach(linkDb => Doc.FindReferences(linkDb, references, undefined)); const filtered = Array.from(references); const newCacheUpdate = filtered.map(doc => doc[Id]).join(';'); diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 87010f770..427b11751 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -32,7 +32,6 @@ export enum DocumentType { IMPORT = 'import', PRES = 'presentation', PRESELEMENT = 'preselement', - COLOR = 'color', YOUTUBE = 'youtube', COMPARISON = 'comparison', GROUP = 'group', diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 4ec100728..37196187b 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -32,7 +32,6 @@ import { ContextMenu } from '../views/ContextMenu'; import { ContextMenuProps } from '../views/ContextMenuItem'; import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, InkingStroke } from '../views/InkingStroke'; import { AudioBox, media_state } from '../views/nodes/AudioBox'; -import { ColorBox } from '../views/nodes/ColorBox'; import { ComparisonBox } from '../views/nodes/ComparisonBox'; import { DataVizBox } from '../views/nodes/DataVizBox/DataVizBox'; import { EquationBox } from '../views/nodes/EquationBox'; @@ -495,13 +494,6 @@ export namespace Docs { options: { _width: 400 }, }, ], - [ - DocumentType.COLOR, - { - layout: { view: ColorBox, dataField: defaultDataKey }, - options: { _nativeWidth: 220, _nativeHeight: 300 }, - }, - ], [ DocumentType.IMG, { @@ -1018,9 +1010,6 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.SEARCH), new List([]), options); } - export function ColorDocument(options: DocumentOptions = {}) { - return InstanceFromProto(Prototypes.get(DocumentType.COLOR), '', options); - } export function LoadingDocument(file: File | string, options: DocumentOptions) { return InstanceFromProto(Prototypes.get(DocumentType.LOADING), undefined, { _height: 150, _width: 200, title: typeof file == 'string' ? file : file.name, ...options }, undefined, ''); } @@ -1638,7 +1627,7 @@ export namespace DocUtils { options = { ...options, _width: 400, _height: 512, title: path }; } - return ctor ? ctor(path, options, overwriteDoc) : undefined; + return ctor ? ctor(path, overwriteDoc ? { ...options, title: StrCast(overwriteDoc.title, path) } : options, overwriteDoc) : undefined; } export function addDocumentCreatorMenuItems(docTextAdder: (d: Doc) => void, docAdder: (d: Doc) => void, x: number, y: number, simpleMenu: boolean = false, pivotField?: string, pivotValue?: string): void { diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index ad5a1654d..7f82ff70a 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -1,4 +1,4 @@ -import { action, computed, observable, ObservableSet, observe } from 'mobx'; +import { action, computed, makeObservable, observable, ObservableSet, observe } from 'mobx'; import { Doc, DocListCast, Opt } from '../../fields/Doc'; import { AclAdmin, AclEdit, Animation } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; @@ -22,8 +22,8 @@ const { Howl } = require('howler'); export class DocumentManager { //global holds all of the nodes (regardless of which collection they're in) @observable _documentViews = new Set(); - @observable public LinkAnchorBoxViews: DocumentView[] = []; - @observable public LinkedDocumentViews: { a: DocumentView; b: DocumentView; l: Doc }[] = []; + @observable public LinkAnchorBoxViews: DocumentView[] = observable([]); + @observable public LinkedDocumentViews: { a: DocumentView; b: DocumentView; l: Doc }[] = observable([]); @computed public get DocumentViews() { return Array.from(this._documentViews).filter(view => !(view.ComponentView instanceof KeyValueBox) && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(view.docViewPath))); } @@ -38,11 +38,12 @@ export class DocumentManager { public static get Instance(): DocumentManager { return this._instance || (this._instance = new this()); } + @observable public CurrentlyLoading: Doc[] = observable([]); // this assignment doesn't work. the actual assignment happens in DocumentManager's constructor //private constructor so no other class can create a nodemanager private constructor() { - if (!LoadingBox.CurrentlyLoading) LoadingBox.CurrentlyLoading = []; - observe(LoadingBox.CurrentlyLoading, change => { + makeObservable(this); + observe(this.CurrentlyLoading, change => { // watch CurrentlyLoading-- when something is loaded, it's removed from the list and we have to update its icon if it were iconified since LoadingBox icons are different than the media they become switch (change.type as any) { case 'update': diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx index 30e448797..55aac5eb0 100644 --- a/src/client/util/Import & Export/DirectoryImportBox.tsx +++ b/src/client/util/Import & Export/DirectoryImportBox.tsx @@ -21,7 +21,6 @@ import { DocumentManager } from '../DocumentManager'; import './DirectoryImportBox.scss'; import ImportMetadataEntry, { keyPlaceholder, valuePlaceholder } from './ImportMetadataEntry'; import * as React from 'react'; -import * as _ from 'lodash'; const unsupported = ['text/html', 'text/plain']; @@ -157,7 +156,7 @@ export class DirectoryImportBox extends React.Component { x: NumCast(doc.x), y: NumCast(doc.y) + offset, }; - const parent = this.props.DocumentView?.().props.docViewPath().lastElement(); + const parent = this.props.DocumentView?.()._props.docViewPath().lastElement(); if (parent?.Document.type === DocumentType.COL) { let importContainer: Doc; if (docs.length < 50) { diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 3e98ea379..8346949ba 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -1,4 +1,4 @@ -import { action, observable, observe, runInAction } from 'mobx'; +import { action, makeObservable, observable, observe, runInAction } from 'mobx'; import { computedFn } from 'mobx-utils'; import { Doc, DocListCast, DocListCastAsync, Field, Opt } from '../../fields/Doc'; import { DirectLinks } from '../../fields/DocSymbols'; @@ -22,7 +22,7 @@ import { ScriptingGlobals } from './ScriptingGlobals'; */ export class LinkManager { @observable static _instance: LinkManager; - @observable static userLinkDBs: Doc[] = []; + @observable userLinkDBs: Doc[] = observable([]); @observable public static currentLink: Opt; @observable public static currentLinkAnchor: Opt; public static get Instance() { @@ -32,21 +32,21 @@ export class LinkManager { public static Links(doc: Doc | undefined) { return doc ? LinkManager.Instance.getAllRelatedLinks(doc) : []; } - public static addLinkDB = async (linkDb: any) => { + public addLinkDB = async (linkDb: any) => { await Promise.all( ((await DocListCastAsync(linkDb.data)) ?? []).map(link => // makes sure link anchors are loaded to avoid incremental updates to computedFns in LinkManager [PromiseValue(link?.link_anchor_1), PromiseValue(link?.link_anchor_2)] ) ); - LinkManager.userLinkDBs.push(linkDb); + this.userLinkDBs.push(linkDb); }; public static AutoKeywords = 'keywords:Usages'; static _links: Doc[] = []; constructor() { + makeObservable(this); LinkManager._instance = this; this.createlink_relationshipLists(); - LinkManager.userLinkDBs = []; // since this is an action, not a reaction, we get only one shot to add this link to the Anchor docs // Thus make sure all promised values are resolved from link -> link.proto -> link.link_anchor_[1,2] -> link.link_anchor_[1,2].proto // Then add the link to the anchor protos. @@ -124,7 +124,7 @@ export class LinkManager { } }; observe( - LinkManager.userLinkDBs, + this.userLinkDBs, change => { switch (change.type as any) { case 'splice': @@ -136,7 +136,7 @@ export class LinkManager { true ); runInAction(() => (FieldLoader.ServerLoadStatus.message = 'links')); - LinkManager.addLinkDB(Doc.LinkDBDoc()); + this.addLinkDB(Doc.LinkDBDoc()); } public createlink_relationshipLists = () => { diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx index c8940194c..495af6abd 100644 --- a/src/client/util/RTFMarkup.tsx +++ b/src/client/util/RTFMarkup.tsx @@ -26,7 +26,7 @@ export class RTFMarkup extends React.Component<{}> { RTFMarkup.Instance = this; } - @observable _stats: { [key: string]: any } | undefined; + @observable _stats: { [key: string]: any } | undefined = undefined; /** * @returns the main interface of the SharingManager. diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 25f158f40..d36a360a1 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -1,4 +1,4 @@ -import { action, observable } from 'mobx'; +import { action, makeObservable, observable } from 'mobx'; import { Doc, Opt } from '../../fields/Doc'; import { DocViews } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; @@ -12,9 +12,13 @@ import { UndoManager } from './UndoManager'; export namespace SelectionManager { class Manager { - @observable SelectedViews: DocumentView[] = []; + @observable SelectedViews: DocumentView[] = observable([]); @observable IsDragging: boolean = false; - @observable SelectedSchemaDocument: Doc | undefined; + @observable SelectedSchemaDocument: Doc | undefined = undefined; + + constructor() { + makeObservable(this); + } @action SelectSchemaViewDoc(doc: Opt) { @@ -26,7 +30,7 @@ export namespace SelectionManager { if (!extendSelection) this.DeselectAll(); manager.SelectedViews.push(docView); docView.SELECTED = true; - docView.props.whenChildContentsActiveChanged(true); + docView._props.whenChildContentsActiveChanged(true); } } @action @@ -34,7 +38,7 @@ export namespace SelectionManager { if (docView && manager.SelectedViews.includes(docView)) { docView.SELECTED = false; manager.SelectedViews.splice(manager.SelectedViews.indexOf(docView), 1); - docView.props.whenChildContentsActiveChanged(false); + docView._props.whenChildContentsActiveChanged(false); } } @action @@ -44,7 +48,7 @@ export namespace SelectionManager { manager.SelectedSchemaDocument = undefined; manager.SelectedViews.forEach(dv => { dv.SELECTED = false; - dv.props.whenChildContentsActiveChanged(false); + dv._props.whenChildContentsActiveChanged(false); }); manager.SelectedViews.length = 0; } @@ -87,7 +91,7 @@ export namespace SelectionManager { 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; + return SelectionManager.Views().lastElement()?._props.renderDepth === 0; } let selected = (sel => (checkContext ? DocCast(sel?.embedContainer) : sel))(SelectionManager.SelectedSchemaDoc() ?? SelectionManager.Docs().lastElement()); return selected?.type === type || selected?.type_collection === type || !type; @@ -115,7 +119,7 @@ ScriptingGlobals.add(function redo() { }); ScriptingGlobals.add(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) { const docs = SelectionManager.Views() - .map(dv => dv.props.Document) + .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))); return docs.length ? new List(docs) : prevValue; }); diff --git a/src/client/util/ServerStats.tsx b/src/client/util/ServerStats.tsx index 08dbaac5d..7d5e0458d 100644 --- a/src/client/util/ServerStats.tsx +++ b/src/client/util/ServerStats.tsx @@ -36,7 +36,7 @@ export class ServerStats extends React.Component<{}> { ServerStats.Instance = this; } - @observable _stats: { [key: string]: any } | undefined; + @observable _stats: { [key: string]: any } | undefined = undefined; /** * @returns the main interface of the SharingManager. @@ -56,9 +56,7 @@ export class ServerStats extends React.Component<{}> {
Active users:{this._stats?.socketMap.length} - {this._stats?.socketMap.map((user: any) => ( -

{user.username}

- ))} + {this._stats?.socketMap.map((user: any) =>

{user.username}

)}
); diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index 39c471970..ccf6fb820 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -1,6 +1,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Button, ColorPicker, Dropdown, DropdownType, EditableText, Group, NumberDropdown, Size, Toggle, ToggleType, Type } from 'browndash-components'; -import { action, computed, observable, runInAction } from 'mobx'; +import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { BsGoogle } from 'react-icons/bs'; @@ -45,11 +45,12 @@ export class SettingsManager extends React.Component<{}> { @observable private new_confirm = ''; @observable activeTab = 'Accounts'; - @observable public static propertiesWidth: number = 0; - @observable public static headerBarHeight: number = 0; + @observable public propertiesWidth: number = 0; + @observable public headerBarHeight: number = 0; constructor(props: {}) { super(props); + makeObservable(this); SettingsManager.Instance = this; this.matchSystem(); window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { @@ -116,7 +117,6 @@ export class SettingsManager extends React.Component<{}> { }); @undoBatch - @action changeColorScheme = action((scheme: string) => { Doc.UserDoc().userTheme = scheme; switch (scheme) { diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 403f4e090..a46c6363e 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -67,8 +67,8 @@ export class SharingManager extends React.Component<{}> { public static Instance: SharingManager; @observable private isOpen = false; // whether the SharingManager modal is open or not @observable public users: ValidatedUser[] = []; // the list of users with sharing docs - @observable private targetDoc: Doc | undefined; // the document being shared - @observable private targetDocView: DocumentView | undefined; // the DocumentView of the document being shared + @observable private targetDoc: Doc | undefined = undefined; // the document being shared + @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 diff --git a/src/client/util/SnappingManager.ts b/src/client/util/SnappingManager.ts index fce43eef6..715eb021f 100644 --- a/src/client/util/SnappingManager.ts +++ b/src/client/util/SnappingManager.ts @@ -6,7 +6,7 @@ export namespace SnappingManager { @observable ShiftKey = false; @observable CtrlKey = false; @observable IsDragging: boolean = false; - @observable IsResizing: Doc | undefined; + @observable IsResizing: Doc | undefined = undefined; @observable CanEmbed: boolean = false; @observable public horizSnapLines: number[] = []; @observable public vertSnapLines: number[] = []; diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index 412b8ba6e..f89624941 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -1,9 +1,8 @@ +import { action, makeObservable, observable, runInAction } from 'mobx'; import * as React from 'react'; -import { observable, action, runInAction } from 'mobx'; -import './AntimodeMenu.scss'; -import { StrCast } from '../../fields/Types'; -import { Doc } from '../../fields/Doc'; import { SettingsManager } from '../util/SettingsManager'; +import { copyProps } from '../../Utils'; +import './AntimodeMenu.scss'; export interface AntimodeMenuProps {} /** @@ -16,6 +15,18 @@ export abstract class AntimodeMenu extends React.Co protected _mainCont: React.RefObject = React.createRef(); protected _dragging: boolean = false; + _prevProps: React.PropsWithChildren; + @observable _props: React.PropsWithChildren; + constructor(props: React.PropsWithChildren) { + super(props); + this._props = this._prevProps = props; + makeObservable(this); + } + + componentDidUpdate() { + copyProps(this); + } + @observable protected _top: number = -300; @observable protected _left: number = -300; @observable protected _opacity: number = 0; diff --git a/src/client/views/AudioWaveform.scss b/src/client/views/AudioWaveform.scss deleted file mode 100644 index 6cbd1759a..000000000 --- a/src/client/views/AudioWaveform.scss +++ /dev/null @@ -1,17 +0,0 @@ -.audioWaveform { - position: relative; - width: 100%; - height: 200%; - overflow: hidden; - z-index: -1000; - bottom: 0; - pointer-events: none; - div { - height: 100% !important; - width: 100% !important; - } - canvas { - height: 100% !important; - width: 100% !important; - } -} diff --git a/src/client/views/AudioWaveform.tsx b/src/client/views/AudioWaveform.tsx deleted file mode 100644 index 1fd2fedc3..000000000 --- a/src/client/views/AudioWaveform.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import * as React from 'react'; -import axios from 'axios'; -import { action, computed, IReactionDisposer, reaction } from 'mobx'; -import { observer } from 'mobx-react'; -import Waveform from 'react-audio-waveform'; -import { Doc, NumListCast } from '../../fields/Doc'; -import { List } from '../../fields/List'; -import { listSpec } from '../../fields/Schema'; -import { Cast } from '../../fields/Types'; -import { numberRange } from '../../Utils'; -import './AudioWaveform.scss'; -import { Colors } from './global/globalEnums'; - -/** - * AudioWaveform - * - * Used in CollectionStackedTimeline to render a canvas with a visual of an audio waveform for AudioBox and VideoBox documents. - * Uses react-audio-waveform package. - * Bins the audio data into audioBuckets which are passed to package to render the lines. - * Calculates new buckets each time a new zoom factor or new set of trim bounds is created and stores it in a field on the layout doc with a title indicating the bounds and zoom for that list (see audioBucketField) - */ - -export interface AudioWaveformProps { - duration: number; // length of media clip - rawDuration: number; // length of underlying media data - mediaPath: string; - layoutDoc: Doc; - clipStart: number; - clipEnd: number; - zoomFactor: number; - PanelHeight: number; - PanelWidth: number; - fieldKey: string; -} - -@observer -export class AudioWaveform extends React.Component { - public static NUMBER_OF_BUCKETS = 100; // number of buckets data is divided into to draw waveform lines - - _disposer: IReactionDisposer | undefined; - - @computed get waveHeight() { - return Math.max(50, this.props.PanelHeight); - } - - @computed get clipStart() { - return this.props.clipStart; - } - @computed get clipEnd() { - return this.props.clipEnd; - } - @computed get zoomFactor() { - return this.props.zoomFactor; - } - - @computed get audioBuckets() { - 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; - - componentWillUnmount() { - this._disposer?.(); - } - - componentDidMount() { - 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]) { - // 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(waveform.slice((clipStart / this.props.rawDuration) * waveform.length, (clipEnd / this.props.rawDuration) * waveform.length)); - setTimeout(() => this.createWaveformBuckets(fieldKey, clipStart, clipEnd, zoomFactor)); - } - }, - { fireImmediately: true } - ); - } - - // decodes the audio file into peaks for generating the waveform - createWaveformBuckets = async (fieldKey: string, clipStart: number, clipEnd: number, zoomFactor: number) => { - axios({ url: this.props.mediaPath, responseType: 'arraybuffer' }).then(response => { - const context = new window.AudioContext(); - context.decodeAudioData( - response.data, - action(buffer => { - const rawDecodedAudioData = buffer.getChannelData(0); - const startInd = clipStart / this.props.rawDuration; - const endInd = clipEnd / this.props.rawDuration; - const decodedAudioData = rawDecodedAudioData.slice(Math.floor(startInd * rawDecodedAudioData.length), Math.floor(endInd * rawDecodedAudioData.length)); - const numBuckets = Math.floor(AudioWaveform.NUMBER_OF_BUCKETS * zoomFactor); - - const bucketDataSize = Math.floor(decodedAudioData.length / numBuckets); - const brange = Array.from(Array(bucketDataSize)); - const bucketList = numberRange(numBuckets).map((i: number) => brange.reduce((p, x, j) => Math.abs(Math.max(p, decodedAudioData[i * bucketDataSize + j])), 0) / 2); - this.props.layoutDoc[fieldKey] = new List(bucketList); - }) - ); - }); - }; - - render() { - return ( -
- -
- ); - } -} diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index 57bc11385..249e2c3a3 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -1,40 +1,42 @@ -import * as React from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, IReactionDisposer, observable } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; -import './ContextMenu.scss'; -import { ContextMenuItem, ContextMenuProps, OriginalMenuProps } from './ContextMenuItem'; -import { Utils } from '../../Utils'; +import * as React from 'react'; import { StrCast } from '../../fields/Types'; -import { Doc } from '../../fields/Doc'; import { SettingsManager } from '../util/SettingsManager'; +import './ContextMenu.scss'; +import { ContextMenuItem, ContextMenuProps, OriginalMenuProps } from './ContextMenuItem'; @observer export class ContextMenu extends React.Component { static Instance: ContextMenu; - @observable private _items: Array = []; - @observable private _pageX: number = 0; - @observable private _pageY: number = 0; - @observable private _display: boolean = false; - @observable private _searchString: string = ''; - @observable private _showSearch: boolean = false; + private _ignoreUp = false; + private _reactionDisposer?: IReactionDisposer; + private _defaultPrefix: string = ''; + private _defaultItem: ((name: string) => void) | undefined; + private _onDisplay?: () => void = undefined; + + @observable _items: ContextMenuProps[] = observable([]); + @observable _pageX: number = 0; + @observable _pageY: number = 0; + @observable _display: boolean = false; + @observable _searchString: string = ''; + @observable _showSearch: boolean = false; // afaik displaymenu can be called before all the items are added to the menu, so can't determine in displayMenu what the height of the menu will be - @observable private _yRelativeToTop: boolean = true; - @observable selectedIndex = -1; + @observable _yRelativeToTop: boolean = true; + @observable _selectedIndex = -1; - @observable private _width: number = 0; - @observable private _height: number = 0; + @observable _width: number = 0; + @observable _height: number = 0; - @observable private _mouseX: number = -1; - @observable private _mouseY: number = -1; - @observable private _shouldDisplay: boolean = false; - private _ignoreUp = false; - private _reactionDisposer?: IReactionDisposer; + @observable _mouseX: number = -1; + @observable _mouseY: number = -1; + @observable _shouldDisplay: boolean = false; - constructor(props: Readonly<{}>) { + constructor(props: any) { super(props); - + makeObservable(this); ContextMenu.Instance = this; } @@ -74,36 +76,27 @@ export class ContextMenu extends React.Component { this._reactionDisposer?.(); } - @action - componentDidMount = () => { + componentDidMount() { document.addEventListener('pointerdown', this.onPointerDown, true); document.addEventListener('pointerup', this.onPointerUp); - }; + } @action clearItems() { - this._items = []; + this._items.length = 0; this._defaultPrefix = ''; this._defaultItem = undefined; } - _defaultPrefix: string = ''; - _defaultItem: ((name: string) => void) | undefined; - - findByDescription = (target: string, toLowerCase = false) => { - return this._items.find(menuItem => { - let reference = menuItem.description; - toLowerCase && (reference = reference.toLowerCase()); - return reference === target; - }); - }; + findByDescription = (target: string, toLowerCase = false) => + this._items.find(menuItem => + (toLowerCase ? menuItem.description.toLowerCase() : menuItem.description) === target); // prettier-ignore @action addItem(item: ContextMenuProps) { - if (this._items.indexOf(item) === -1) { - this._items.push(item); - } + !this._items.includes(item) && this._items.push(item); } + @action moveAfter(item: ContextMenuProps, after?: ContextMenuProps) { const curInd = this._items.findIndex(i => i.description === item.description); @@ -111,6 +104,7 @@ export class ContextMenu extends React.Component { const afterInd = after && this.findByDescription(after.description) ? this._items.findIndex(i => i.description === after.description) : this._items.length; this._items.splice(afterInd, 0, item); } + @action setDefaultItem(prefix: string, item: (name: string) => void) { this._defaultPrefix = prefix; @@ -126,7 +120,6 @@ export class ContextMenu extends React.Component { return this._pageY + this._height > window.innerHeight - ContextMenu.buffer ? window.innerHeight - ContextMenu.buffer - this._height : Math.max(0, this._pageY); } - _onDisplay?: () => void = undefined; @action displayMenu = (x: number, y: number, initSearch = '', showSearch = false, onDisplay?: () => void) => { //maxX and maxY will change if the UI/font size changes, but will work for any amount @@ -201,7 +194,7 @@ export class ContextMenu extends React.Component {
{value.join(' -> ')}
) : ( - + ) ); } @@ -211,7 +204,8 @@ export class ContextMenu extends React.Component { } render() { - return !this._display ? null : ( + console.log('DISPLAY = ' + this._display); + return (
{ @@ -221,6 +215,7 @@ export class ContextMenu extends React.Component { } })} style={{ + display: this._display ? '' : 'none', left: this.pageX, ...(this._yRelativeToTop ? { top: this.pageY } : { bottom: this.pageY }), background: SettingsManager.userBackgroundColor, @@ -242,17 +237,17 @@ export class ContextMenu extends React.Component { @action onKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'ArrowDown') { - if (this.selectedIndex < this.flatItems.length - 1) { - this.selectedIndex++; + if (this._selectedIndex < this.flatItems.length - 1) { + this._selectedIndex++; } e.preventDefault(); } else if (e.key === 'ArrowUp') { - if (this.selectedIndex > 0) { - this.selectedIndex--; + if (this._selectedIndex > 0) { + this._selectedIndex--; } e.preventDefault(); } else if (e.key === 'Enter' || e.key === 'Tab') { - const item = this.flatItems[this.selectedIndex]; + const item = this.flatItems[this._selectedIndex]; if (item) { item.event({ x: this.pageX, y: this.pageY }); } else if (this._searchString.startsWith(this._defaultPrefix)) { @@ -268,12 +263,12 @@ export class ContextMenu extends React.Component { onChange = (e: React.ChangeEvent) => { this._searchString = e.target.value; if (!this._searchString) { - this.selectedIndex = -1; + this._selectedIndex = -1; } else { - if (this.selectedIndex === -1) { - this.selectedIndex = 0; + if (this._selectedIndex === -1) { + this._selectedIndex = 0; } else { - this.selectedIndex = Math.min(this.flatItems.length - 1, this.selectedIndex); + this._selectedIndex = Math.min(this.flatItems.length - 1, this._selectedIndex); } } }; diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index 6d97d965e..59b223c14 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -1,12 +1,11 @@ import * as React from 'react'; -import { observable, action, runInAction } from 'mobx'; +import { observable, action, runInAction, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { UndoManager } from '../util/UndoManager'; -import { Doc } from '../../fields/Doc'; -import { StrCast } from '../../fields/Types'; import { SettingsManager } from '../util/SettingsManager'; +import { copyProps } from '../../Utils'; export interface OriginalMenuProps { description: string; @@ -32,9 +31,20 @@ export class ContextMenuItem extends React.Component = []; @observable private overItem = false; - @action + _prevProps: ContextMenuProps & { selected?: boolean }; + @observable _props: ContextMenuProps & { selected?: boolean }; + constructor(props: ContextMenuProps & { selected?: boolean }) { + super(props); + this._props = this._prevProps = props; + makeObservable(this); + } + + componentDidUpdate() { + copyProps(this); + } + componentDidMount() { - this._items.length = 0; + runInAction(() => this._items.length = 0); if ((this.props as SubmenuProps)?.subitems) { (this.props as SubmenuProps).subitems?.forEach(i => runInAction(() => this._items.push(i))); } diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index d104eb90c..2ce0c085a 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -1,4 +1,4 @@ -import { action, computed, observable } from 'mobx'; +import { action, computed, makeObservable, observable, runInAction, untracked } from 'mobx'; import { DateField } from '../../fields/DateField'; import { Doc, DocListCast, Opt } from '../../fields/Doc'; import { AclAdmin, AclAugment, AclEdit, AclPrivate, AclReadonly, DocData } from '../../fields/DocSymbols'; @@ -21,17 +21,26 @@ export interface DocComponentProps { } export function DocComponent

() { class Component extends React.Component> { + @observable _props!: React.PropsWithChildren

; + constructor(props: React.PropsWithChildren

) { + super(props); + this._props = props; + makeObservable(this); + } + componentDidUpdate() { + // untracked(() => (this._props = this.props)); + } //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then @computed get Document() { - return this.props.Document; + return this._props.Document; } // This is the rendering data of a document -- it may be "The Document", or it may be some template document that holds the rendering info @computed get layoutDoc() { - return this.props.LayoutTemplateString ? this.props.Document : Doc.Layout(this.props.Document, this.props.LayoutTemplate?.()); + return this._props.LayoutTemplateString ? this.Document : Doc.Layout(this.Document, this._props.LayoutTemplate?.()); } // This is the data part of a document -- ie, the data that is constant across all views of the document @computed get dataDoc() { - return this.props.Document[DocData] as Doc; + return this._props.Document[DocData] as Doc; } } return Component; @@ -49,22 +58,28 @@ interface ViewBoxBaseProps { } export function ViewBoxBaseComponent

() { class Component extends React.Component> { + @observable _props: React.PropsWithChildren

; + constructor(props: React.PropsWithChildren

) { + super(props); + this._props = props; + makeObservable(this); + } //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then //@computed get Document(): T { return schemaCtor(this.props.Document); } - @computed get Document() { - return this.props.Document; + get Document() { + return this._props.Document; } // This is the rendering data of a document -- it may be "The Document", or it may be some template document that holds the rendering info - @computed get layoutDoc() { - return Doc.Layout(this.props.Document); + get layoutDoc() { + return Doc.Layout(this.Document); } // This is the data part of a document -- ie, the data that is constant across all views of the document - @computed get dataDoc() { - return this.props.Document.isTemplateForField || this.props.Document.isTemplateDoc ? this.props.TemplateDataDocument ?? this.props.Document[DocData] : this.props.Document[DocData]; + get dataDoc() { + return this.Document.isTemplateForField || this.Document.isTemplateDoc ? this._props.TemplateDataDocument ?? this.Document[DocData] : this.Document[DocData]; } // key where data is stored - @computed get fieldKey() { - return this.props.fieldKey; + get fieldKey() { + return this._props.fieldKey; } } return Component; @@ -85,24 +100,30 @@ export interface ViewBoxAnnotatableProps { } export function ViewBoxAnnotatableComponent

() { class Component extends React.Component> { + @observable _props: React.PropsWithChildren

; + constructor(props: React.PropsWithChildren

) { + super(props); + this._props = props; + makeObservable(this); + } @observable _annotationKeySuffix = () => 'annotations'; @observable _isAnyChildContentActive = false; //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then @computed get Document() { - return this.props.Document; + return this._props.Document; } // This is the rendering data of a document -- it may be "The Document", or it may be some template document that holds the rendering info @computed get layoutDoc() { - return Doc.Layout(this.props.Document); + return Doc.Layout(this.Document); } // This is the data part of a document -- ie, the data that is constant across all views of the document @computed get dataDoc() { - return this.props.Document.isTemplateForField || this.props.Document.isTemplateDoc ? this.props.TemplateDataDocument ?? this.props.Document[DocData] : this.props.Document[DocData]; + return this.Document.isTemplateForField || this.Document.isTemplateDoc ? this._props.TemplateDataDocument ?? this.Document[DocData] : this.Document[DocData]; } // key where data is stored @computed get fieldKey() { - return this.props.fieldKey; + return this._props.fieldKey; } isAnyChildContentActive = () => this._isAnyChildContentActive; @@ -136,7 +157,7 @@ export function ViewBoxAnnotatableComponent

() if (targetDataDoc.isGroup && DocListCast(targetDataDoc[annotationKey ?? this.annotationKey]).length < 2) { (DocumentManager.Instance.getFirstDocumentView(targetDataDoc)?.ComponentView as CollectionFreeFormView)?.promoteCollection(); } else { - this.isAnyChildContentActive() && this.props.select(false); + this.isAnyChildContentActive() && this._props.select(false); } return true; } @@ -149,7 +170,7 @@ export function ViewBoxAnnotatableComponent

() // moving it into the target. @action.bound moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[], annotationKey?: string) => boolean, annotationKey?: string): boolean => { - if (Doc.AreProtosEqual(this.props.Document, targetCollection)) { + if (Doc.AreProtosEqual(this._props.Document, targetCollection)) { return true; } const first = doc instanceof Doc ? doc : doc[0]; @@ -161,7 +182,7 @@ export function ViewBoxAnnotatableComponent

() @action.bound addDocument = (doc: Doc | Doc[], annotationKey?: string): boolean => { const docs = doc instanceof Doc ? [doc] : doc; - if (this.props.filterAddDocument?.(docs) === false || docs.find(doc => Doc.AreProtosEqual(doc, this.props.Document) && Doc.LayoutField(doc) === Doc.LayoutField(this.props.Document))) { + if (this._props.filterAddDocument?.(docs) === false || docs.find(doc => Doc.AreProtosEqual(doc, this.Document) && Doc.LayoutField(doc) === Doc.LayoutField(this.Document))) { return false; } const targetDataDoc = this.dataDoc; @@ -190,7 +211,7 @@ export function ViewBoxAnnotatableComponent

() return true; }; - whenChildContentsActiveChanged = action((isActive: boolean) => this.props.whenChildContentsActiveChanged((this._isAnyChildContentActive = isActive))); + whenChildContentsActiveChanged = action((isActive: boolean) => this._props.whenChildContentsActiveChanged((this._isAnyChildContentActive = isActive))); } return Component; } diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index a64722a0b..47ec0f1b4 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -1,7 +1,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; -import { action, computed, observable, runInAction } from 'mobx'; +import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { Doc } from '../../fields/Doc'; import { RichTextField } from '../../fields/RichTextField'; @@ -60,8 +60,11 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV public static hasPushedHack = false; public static hasPulledHack = false; + @observable _props: { views: () => (DocumentView | undefined)[] }; constructor(props: { views: () => (DocumentView | undefined)[] }) { super(props); + this._props = props; + makeObservable(this); runInAction(() => (DocumentButtonBar.Instance = this)); } @@ -111,12 +114,12 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV }); get view0() { - return this.props.views()?.[0]; + return this._props.views()?.[0]; } @computed get considerGoogleDocsPush() { - const targetDoc = this.view0?.props.Document; + const targetDoc = this.view0?.Document; const published = targetDoc && Doc.GetProto(targetDoc)[GoogleRef] !== undefined; const animation = this.isAnimatingPulse ? 'shadow-pulse 1s linear infinite' : 'none'; return !targetDoc ? null : ( @@ -143,7 +146,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV @computed get considerGoogleDocsPull() { - const targetDoc = this.view0?.props.Document; + const targetDoc = this.view0?.Document; const dataDoc = targetDoc && Doc.GetProto(targetDoc); const animation = this.isAnimatingFetch ? 'spin 0.5s linear infinite' : 'none'; @@ -214,7 +217,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV @observable subFollow = ''; @computed get followLinkButton() { - const targetDoc = this.view0?.props.Document; + const targetDoc = this.view0?.Document; const followBtn = (allDocs: boolean, click: (doc: Doc) => void, isSet: (doc?: Doc) => boolean, icon: IconProp) => { const tooltip = `Follow ${this.subPin}documents`; return !tooltip ? null : ( @@ -229,7 +232,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV onPointerEnter={action(e => (this.subPin = allDocs ? 'All ' : ''))} onPointerLeave={action(e => (this.subPin = ''))} onClick={e => { - this.props.views().forEach(dv => click(dv!.Document)); + this._props.views().forEach(dv => click(dv!.Document)); e.stopPropagation(); }} /> @@ -243,7 +246,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV

this.props.views().map(view => view?.docView?.toggleFollowLink(undefined, false)))}> + onClick={undoBatch(e => this._props.views().map(view => view?.docView?.toggleFollowLink(undefined, false)))}>
{followBtn( true, @@ -260,7 +263,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV @observable subLink = ''; @computed get linkButton() { - const targetDoc = this.view0?.props.Document; + const targetDoc = this.view0?.Document; return !targetDoc || !this.view0 ? null : (
@@ -304,7 +307,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV onPointerLeave={action(e => (this.subEndLink = ''))} onClick={e => { this.view0 && - DocumentLinksButton.finishLinkClick(e.clientX, e.clientY, DocumentLinksButton.StartLink, this.view0.props.Document, true, this.view0, { + DocumentLinksButton.finishLinkClick(e.clientX, e.clientY, DocumentLinksButton.StartLink, this.view0.Document, true, this.view0, { pinDocLayout: pinLayout, pinData: !pinContent ? {} : { poslayoutview: true, dataannos: true, dataview: pinContent }, } as PinProps); @@ -331,7 +334,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV @observable subPin = ''; @computed get pinButton() { - const targetDoc = this.view0?.props.Document; + const targetDoc = this.view0?.Document; const pinBtn = (pinLayoutView: boolean, pinContentView: boolean, icon: IconProp) => { const tooltip = `Pin Document and Save ${this.subPin} to trail`; return !tooltip ? null : ( @@ -353,7 +356,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV )} onPointerLeave={action(e => (this.subPin = ''))} onClick={e => { - const docs = this.props + const docs = this._props .views() .filter(v => v) .map(dv => dv!.Document); @@ -376,7 +379,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
{ - const docs = this.props + const docs = this._props .views() .filter(v => v) .map(dv => dv!.Document); @@ -396,7 +399,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV @computed get shareButton() { - const targetDoc = this.view0?.props.Document; + const targetDoc = this.view0?.Document; return !targetDoc ? null : ( {'Open Sharing Manager'}
}>
SharingManager.Instance.open(this.view0, targetDoc)}> @@ -408,10 +411,10 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV @computed get menuButton() { - const targetDoc = this.view0?.props.Document; + const targetDoc = this.view0?.Document; return !targetDoc ? null : ( {`Open Context Menu`}
}> -
+
setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => this.openContextMenu(e))}>
@@ -427,10 +430,10 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV anchorPoint={anchorPoints.LEFT_TOP} content={ dv) - .map(dv => dv!.props.Document)} + .map(dv => dv!.Document)} suggestWithFunction /> // tfs: @bcz This might need to be the data document? }> @@ -447,7 +450,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV _stopFunc: () => void = emptyFunction; @computed get recordButton() { - const targetDoc = this.view0?.props.Document; + const targetDoc = this.view0?.Document; return !targetDoc ? null : ( Press to record audio annotation
}>
(DocumentV style={{ backgroundColor: this._isRecording ? Colors.ERROR_RED : Colors.DARK_GRAY, color: Colors.WHITE }} onPointerDown={action((e: React.PointerEvent) => { this._isRecording = true; - this.props.views().map(view => view && DocumentViewInternal.recordAudioAnnotation(view.dataDoc, view.LayoutFieldKey, stopFunc => (this._stopFunc = stopFunc), emptyFunction)); + this._props.views().map(view => view && DocumentViewInternal.recordAudioAnnotation(view.dataDoc, view.LayoutFieldKey, stopFunc => (this._stopFunc = stopFunc), emptyFunction)); const b = UndoManager.StartBatch('Recording'); setupMoveUpEvents( this, @@ -482,8 +485,8 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV onEmbedButtonMoved = () => { if (this._dragRef.current) { const dragDocView = this.view0!; - const dragData = new DragManager.DocumentDragData([dragDocView.props.Document]); - const [left, top] = dragDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); + const dragData = new DragManager.DocumentDragData([dragDocView.Document]); + const [left, top] = dragDocView._props.ScreenToLocalTransform().inverse().transformPoint(0, 0); dragData.defaultDropAction = 'embed'; dragData.canEmbed = true; DragManager.StartDocumentDrag([dragDocView.ContentDiv!], dragData, left, top, { hideSource: false }); @@ -497,7 +500,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV @computed get templateButton() { const view0 = this.view0; - const views = this.props.views(); + const views = this._props.views(); return !view0 ? null : ( Tap to Customize Layout. Drag an embedding
} open={this._tooltipOpen} onClose={action(() => (this._tooltipOpen = false))} placement="bottom">
!this._ref.current?.getBoundingClientRect().width && (this._tooltipOpen = true))}> @@ -522,7 +525,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV ); } - openContextMenu = (e: React.MouseEvent) => { + openContextMenu = (e: PointerEvent) => { let child = SelectionManager.Views()[0].ContentDiv!.children[0]; while (child.children.length) { const next = Array.from(child.children).find(c => c.className?.toString().includes('SVGAnimatedString') || typeof c.className === 'string'); @@ -559,7 +562,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV @action toggleTrail = (e: React.PointerEvent) => { - const rootView = this.props.views()[0]; + const rootView = this._props.views()[0]; const doc = rootView?.Document; if (doc) { const anchor = rootView.ComponentView?.getAnchor?.(true) ?? doc; @@ -569,12 +572,12 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV anchor.presentationTrail = trail; } Doc.ActivePresentation = trail; - this.props.views().lastElement()?.props.addDocTab(trail, OpenWhere.replaceRight); + this._props.views().lastElement()?._props.addDocTab(trail, OpenWhere.replaceRight); } e.stopPropagation(); }; render() { - const doc = this.view0?.props.Document; + const doc = this.view0?.Document; if (!doc || !this.view0) return null; const isText = () => doc[this.view0!.LayoutFieldKey] instanceof RichTextField; @@ -589,9 +592,9 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
(link.link_displayLine = !IsFollowLinkScript(this.props.views().lastElement()?.Document.onClick))} - linkCreateAnchor={() => this.props.views().lastElement()?.ComponentView?.getAnchor?.(true)} - linkFrom={() => this.props.views().lastElement()?.Document} + linkCreated={link => (link.link_displayLine = !IsFollowLinkScript(this._props.views().lastElement()?.Document.onClick))} + linkCreateAnchor={() => this._props.views().lastElement()?.ComponentView?.getAnchor?.(true)} + linkFrom={() => this._props.views().lastElement()?.Document} />
) : ( diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index b4c19df2d..6ef3fcc66 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -1,7 +1,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { IconButton } from 'browndash-components'; -import { action, computed, observable, runInAction } from 'mobx'; +import { action, computed, makeObservable, observable, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { FaUndo } from 'react-icons/fa'; import { DateField } from '../../fields/DateField'; @@ -34,10 +34,15 @@ import { DocumentView, OpenWhereMod } from './nodes/DocumentView'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import { ImageBox } from './nodes/ImageBox'; import * as React from 'react'; -import * as _ from 'lodash'; +interface DocumentDecorationsProps { + PanelWidth: number; + PanelHeight: number; + boundsLeft: number; + boundsTop: number; +} @observer -export class DocumentDecorations extends React.Component<{ PanelWidth: number; PanelHeight: number; boundsLeft: number; boundsTop: number }, { value: string }> { +export class DocumentDecorations extends React.Component { static Instance: DocumentDecorations; private _resizeHdlId = ''; private _keyinput = React.createRef(); @@ -61,8 +66,11 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P @observable private _showRotCenter = false; // whether to show a draggable green dot that represents the center of rotation @observable private _rotCenter = [0, 0]; // the center of rotation in object coordinates (0,0) = object center (not top left!) - constructor(props: any) { + @observable _props: React.PropsWithChildren; + constructor(props: React.PropsWithChildren) { super(props); + this._props = props; + makeObservable(this); DocumentDecorations.Instance = this; document.addEventListener('pointermove', // show decorations whenever pointer moves outside of selection bounds. action(e => { @@ -78,8 +86,8 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P @computed get ClippedBounds() { const bounds = this.Bounds; - const leftBounds = this.props.boundsLeft; - const topBounds = LightboxView.LightboxDoc ? 0 : this.props.boundsTop; + const leftBounds = this._props.boundsLeft; + const topBounds = LightboxView.LightboxDoc ? 0 : this._props.boundsTop; bounds.x = Math.max(leftBounds, bounds.x - this._resizeBorderWidth / 2) + this._resizeBorderWidth / 2; bounds.y = Math.max(topBounds, bounds.y - this._resizeBorderWidth / 2 - this._titleHeight) + this._resizeBorderWidth / 2 + this._titleHeight; const borderRadiusDraggerWidth = 15; @@ -92,7 +100,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P return (LinkFollower.IsFollowing || DocumentView.ExploreMode) ? { x: 0, y: 0, r: 0, b: 0 } : SelectionManager.Views() - .filter(dv => dv.props.renderDepth > 0) + .filter(dv => dv._props.renderDepth > 0) .map(dv => dv.getBounds()) .reduce((bounds, rect) => !rect ? bounds : { x: Math.min(rect.left, bounds.x), @@ -198,12 +206,12 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P if (containers.size > 1) return false; const { left, top } = dragDocView.getBounds() || { left: 0, top: 0 }; const dragData = new DragManager.DocumentDragData( - SelectionManager.Views().map(dv => dv.props.Document), - dragDocView.props.dropAction + SelectionManager.Views().map(dv => dv.Document), + dragDocView._props.dropAction ); - dragData.offset = dragDocView.props.ScreenToLocalTransform().transformDirection(e.x - left, e.y - top); - dragData.moveDocument = dragDocView.props.moveDocument; - dragData.removeDocument = dragDocView.props.removeDocument; + dragData.offset = dragDocView._props.ScreenToLocalTransform().transformDirection(e.x - left, e.y - top); + dragData.moveDocument = dragDocView._props.moveDocument; + dragData.removeDocument = dragDocView._props.removeDocument; dragData.isDocDecorationMove = true; dragData.canEmbed = dragTitle; this._hidden = true; @@ -223,7 +231,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P _deleteAfterIconify = false; _iconifyBatch: UndoManager.Batch | undefined; onCloseClick = (forceDeleteOrIconify: boolean | undefined) => { - const views = SelectionManager.Views().filter(v => v && v.props.renderDepth > 0); + const views = SelectionManager.Views().filter(v => v && v._props.renderDepth > 0); if (forceDeleteOrIconify === false && this._iconifyBatch) return; this._deleteAfterIconify = forceDeleteOrIconify || this._iconifyBatch ? true : false; var iconifyingCount = views.length; @@ -231,11 +239,11 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P if ((force || --iconifyingCount === 0) && this._iconifyBatch) { if (this._deleteAfterIconify) { views.forEach(iconView => { - Doc.setNativeView(iconView.props.Document); - if (iconView.props.Document.activeFrame) { - iconView.props.Document.opacity = 0; // bcz: hacky ... allows inkMasks and other documents to be "turned off" without removing them from the animated collection which allows them to function properly in a presenation. + Doc.setNativeView(iconView.Document); + if (iconView.Document.activeFrame) { + iconView.Document.opacity = 0; // bcz: hacky ... allows inkMasks and other documents to be "turned off" without removing them from the animated collection which allows them to function properly in a presenation. } else { - iconView.props.removeDocument?.(iconView.props.Document); + iconView._props.removeDocument?.(iconView.Document); } }); views.forEach(SelectionManager.DeselectView); @@ -296,7 +304,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P SelectionManager.DeselectAll(); }; - onSelectContainerDocClick = () => SelectionManager.Views()?.[0]?.props.docViewPath?.().lastElement()?.select(false); + onSelectContainerDocClick = () => SelectionManager.Views()?.[0]?._props.docViewPath?.().lastElement()?.select(false); /** * sets up events when user clicks on the border radius editor */ @@ -344,7 +352,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P }; setRotateCenter = (seldocview: DocumentView, rotCenter: number[]) => { - const newloccentern = seldocview.props.ScreenToLocalTransform().transformPoint(rotCenter[0], rotCenter[1]); + const newloccentern = seldocview._props.ScreenToLocalTransform().transformPoint(rotCenter[0], rotCenter[1]); const newlocenter = [newloccentern[0] - NumCast(seldocview.layoutDoc._width) / 2, newloccentern[1] - NumCast(seldocview.layoutDoc._height) / 2]; const final = Utils.rotPt(newlocenter[0], newlocenter[1], -(NumCast(seldocview.Document._rotation) / 180) * Math.PI); seldocview.Document.rotation_centerX = final.x / NumCast(seldocview.layoutDoc._width); @@ -376,7 +384,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P const seldocview = SelectionManager.Views()[0]; SelectionManager.Views().forEach(dv => { const accumRot = (NumCast(dv.Document._rotation) / 180) * Math.PI; - const localRotCtr = dv.props.ScreenToLocalTransform().transformPoint(rcScreen.X, rcScreen.Y); + const localRotCtr = dv._props.ScreenToLocalTransform().transformPoint(rcScreen.X, rcScreen.Y); const localRotCtrOffset = [localRotCtr[0] - NumCast(dv.Document.width) / 2, localRotCtr[1] - NumCast(dv.Document.height) / 2]; const startRotCtr = Utils.rotPt(localRotCtrOffset[0], localRotCtrOffset[1], -accumRot); const unrotatedDocPos = { x: NumCast(dv.Document.x) + localRotCtrOffset[0] - startRotCtr.x, y: NumCast(dv.Document.y) + localRotCtrOffset[1] - startRotCtr.y }; @@ -454,7 +462,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P dot = (b[0] - a[0]) * (p[1] - a[1]) - (b[1] - a[1]) * (p[0] - a[0]); return [a[0] + atob[0] * t, a[1] + atob[1] * t]; }; - const tl = docView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0); + const tl = docView._props.ScreenToLocalTransform().inverse().transformPoint(0, 0); return project([e.clientX + this._offset.x, e.clientY + this._offset.y], tl, [tl[0] + fixedAspect, tl[1] + 1]); }; onPointerMove = (e: PointerEvent, down: number[], move: number[]): boolean => { @@ -475,7 +483,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P !this._interactionLock && runInAction(async () => { // resize selected docs if we're not in the middle of a resize (ie, throttle input events to frame rate) this._interactionLock = true; this._snapPt = thisPt; - e.ctrlKey && (SelectionManager.Views().forEach(docView => !Doc.NativeHeight(docView.props.Document) && docView.toggleNativeDimensions())); + e.ctrlKey && (SelectionManager.Views().forEach(docView => !Doc.NativeHeight(docView.Document) && docView.toggleNativeDimensions())); const fixedAspect = SelectionManager.Docs().some(this.hasFixedAspect); const scaleAspect = {x:scale.x === 1 && fixedAspect ? scale.y : scale.x, y: scale.x !== 1 && fixedAspect ? scale.x : scale.y}; SelectionManager.Views().forEach(docView => @@ -522,7 +530,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P doc.xPadding = NumCast(doc.xPadding) * scale.x; doc.yPadding = NumCast(doc.yPadding) * scale.y; } else { - const refCent = docView.props.ScreenToLocalTransform().transformPoint(refPt[0], refPt[1]); // fixed reference point for resize (ie, a point that doesn't move) + const refCent = docView._props.ScreenToLocalTransform().transformPoint(refPt[0], refPt[1]); // fixed reference point for resize (ie, a point that doesn't move) const [nwidth, nheight] = [docView.nativeWidth, docView.nativeHeight]; const [initWidth, initHeight] = [NumCast(doc._width, 1), NumCast(doc._height)]; @@ -615,7 +623,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P return ScriptField.MakeFunction(this._titleControlString.substring(1), { doc: Doc.name })!.script.run({ self: selected.Document, this: selected.layoutDoc }, console.log).result?.toString() || ''; } if (this._titleControlString.startsWith('#')) { - return Field.toString(selected.props.Document[this._titleControlString.substring(1)] as Field) || '-unset-'; + return Field.toString(selected.Document[this._titleControlString.substring(1)] as Field) || '-unset-'; } return this._accumulatedTitle; } @@ -625,7 +633,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P @computed get rotCenter() { const lastView = SelectionManager.Views().lastElement(); if (lastView) { - const invXf = lastView.props.ScreenToLocalTransform().inverse(); + const invXf = lastView._props.ScreenToLocalTransform().inverse(); const seldoc = lastView.layoutDoc; const loccenter = Utils.rotPt(NumCast(seldoc.rotation_centerX) * NumCast(seldoc._width), NumCast(seldoc.rotation_centerY) * NumCast(seldoc._height), invXf.Rotate); return invXf.transformPoint(loccenter.x + NumCast(seldoc._width) / 2, loccenter.y + NumCast(seldoc._height) / 2); @@ -648,16 +656,16 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P var shareSymbolIcon = ReverseHierarchyMap.get(shareMode)?.image; // hide the decorations if the parent chooses to hide it or if the document itself hides it - const hideDecorations = SnappingManager.GetIsResizing() || seldocview.props.hideDecorations || seldocview.Document.layout_hideDecorations; + const hideDecorations = SnappingManager.GetIsResizing() || seldocview._props.hideDecorations || seldocview.Document.layout_hideDecorations; const hideResizers = - ![AclAdmin, AclEdit, AclAugment].includes(GetEffectiveAcl(seldocview.Document)) || hideDecorations || seldocview.props.hideResizeHandles || seldocview.Document.layout_hideResizeHandles || this._isRounding || this._isRotating; - const hideTitle = this._showNothing || hideDecorations || seldocview.props.hideDecorationTitle || seldocview.Document.layout_hideDecorationTitle || this._isRounding || this._isRotating; - const hideDocumentButtonBar = hideDecorations || seldocview.props.hideDocumentButtonBar || seldocview.Document.layout_hideDocumentButtonBar || this._isRounding || this._isRotating; + ![AclAdmin, AclEdit, AclAugment].includes(GetEffectiveAcl(seldocview.Document)) || hideDecorations || seldocview._props.hideResizeHandles || seldocview.Document.layout_hideResizeHandles || this._isRounding || this._isRotating; + const hideTitle = this._showNothing || hideDecorations || seldocview._props.hideDecorationTitle || seldocview.Document.layout_hideDecorationTitle || this._isRounding || this._isRotating; + const hideDocumentButtonBar = hideDecorations || seldocview._props.hideDocumentButtonBar || seldocview.Document.layout_hideDocumentButtonBar || this._isRounding || this._isRotating; // if multiple documents have been opened at the same time, then don't show open button const hideOpenButton = this._showNothing || hideDecorations || - seldocview.props.hideOpenButton || + seldocview._props.hideOpenButton || seldocview.Document.layout_hideOpenButton || SelectionManager.Views().some(docView => docView.Document._dragOnlyWithinContainer || docView.Document.isGroup || docView.Document.layout_hideOpenButton) || this._isRounding || @@ -667,10 +675,10 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P hideDecorations || this._isRounding || this._isRotating || - seldocview.props.hideDeleteButton || + seldocview._props.hideDeleteButton || seldocview.Document.hideDeleteButton || SelectionManager.Views().some(docView => { - const collectionAcl = docView.props.docViewPath()?.lastElement() ? GetEffectiveAcl(docView.props.docViewPath().lastElement().dataDoc) : AclEdit; + const collectionAcl = docView._props.docViewPath()?.lastElement() ? GetEffectiveAcl(docView._props.docViewPath().lastElement().dataDoc) : AclEdit; return collectionAcl !== AclAdmin && collectionAcl !== AclEdit && GetEffectiveAcl(docView.Document) !== AclAdmin; }); const topBtn = (key: string, icon: string, pointerDown: undefined | ((e: React.PointerEvent) => void), click: undefined | ((e: any) => void), title: string) => ( @@ -798,7 +806,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
)} - {seldocview.props.renderDepth <= 1 || !seldocview.props.docViewPath().lastElement() ? null : topBtn('selector', 'arrow-alt-circle-up', undefined, this.onSelectContainerDocClick, 'tap to select containing document')} + {seldocview._props.renderDepth <= 1 || !seldocview._props.docViewPath().lastElement() ? null : topBtn('selector', 'arrow-alt-circle-up', undefined, this.onSelectContainerDocClick, 'tap to select containing document')} {useRounding && (
{ _editingDisposer?: IReactionDisposer; @observable _editing: boolean = false; + _prevProps: EditableProps; + @observable _props: EditableProps; constructor(props: EditableProps) { super(props); - this._editing = this.props.editing ? true : false; + this._props = this._prevProps = props; + makeObservable(this); + this._editing = this._props.editing ? true : false; } componentDidMount(): void { @@ -89,12 +96,12 @@ export class EditableView extends React.Component { ); } - @action componentDidUpdate() { - if (this._editing && this.props.editing === false) { + copyProps(this); + if (this._editing && this._props.editing === false) { this._inputref?.value && this.finalizeEdit(this._inputref.value, false, true, false); - } else if (this.props.editing !== undefined) { - this._editing = this.props.editing; + } else if (this._props.editing !== undefined) { + this._editing = this._props.editing; } } @@ -120,28 +127,28 @@ export class EditableView extends React.Component { case 'Tab': e.stopPropagation(); this.finalizeEdit(e.currentTarget.value, e.shiftKey, false, false); - this.props.OnTab?.(e.shiftKey); + this._props.OnTab?.(e.shiftKey); break; case 'Backspace': e.stopPropagation(); - if (!e.currentTarget.value) this.props.OnEmpty?.(); + if (!e.currentTarget.value) this._props.OnEmpty?.(); break; case 'Enter': - if (this.props.allowCRs !== true) { + if (this._props.allowCRs !== true) { e.stopPropagation(); if (!e.ctrlKey) { this.finalizeEdit(e.currentTarget.value, e.shiftKey, false, true); - } else if (this.props.OnFillDown) { - this.props.OnFillDown(e.currentTarget.value); + } else if (this._props.OnFillDown) { + this._props.OnFillDown(e.currentTarget.value); this._editing = false; - this.props.isEditingCallback?.(false); + this._props.isEditingCallback?.(false); } } break; case 'Escape': e.stopPropagation(); this._editing = false; - this.props.isEditingCallback?.(false); + this._props.isEditingCallback?.(false); break; case 'ArrowUp': case 'ArrowDown': @@ -155,30 +162,30 @@ export class EditableView extends React.Component { case 'Control': break; case ':': - if (this.props.menuCallback) { + if (this._props.menuCallback) { e.stopPropagation(); - this.props.menuCallback(e.currentTarget.getBoundingClientRect().x, e.currentTarget.getBoundingClientRect().y); + this._props.menuCallback(e.currentTarget.getBoundingClientRect().x, e.currentTarget.getBoundingClientRect().y); break; } default: - if (this.props.textCallback?.(e.key)) { + if (this._props.textCallback?.(e.key)) { e.stopPropagation(); this._editing = false; - this.props.isEditingCallback?.(false); + this._props.isEditingCallback?.(false); } } }; @action onClick = (e: React.MouseEvent) => { - if (this.props.editing !== false) { + if (this._props.editing !== false) { e.nativeEvent.stopPropagation(); - if (this._ref.current && this.props.showMenuOnLoad) { - this.props.menuCallback?.(this._ref.current.getBoundingClientRect().x, this._ref.current.getBoundingClientRect().y); + if (this._ref.current && this._props.showMenuOnLoad) { + this._props.menuCallback?.(this._ref.current.getBoundingClientRect().x, this._ref.current.getBoundingClientRect().y); } else { this._editing = true; - this.props.isEditingCallback?.(true); + this._props.isEditingCallback?.(true); } // e.stopPropagation(); } @@ -186,17 +193,17 @@ export class EditableView extends React.Component { @action finalizeEdit(value: string, shiftDown: boolean, lostFocus: boolean, enterKey: boolean) { - if (this.props.SetValue(value, shiftDown, enterKey)) { + if (this._props.SetValue(value, shiftDown, enterKey)) { this._editing = false; - this.props.isEditingCallback?.(false); + this._props.isEditingCallback?.(false); } else { this._editing = false; - this.props.isEditingCallback?.(false); + this._props.isEditingCallback?.(false); !lostFocus && setTimeout( action(() => { this._editing = true; - this.props.isEditingCallback?.(true); + this._props.isEditingCallback?.(true); }), 0 ); @@ -215,9 +222,9 @@ export class EditableView extends React.Component { }; renderEditor() { - return this.props.autosuggestProps ? ( + return this._props.autosuggestProps ? ( { onClick: this.stopPropagation, onPointerUp: this.stopPropagation, onKeyPress: this.stopPropagation, - value: this.props.autosuggestProps.value, + value: this._props.autosuggestProps.value, // @ts-ignore - onChange: this.props.autosuggestProps.onChange, + onChange: this._props.autosuggestProps.onChange, }} /> - ) : this.props.oneLine !== false && this.props.GetValue()?.toString().indexOf('\n') === -1 ? ( + ) : this._props.oneLine !== false && this._props.GetValue()?.toString().indexOf('\n') === -1 ? ( (this._inputref = r)} - style={{ display: this.props.display, overflow: 'auto', fontSize: this.props.fontSize, minWidth: 20, background: this.props.background }} - placeholder={this.props.placeholder} + style={{ display: this._props.display, overflow: 'auto', fontSize: this._props.fontSize, minWidth: 20, background: this._props.background }} + placeholder={this._props.placeholder} onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)} - defaultValue={this.props.GetValue()} + defaultValue={this._props.GetValue()} autoFocus={true} onChange={this.onChange} onKeyDown={this.onKeyDown} @@ -253,10 +260,10 @@ export class EditableView extends React.Component {