@tldraw/editor 4.2.0-canary.43016e91a60a → 4.2.0-canary.8b4e0398f335

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/editor/Editor.ts"],
4
- "sourcesContent": ["import {\n\tAtom,\n\tEMPTY_ARRAY,\n\tatom,\n\tcomputed,\n\treact,\n\ttransact,\n\tunsafe__withoutCapture,\n} from '@tldraw/state'\nimport {\n\tComputedCache,\n\tRecordType,\n\tStoreSideEffects,\n\tStoreSnapshot,\n\tUnknownRecord,\n\treverseRecordsDiff,\n} from '@tldraw/store'\nimport {\n\tCameraRecordType,\n\tInstancePageStateRecordType,\n\tPageRecordType,\n\tStyleProp,\n\tStylePropValue,\n\tTLArrowShape,\n\tTLAsset,\n\tTLAssetId,\n\tTLAssetPartial,\n\tTLBinding,\n\tTLBindingCreate,\n\tTLBindingId,\n\tTLBindingUpdate,\n\tTLCamera,\n\tTLCursor,\n\tTLCursorType,\n\tTLDOCUMENT_ID,\n\tTLDocument,\n\tTLFrameShape,\n\tTLGeoShape,\n\tTLGroupShape,\n\tTLHandle,\n\tTLINSTANCE_ID,\n\tTLImageAsset,\n\tTLInstance,\n\tTLInstancePageState,\n\tTLInstancePresence,\n\tTLNoteShape,\n\tTLPOINTER_ID,\n\tTLPage,\n\tTLPageId,\n\tTLParentId,\n\tTLRecord,\n\tTLShape,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLStore,\n\tTLStoreSnapshot,\n\tTLUnknownBinding,\n\tTLUnknownShape,\n\tTLVideoAsset,\n\tcreateBindingId,\n\tcreateShapeId,\n\tgetShapePropKeysByStyle,\n\tisPageId,\n\tisShapeId,\n} from '@tldraw/tlschema'\nimport {\n\tFileHelpers,\n\tIndexKey,\n\tJsonObject,\n\tPerformanceTracker,\n\tResult,\n\tZERO_INDEX_KEY,\n\tannotateError,\n\tassert,\n\tassertExists,\n\tbind,\n\tcompact,\n\tdebounce,\n\tdedupe,\n\texhaustiveSwitchError,\n\tfetch,\n\tgetIndexAbove,\n\tgetIndexBetween,\n\tgetIndices,\n\tgetIndicesAbove,\n\tgetIndicesBetween,\n\tgetOwnProperty,\n\thasOwnProperty,\n\tlast,\n\tlerp,\n\tmaxBy,\n\tminBy,\n\tsortById,\n\tsortByIndex,\n\tstructuredClone,\n\tuniqueId,\n} from '@tldraw/utils'\nimport EventEmitter from 'eventemitter3'\nimport {\n\tTLEditorSnapshot,\n\tTLLoadSnapshotOptions,\n\tgetSnapshot,\n\tloadSnapshot,\n} from '../config/TLEditorSnapshot'\nimport { TLUser, createTLUser } from '../config/createTLUser'\nimport { TLAnyBindingUtilConstructor, checkBindings } from '../config/defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from '../config/defaultShapes'\nimport {\n\tDEFAULT_ANIMATION_OPTIONS,\n\tDEFAULT_CAMERA_OPTIONS,\n\tINTERNAL_POINTER_IDS,\n\tLEFT_MOUSE_BUTTON,\n\tMIDDLE_MOUSE_BUTTON,\n\tRIGHT_MOUSE_BUTTON,\n\tSTYLUS_ERASER_BUTTON,\n\tZOOM_TO_FIT_PADDING,\n} from '../constants'\nimport { exportToSvg } from '../exports/exportToSvg'\nimport { getSvgAsImage } from '../exports/getSvgAsImage'\nimport { tlmenus } from '../globals/menus'\nimport { tltime } from '../globals/time'\nimport { TldrawOptions, defaultTldrawOptions } from '../options'\nimport { Box, BoxLike } from '../primitives/Box'\nimport { Mat, MatLike } from '../primitives/Mat'\nimport { Vec, VecLike } from '../primitives/Vec'\nimport { EASINGS } from '../primitives/easings'\nimport { Geometry2d } from '../primitives/geometry/Geometry2d'\nimport { Group2d } from '../primitives/geometry/Group2d'\nimport { intersectPolygonPolygon } from '../primitives/intersect'\nimport { PI, approximately, areAnglesCompatible, clamp, pointInPolygon } from '../primitives/utils'\nimport { ReadonlySharedStyleMap, SharedStyle, SharedStyleMap } from '../utils/SharedStylesMap'\nimport { areShapesContentEqual } from '../utils/areShapesContentEqual'\nimport { dataUrlToFile } from '../utils/assets'\nimport { debugFlags } from '../utils/debug-flags'\nimport {\n\tTLDeepLink,\n\tTLDeepLinkOptions,\n\tcreateDeepLinkString,\n\tparseDeepLinkString,\n} from '../utils/deepLinks'\nimport { getIncrementedName } from '../utils/getIncrementedName'\nimport { isAccelKey } from '../utils/keyboard'\nimport { getReorderingShapesChanges } from '../utils/reorderShapes'\nimport { TLTextOptions, TiptapEditor } from '../utils/richText'\nimport { applyRotationToSnapshotShapes, getRotationSnapshot } from '../utils/rotation'\nimport { BindingOnDeleteOptions, BindingUtil } from './bindings/BindingUtil'\nimport { bindingsIndex } from './derivations/bindingsIndex'\nimport { notVisibleShapes } from './derivations/notVisibleShapes'\nimport { parentsToChildren } from './derivations/parentsToChildren'\nimport { deriveShapeIdsInCurrentPage } from './derivations/shapeIdsInCurrentPage'\nimport { ClickManager } from './managers/ClickManager/ClickManager'\nimport { EdgeScrollManager } from './managers/EdgeScrollManager/EdgeScrollManager'\nimport { FocusManager } from './managers/FocusManager/FocusManager'\nimport { FontManager } from './managers/FontManager/FontManager'\nimport { HistoryManager } from './managers/HistoryManager/HistoryManager'\nimport { ScribbleManager } from './managers/ScribbleManager/ScribbleManager'\nimport { SnapManager } from './managers/SnapManager/SnapManager'\nimport { TextManager } from './managers/TextManager/TextManager'\nimport { TickManager } from './managers/TickManager/TickManager'\nimport { UserPreferencesManager } from './managers/UserPreferencesManager/UserPreferencesManager'\nimport { ShapeUtil, TLGeometryOpts, TLResizeMode } from './shapes/ShapeUtil'\nimport { RootState } from './tools/RootState'\nimport { StateNode, TLStateNodeConstructor } from './tools/StateNode'\nimport { TLContent } from './types/clipboard-types'\nimport { TLEventMap } from './types/emit-types'\nimport {\n\tTLEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLWheelEventInfo,\n} from './types/event-types'\nimport { TLExternalAsset, TLExternalContent } from './types/external-content'\nimport { TLHistoryBatchOptions } from './types/history-types'\nimport {\n\tOptionalKeys,\n\tRequiredKeys,\n\tTLCameraMoveOptions,\n\tTLCameraOptions,\n\tTLGetShapeAtPointOptions,\n\tTLImageExportOptions,\n\tTLSvgExportOptions,\n\tTLUpdatePointerOptions,\n} from './types/misc-types'\nimport { TLAdjacentDirection, TLResizeHandle } from './types/selection-types'\n\n/** @public */\nexport type TLResizeShapeOptions = Partial<{\n\tinitialBounds: Box\n\tscaleOrigin: VecLike\n\tscaleAxisRotation: number\n\tinitialShape: TLShape\n\tinitialPageTransform: MatLike\n\tdragHandle: TLResizeHandle\n\tisAspectRatioLocked: boolean\n\tmode: TLResizeMode\n\tskipStartAndEndCallbacks: boolean\n}>\n\n/** @public */\nexport interface TLEditorOptions {\n\t/**\n\t * The Store instance to use for keeping the app's data. This may be prepopulated, e.g. by loading\n\t * from a server or database.\n\t */\n\tstore: TLStore\n\t/**\n\t * An array of shapes to use in the editor. These will be used to create and manage shapes in the editor.\n\t */\n\tshapeUtils: readonly TLAnyShapeUtilConstructor[]\n\t/**\n\t * An array of bindings to use in the editor. These will be used to create and manage bindings in the editor.\n\t */\n\tbindingUtils: readonly TLAnyBindingUtilConstructor[]\n\t/**\n\t * An array of tools to use in the editor. These will be used to handle events and manage user interactions in the editor.\n\t */\n\ttools: readonly TLStateNodeConstructor[]\n\t/**\n\t * Should return a containing html element which has all the styles applied to the editor. If not\n\t * given, the body element will be used.\n\t */\n\tgetContainer(): HTMLElement\n\t/**\n\t * A user defined externally to replace the default user.\n\t */\n\tuser?: TLUser\n\t/**\n\t * The editor's initial active tool (or other state node id).\n\t */\n\tinitialState?: string\n\t/**\n\t * Whether to automatically focus the editor when it mounts.\n\t */\n\tautoFocus?: boolean\n\t/**\n\t * Whether to infer dark mode from the user's system preferences. Defaults to false.\n\t */\n\tinferDarkMode?: boolean\n\t/**\n\t * Options for the editor's camera.\n\t */\n\tcameraOptions?: Partial<TLCameraOptions>\n\ttextOptions?: TLTextOptions\n\toptions?: Partial<TldrawOptions>\n\tlicenseKey?: string\n\tfontAssetUrls?: { [key: string]: string | undefined }\n\t/**\n\t * Provides a way to hide shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * getShapeVisibility={(shape, editor) => shape.meta.hidden ? 'hidden' : 'inherit'}\n\t * ```\n\t *\n\t * - `'inherit' | undefined` - (default) The shape will be visible unless its parent is hidden.\n\t * - `'hidden'` - The shape will be hidden.\n\t * - `'visible'` - The shape will be visible.\n\t *\n\t * @param shape - The shape to check.\n\t * @param editor - The editor instance.\n\t */\n\tgetShapeVisibility?(\n\t\tshape: TLShape,\n\t\teditor: Editor\n\t): 'visible' | 'hidden' | 'inherit' | null | undefined\n}\n\n/**\n * Options for {@link Editor.(run:1)}.\n * @public\n */\nexport interface TLEditorRunOptions extends TLHistoryBatchOptions {\n\tignoreShapeLock?: boolean\n}\n\n/** @public */\nexport interface TLRenderingShape {\n\tid: TLShapeId\n\tshape: TLShape\n\tutil: ShapeUtil\n\tindex: number\n\tbackgroundIndex: number\n\topacity: number\n}\n\n/** @public */\nexport class Editor extends EventEmitter<TLEventMap> {\n\treadonly id = uniqueId()\n\tconstructor({\n\t\tstore,\n\t\tuser,\n\t\tshapeUtils,\n\t\tbindingUtils,\n\t\ttools,\n\t\tgetContainer,\n\t\tcameraOptions,\n\t\ttextOptions,\n\t\tinitialState,\n\t\tautoFocus,\n\t\tinferDarkMode,\n\t\toptions,\n\t\tgetShapeVisibility,\n\t\tfontAssetUrls,\n\t}: TLEditorOptions) {\n\t\tsuper()\n\n\t\tthis._getShapeVisibility = getShapeVisibility\n\n\t\tthis.options = { ...defaultTldrawOptions, ...options }\n\n\t\tthis.store = store\n\t\tthis.history = new HistoryManager<TLRecord>({\n\t\t\tstore,\n\t\t\tannotateError: (error: any) => {\n\t\t\t\tthis.annotateError(error, { origin: 'history.batch', willCrashApp: true })\n\t\t\t\tthis.crash(error)\n\t\t\t},\n\t\t})\n\n\t\tthis.snaps = new SnapManager(this)\n\n\t\tthis.disposables.add(this.timers.dispose)\n\n\t\tthis._cameraOptions.set({ ...DEFAULT_CAMERA_OPTIONS, ...cameraOptions })\n\n\t\tthis._textOptions = atom('text options', textOptions ?? null)\n\n\t\tthis.user = new UserPreferencesManager(user ?? createTLUser(), inferDarkMode ?? false)\n\t\tthis.disposables.add(() => this.user.dispose())\n\n\t\tthis.getContainer = getContainer\n\n\t\tthis.textMeasure = new TextManager(this)\n\t\tthis.disposables.add(() => this.textMeasure.dispose())\n\n\t\tthis.fonts = new FontManager(this, fontAssetUrls)\n\n\t\tthis._tickManager = new TickManager(this)\n\n\t\tclass NewRoot extends RootState {\n\t\t\tstatic override initial = initialState ?? ''\n\t\t}\n\n\t\tthis.root = new NewRoot(this)\n\t\tthis.root.children = {}\n\n\t\tthis.markEventAsHandled = this.markEventAsHandled.bind(this)\n\n\t\tconst allShapeUtils = checkShapesAndAddCore(shapeUtils)\n\n\t\tconst _shapeUtils = {} as Record<string, ShapeUtil<any>>\n\t\tconst _styleProps = {} as Record<string, Map<StyleProp<unknown>, string>>\n\t\tconst allStylesById = new Map<string, StyleProp<unknown>>()\n\n\t\tfor (const Util of allShapeUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_shapeUtils[Util.type] = util\n\n\t\t\tconst propKeysByStyle = getShapePropKeysByStyle(Util.props ?? {})\n\t\t\t_styleProps[Util.type] = propKeysByStyle\n\n\t\t\tfor (const style of propKeysByStyle.keys()) {\n\t\t\t\tif (!allStylesById.has(style.id)) {\n\t\t\t\t\tallStylesById.set(style.id, style)\n\t\t\t\t} else if (allStylesById.get(style.id) !== style) {\n\t\t\t\t\tthrow Error(\n\t\t\t\t\t\t`Multiple style props with id \"${style.id}\" in use. Style prop IDs must be unique.`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.shapeUtils = _shapeUtils\n\t\tthis.styleProps = _styleProps\n\n\t\tconst allBindingUtils = checkBindings(bindingUtils)\n\t\tconst _bindingUtils = {} as Record<string, BindingUtil<any>>\n\t\tfor (const Util of allBindingUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_bindingUtils[Util.type] = util\n\t\t}\n\t\tthis.bindingUtils = _bindingUtils\n\n\t\t// Tools.\n\t\t// Accept tools from constructor parameters which may not conflict with the root note's default or\n\t\t// \"baked in\" tools, select and zoom.\n\t\tfor (const Tool of [...tools]) {\n\t\t\tif (hasOwnProperty(this.root.children!, Tool.id)) {\n\t\t\t\tthrow Error(`Can't override tool with id \"${Tool.id}\"`)\n\t\t\t}\n\t\t\tthis.root.children![Tool.id] = new Tool(this, this.root)\n\t\t}\n\n\t\tthis.scribbles = new ScribbleManager(this)\n\n\t\t// Cleanup\n\n\t\tconst cleanupInstancePageState = (\n\t\t\tprevPageState: TLInstancePageState,\n\t\t\tshapesNoLongerInPage: Set<TLShapeId>\n\t\t) => {\n\t\t\tlet nextPageState = null as null | TLInstancePageState\n\n\t\t\tconst selectedShapeIds = prevPageState.selectedShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (selectedShapeIds.length !== prevPageState.selectedShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.selectedShapeIds = selectedShapeIds\n\t\t\t}\n\n\t\t\tconst erasingShapeIds = prevPageState.erasingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (erasingShapeIds.length !== prevPageState.erasingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.erasingShapeIds = erasingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.hoveredShapeId && shapesNoLongerInPage.has(prevPageState.hoveredShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hoveredShapeId = null\n\t\t\t}\n\n\t\t\tif (prevPageState.editingShapeId && shapesNoLongerInPage.has(prevPageState.editingShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.editingShapeId = null\n\t\t\t}\n\n\t\t\tconst hintingShapeIds = prevPageState.hintingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (hintingShapeIds.length !== prevPageState.hintingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hintingShapeIds = hintingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.focusedGroupId && shapesNoLongerInPage.has(prevPageState.focusedGroupId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.focusedGroupId = null\n\t\t\t}\n\t\t\treturn nextPageState\n\t\t}\n\n\t\tthis.sideEffects = this.store.sideEffects\n\n\t\tlet deletedBindings = new Map<TLBindingId, BindingOnDeleteOptions<any>>()\n\t\tconst deletedShapeIds = new Set<TLShapeId>()\n\t\tconst invalidParents = new Set<TLShapeId>()\n\t\tlet invalidBindingTypes = new Set<string>()\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.registerOperationCompleteHandler(() => {\n\t\t\t\t// this needs to be cleared here because further effects may delete more shapes\n\t\t\t\t// and we want the next invocation of this handler to handle those separately\n\t\t\t\tdeletedShapeIds.clear()\n\n\t\t\t\tfor (const parentId of invalidParents) {\n\t\t\t\t\tinvalidParents.delete(parentId)\n\t\t\t\t\tconst parent = this.getShape(parentId)\n\t\t\t\t\tif (!parent) continue\n\n\t\t\t\t\tconst util = this.getShapeUtil(parent)\n\t\t\t\t\tconst changes = util.onChildrenChange?.(parent)\n\n\t\t\t\t\tif (changes?.length) {\n\t\t\t\t\t\tthis.updateShapes(changes)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (invalidBindingTypes.size) {\n\t\t\t\t\tconst t = invalidBindingTypes\n\t\t\t\t\tinvalidBindingTypes = new Set()\n\t\t\t\t\tfor (const type of t) {\n\t\t\t\t\t\tconst util = this.getBindingUtil(type)\n\t\t\t\t\t\tutil.onOperationComplete?.()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (deletedBindings.size) {\n\t\t\t\t\tconst t = deletedBindings\n\t\t\t\t\tdeletedBindings = new Map()\n\t\t\t\t\tfor (const opts of t.values()) {\n\t\t\t\t\t\tthis.getBindingUtil(opts.binding).onAfterDelete?.(opts)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.emit('update')\n\t\t\t})\n\t\t)\n\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.register({\n\t\t\t\tshape: {\n\t\t\t\t\tafterChange: (shapeBefore, shapeAfter) => {\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shapeAfter)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tif (binding.fromId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t\treason: 'self',\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (binding.toId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t\treason: 'self',\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if the shape's parent changed and it has a binding, update the binding\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId) {\n\t\t\t\t\t\t\tconst notifyBindingAncestryChange = (id: TLShapeId) => {\n\t\t\t\t\t\t\t\tconst descendantShape = this.getShape(id)\n\t\t\t\t\t\t\t\tif (!descendantShape) return\n\n\t\t\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(descendantShape)) {\n\t\t\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\n\t\t\t\t\t\t\t\t\tif (binding.fromId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\treason: 'ancestry',\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (binding.toId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\treason: 'ancestry',\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnotifyBindingAncestryChange(shapeAfter.id)\n\t\t\t\t\t\t\tthis.visitDescendants(shapeAfter.id, notifyBindingAncestryChange)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if this shape moved to a new page, clean up any previous page's instance state\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId && isPageId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tconst allMovingIds = new Set([shapeBefore.id])\n\t\t\t\t\t\t\tthis.visitDescendants(shapeBefore.id, (id) => {\n\t\t\t\t\t\t\t\tallMovingIds.add(id)\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tfor (const instancePageState of this.getPageStates()) {\n\t\t\t\t\t\t\t\tif (instancePageState.pageId === shapeAfter.parentId) continue\n\t\t\t\t\t\t\t\tconst nextPageState = cleanupInstancePageState(instancePageState, allMovingIds)\n\n\t\t\t\t\t\t\t\tif (nextPageState) {\n\t\t\t\t\t\t\t\t\tthis.store.put([nextPageState])\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeBefore.parentId && isShapeId(shapeBefore.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeBefore.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeAfter.parentId !== shapeBefore.parentId && isShapeId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeAfter.parentId)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (shape) => {\n\t\t\t\t\t\t// if we triggered this delete with a recursive call, don't do anything\n\t\t\t\t\t\tif (deletedShapeIds.has(shape.id)) return\n\t\t\t\t\t\t// if the deleted shape has a parent shape make sure we call it's onChildrenChange callback\n\t\t\t\t\t\tif (shape.parentId && isShapeId(shape.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shape.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedShapeIds.add(shape.id)\n\n\t\t\t\t\t\tconst deleteBindingIds: TLBindingId[] = []\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shape)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tdeleteBindingIds.push(binding.id)\n\t\t\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\t\t\tif (binding.fromId === shape.id) {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteFromShape?.({ binding, shape })\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteToShape?.({ binding, shape })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (deleteBindingIds.length) {\n\t\t\t\t\t\t\tthis.deleteBindings(deleteBindingIds)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst deletedIds = new Set([shape.id])\n\t\t\t\t\t\tconst updates = compact(\n\t\t\t\t\t\t\tthis.getPageStates().map((pageState) => {\n\t\t\t\t\t\t\t\treturn cleanupInstancePageState(pageState, deletedIds)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tif (updates.length) {\n\t\t\t\t\t\t\tthis.store.put(updates)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tbinding: {\n\t\t\t\t\tbeforeCreate: (binding) => {\n\t\t\t\t\t\tconst next = this.getBindingUtil(binding).onBeforeCreate?.({ binding })\n\t\t\t\t\t\tif (next) return next\n\t\t\t\t\t\treturn binding\n\t\t\t\t\t},\n\t\t\t\t\tafterCreate: (binding) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterCreate?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tconst updated = this.getBindingUtil(bindingAfter).onBeforeChange?.({\n\t\t\t\t\t\t\tbindingBefore,\n\t\t\t\t\t\t\tbindingAfter,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tif (updated) return updated\n\t\t\t\t\t\treturn bindingAfter\n\t\t\t\t\t},\n\t\t\t\t\tafterChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(bindingAfter.type)\n\t\t\t\t\t\tthis.getBindingUtil(bindingAfter).onAfterChange?.({ bindingBefore, bindingAfter })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onBeforeDelete?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterDelete?.({ binding })\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpage: {\n\t\t\t\t\tafterCreate: (record) => {\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst _pageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tif (!this.store.has(cameraId)) {\n\t\t\t\t\t\t\tthis.store.put([CameraRecordType.create({ id: cameraId })])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!this.store.has(_pageStateId)) {\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\tInstancePageStateRecordType.create({ id: _pageStateId, pageId: record.id }),\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (record, source) => {\n\t\t\t\t\t\t// page was deleted, need to check whether it's the current page and select another one if so\n\t\t\t\t\t\tif (this.getInstanceState()?.currentPageId === record.id) {\n\t\t\t\t\t\t\tconst backupPageId = this.getPages().find((p) => p.id !== record.id)?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: backupPageId }])\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// delete the camera and state for the page if necessary\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst instance_PageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tthis.store.remove([cameraId, instance_PageStateId])\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance: {\n\t\t\t\t\tafterChange: (prev, next, source) => {\n\t\t\t\t\t\t// instance should never be updated to a page that no longer exists (this can\n\t\t\t\t\t\t// happen when undoing a change that involves switching to a page that has since\n\t\t\t\t\t\t// been deleted by another user)\n\t\t\t\t\t\tif (!this.store.has(next.currentPageId)) {\n\t\t\t\t\t\t\tconst backupPageId = this.store.has(prev.currentPageId)\n\t\t\t\t\t\t\t\t? prev.currentPageId\n\t\t\t\t\t\t\t\t: this.getPages()[0]?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.update(next.id, (instance) => ({\n\t\t\t\t\t\t\t\t\t...instance,\n\t\t\t\t\t\t\t\t\tcurrentPageId: backupPageId,\n\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance_page_state: {\n\t\t\t\t\tafterChange: (prev, next) => {\n\t\t\t\t\t\tif (prev?.selectedShapeIds !== next?.selectedShapeIds) {\n\t\t\t\t\t\t\t// ensure that descendants and ancestors are not selected at the same time\n\t\t\t\t\t\t\tconst filtered = next.selectedShapeIds.filter((id) => {\n\t\t\t\t\t\t\t\tlet parentId = this.getShape(id)?.parentId\n\t\t\t\t\t\t\t\twhile (isShapeId(parentId)) {\n\t\t\t\t\t\t\t\t\tif (next.selectedShapeIds.includes(parentId)) {\n\t\t\t\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tparentId = this.getShape(parentId)?.parentId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn true\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tlet nextFocusedGroupId: null | TLShapeId = null\n\n\t\t\t\t\t\t\tif (filtered.length > 0) {\n\t\t\t\t\t\t\t\tconst commonGroupAncestor = this.findCommonAncestor(\n\t\t\t\t\t\t\t\t\tcompact(filtered.map((id) => this.getShape(id))),\n\t\t\t\t\t\t\t\t\t(shape) => this.isShapeOfType<TLGroupShape>(shape, 'group')\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t\tif (commonGroupAncestor) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = commonGroupAncestor\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (next?.focusedGroupId) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = next.focusedGroupId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tfiltered.length !== next.selectedShapeIds.length ||\n\t\t\t\t\t\t\t\tnextFocusedGroupId !== next.focusedGroupId\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t...next,\n\t\t\t\t\t\t\t\t\t\tselectedShapeIds: filtered,\n\t\t\t\t\t\t\t\t\t\tfocusedGroupId: nextFocusedGroupId ?? null,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t)\n\n\t\tthis._currentPageShapeIds = deriveShapeIdsInCurrentPage(this.store, () =>\n\t\t\tthis.getCurrentPageId()\n\t\t)\n\t\tthis._parentIdsToChildIds = parentsToChildren(this.store)\n\n\t\tthis.disposables.add(\n\t\t\tthis.store.listen((changes) => {\n\t\t\t\tthis.emit('change', changes)\n\t\t\t})\n\t\t)\n\t\tthis.disposables.add(this.history.dispose)\n\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.ensureStoreIsUsable()\n\n\t\t\t\t// clear ephemeral state\n\t\t\t\tthis._updateCurrentPageState({\n\t\t\t\t\teditingShapeId: null,\n\t\t\t\t\thoveredShapeId: null,\n\t\t\t\t\terasingShapeIds: [],\n\t\t\t\t})\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\tif (initialState && this.root.children[initialState] === undefined) {\n\t\t\tthrow Error(`No state found for initialState \"${initialState}\".`)\n\t\t}\n\n\t\tthis.root.enter(undefined, 'initial')\n\n\t\tthis.edgeScrollManager = new EdgeScrollManager(this)\n\t\tthis.focusManager = new FocusManager(this, autoFocus)\n\t\tthis.disposables.add(this.focusManager.dispose.bind(this.focusManager))\n\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tthis.on('tick', this._flushEventsForTick)\n\n\t\tthis.timers.requestAnimationFrame(() => {\n\t\t\tthis._tickManager.start()\n\t\t})\n\n\t\tthis.performanceTracker = new PerformanceTracker()\n\n\t\tif (this.store.props.collaboration?.mode) {\n\t\t\tconst mode = this.store.props.collaboration.mode\n\t\t\tthis.disposables.add(\n\t\t\t\treact('update collaboration mode', () => {\n\t\t\t\t\tthis.store.put([{ ...this.getInstanceState(), isReadonly: mode.get() === 'readonly' }])\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate readonly _getShapeVisibility?: TLEditorOptions['getShapeVisibility']\n\t@computed\n\tprivate getIsShapeHiddenCache() {\n\t\tif (!this._getShapeVisibility) return null\n\t\treturn this.store.createComputedCache<boolean, TLShape>('isShapeHidden', (shape: TLShape) => {\n\t\t\tconst visibility = this._getShapeVisibility!(shape, this)\n\t\t\tconst isParentHidden = PageRecordType.isId(shape.parentId)\n\t\t\t\t? false\n\t\t\t\t: this.isShapeHidden(shape.parentId)\n\n\t\t\tif (isParentHidden) return visibility !== 'visible'\n\t\t\treturn visibility === 'hidden'\n\t\t})\n\t}\n\tisShapeHidden(shapeOrId: TLShape | TLShapeId): boolean {\n\t\tif (!this._getShapeVisibility) return false\n\t\treturn !!this.getIsShapeHiddenCache!()!.get(\n\t\t\ttypeof shapeOrId === 'string' ? shapeOrId : shapeOrId.id\n\t\t)\n\t}\n\n\treadonly options: TldrawOptions\n\n\treadonly contextId = uniqueId()\n\n\t/**\n\t * The editor's store\n\t *\n\t * @public\n\t */\n\treadonly store: TLStore\n\n\t/**\n\t * The root state of the statechart.\n\t *\n\t * @public\n\t */\n\treadonly root: StateNode\n\n\t/**\n\t * A set of functions to call when the app is disposed.\n\t *\n\t * @public\n\t */\n\treadonly disposables = new Set<() => void>()\n\n\t/**\n\t * Whether the editor is disposed.\n\t *\n\t * @public\n\t */\n\tisDisposed = false\n\n\t/** @internal */\n\tprivate readonly _tickManager\n\n\t/**\n\t * A manager for the app's snapping feature.\n\t *\n\t * @public\n\t */\n\treadonly snaps: SnapManager\n\n\t/**\n\t * A manager for the any asynchronous events and making sure they're\n\t * cleaned up upon disposal.\n\t *\n\t * @public\n\t */\n\treadonly timers = tltime.forContext(this.contextId)\n\n\t/**\n\t * A manager for the user and their preferences.\n\t *\n\t * @public\n\t */\n\treadonly user: UserPreferencesManager\n\n\t/**\n\t * A helper for measuring text.\n\t *\n\t * @public\n\t */\n\treadonly textMeasure: TextManager\n\n\t/**\n\t * A utility for managing the set of fonts that should be rendered in the document.\n\t *\n\t * @public\n\t */\n\treadonly fonts: FontManager\n\n\t/**\n\t * A manager for the editor's scribbles.\n\t *\n\t * @public\n\t */\n\treadonly scribbles: ScribbleManager\n\n\t/**\n\t * A manager for side effects and correct state enforcement. See {@link @tldraw/store#StoreSideEffects} for details.\n\t *\n\t * @public\n\t */\n\treadonly sideEffects: StoreSideEffects<TLRecord>\n\n\t/**\n\t * A manager for moving the camera when the mouse is at the edge of the screen.\n\t *\n\t * @public\n\t */\n\tedgeScrollManager: EdgeScrollManager\n\n\t/**\n\t * A manager for ensuring correct focus. See FocusManager for details.\n\t *\n\t * @internal\n\t */\n\tprivate focusManager: FocusManager\n\n\t/**\n\t * The current HTML element containing the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * const container = editor.getContainer()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetContainer: () => HTMLElement\n\n\t/**\n\t * Dispose the editor.\n\t *\n\t * @public\n\t */\n\tdispose() {\n\t\tthis.disposables.forEach((dispose) => dispose())\n\t\tthis.disposables.clear()\n\t\tthis.store.dispose()\n\t\tthis.isDisposed = true\n\t}\n\n\t/* ------------------- Shape Utils ------------------ */\n\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tshapeUtils: { readonly [K in string]?: ShapeUtil<TLUnknownShape> }\n\n\tstyleProps: { [key: string]: Map<StyleProp<any>, string> }\n\n\t/**\n\t * Get a shape util from a shape itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getShapeUtil(myArrowShape)\n\t * const util = editor.getShapeUtil('arrow')\n\t * const util = editor.getShapeUtil<TLArrowShape>(myArrowShape)\n\t * const util = editor.getShapeUtil(TLArrowShape)('arrow')\n\t * ```\n\t *\n\t * @param shape - A shape, shape partial, or shape type.\n\t *\n\t * @public\n\t */\n\tgetShapeUtil<S extends TLUnknownShape>(shape: S | TLShapePartial<S>): ShapeUtil<S>\n\tgetShapeUtil<S extends TLUnknownShape>(type: S['type']): ShapeUtil<S>\n\tgetShapeUtil<T extends ShapeUtil>(type: T extends ShapeUtil<infer R> ? R['type'] : string): T\n\tgetShapeUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst shapeUtil = getOwnProperty(this.shapeUtils, type)\n\t\tassert(shapeUtil, `No shape util found for type \"${type}\"`)\n\t\treturn shapeUtil\n\t}\n\n\t/**\n\t * Returns true if the editor has a shape util for the given shape / shape type.\n\t *\n\t * @param shape - A shape, shape partial, or shape type.\n\t */\n\thasShapeUtil<S extends TLUnknownShape>(shape: S | TLShapePartial<S>): boolean\n\thasShapeUtil<S extends TLUnknownShape>(type: S['type']): boolean\n\thasShapeUtil<T extends ShapeUtil>(\n\t\ttype: T extends ShapeUtil<infer R> ? R['type'] : string\n\t): boolean\n\thasShapeUtil(arg: string | { type: string }): boolean {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\treturn hasOwnProperty(this.shapeUtils, type)\n\t}\n\n\t/* ------------------- Binding Utils ------------------ */\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tbindingUtils: { readonly [K in string]?: BindingUtil<TLUnknownBinding> }\n\n\t/**\n\t * Get a binding util from a binding itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getBindingUtil(myArrowBinding)\n\t * const util = editor.getBindingUtil('arrow')\n\t * const util = editor.getBindingUtil<TLArrowBinding>(myArrowBinding)\n\t * const util = editor.getBindingUtil(TLArrowBinding)('arrow')\n\t * ```\n\t *\n\t * @param binding - A binding, binding partial, or binding type.\n\t *\n\t * @public\n\t */\n\tgetBindingUtil<S extends TLUnknownBinding>(binding: S | { type: S['type'] }): BindingUtil<S>\n\tgetBindingUtil<S extends TLUnknownBinding>(type: S['type']): BindingUtil<S>\n\tgetBindingUtil<T extends BindingUtil>(\n\t\ttype: T extends BindingUtil<infer R> ? R['type'] : string\n\t): T\n\tgetBindingUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst bindingUtil = getOwnProperty(this.bindingUtils, type)\n\t\tassert(bindingUtil, `No binding util found for type \"${type}\"`)\n\t\treturn bindingUtil\n\t}\n\n\t/* --------------------- History -------------------- */\n\n\t/**\n\t * A manager for the app's history.\n\t *\n\t * @readonly\n\t */\n\tprotected readonly history: HistoryManager<TLRecord>\n\n\t/**\n\t * Undo to the last mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.undo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tundo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.undo()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can undo.\n\t *\n\t * @public\n\t */\n\t@computed getCanUndo(): boolean {\n\t\treturn this.history.getNumUndos() > 0\n\t}\n\n\t/**\n\t * Redo to the next mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.redo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tredo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.redo()\n\t\treturn this\n\t}\n\n\tclearHistory() {\n\t\tthis.history.clear()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can redo.\n\t *\n\t * @public\n\t */\n\t@computed getCanRedo(): boolean {\n\t\treturn this.history.getNumRedos() > 0\n\t}\n\n\t/**\n\t * Create a new \"mark\", or stopping point, in the undo redo history. Creating a mark will clear\n\t * any redos. You typically want to do this just before a user interaction begins or is handled.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.markHistoryStoppingPoint()\n\t * editor.flipShapes(editor.getSelectedShapes())\n\t * ```\n\t * @example\n\t * ```ts\n\t * const beginRotateMark = editor.markHistoryStoppingPoint()\n\t * // if the use cancels the rotation, you can bail back to this mark\n\t * editor.bailToMark(beginRotateMark)\n\t * ```\n\t *\n\t * @public\n\t * @param name - The name of the mark, useful for debugging the undo/redo stacks\n\t * @returns a unique id for the mark that can be used with `squashToMark` or `bailToMark`.\n\t */\n\tmarkHistoryStoppingPoint(name?: string): string {\n\t\tconst id = `[${name ?? 'stop'}]_${uniqueId()}`\n\t\tthis.history._mark(id)\n\t\treturn id\n\t}\n\n\t/**\n\t * @internal this is only used to implement some backwards-compatibility logic. Should be fine to delete after 6 months or whatever.\n\t */\n\tgetMarkIdMatching(idSubstring: string) {\n\t\treturn this.history.getMarkIdMatching(idSubstring)\n\t}\n\n\t/**\n\t * Coalesces all changes since the given mark into a single change, removing any intermediate marks.\n\t *\n\t * This is useful if you need to 'compress' the recent history to simplify the undo/redo experience of a complex interaction.\n\t *\n\t * @example\n\t * ```ts\n\t * const bumpShapesMark = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.squashToMark(bumpShapesMark)\n\t * ```\n\t *\n\t * @param markId - The mark id to squash to.\n\t */\n\tsquashToMark(markId: string): this {\n\t\tthis.history.squashToMark(markId)\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the closest mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bail()\n\t * ```\n\t *\n\t * @public\n\t */\n\tbail() {\n\t\tthis.history.bail()\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the given mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * const beginDrag = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.bailToMark(beginDrag)\n\t * ```\n\t *\n\t * @public\n\t */\n\tbailToMark(id: string): this {\n\t\tthis.history.bailToMark(id)\n\t\treturn this\n\t}\n\n\tprivate _shouldIgnoreShapeLock = false\n\n\t/**\n\t * Run a function in a transaction with optional options for context.\n\t * You can use the options to change the way that history is treated\n\t * or allow changes to locked shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * // updating with\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * }, { history: \"ignore\" })\n\t *\n\t * // forcing changes / deletions for locked shapes\n\t * editor.toggleLock([myShape])\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * \teditor.deleteShape(myShape)\n\t * }, { ignoreShapeLock: true }, )\n\t * ```\n\t *\n\t * @param fn - The callback function to run.\n\t * @param opts - The options for the batch.\n\t *\n\t *\n\t * @public\n\t */\n\trun(fn: () => void, opts?: TLEditorRunOptions): this {\n\t\tconst previousIgnoreShapeLock = this._shouldIgnoreShapeLock\n\t\tthis._shouldIgnoreShapeLock = opts?.ignoreShapeLock ?? previousIgnoreShapeLock\n\t\ttry {\n\t\t\tthis.history.batch(fn, opts)\n\t\t} finally {\n\t\t\tthis._shouldIgnoreShapeLock = previousIgnoreShapeLock\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/* --------------------- Errors --------------------- */\n\n\t/** @internal */\n\tannotateError(\n\t\terror: unknown,\n\t\t{\n\t\t\torigin,\n\t\t\twillCrashApp,\n\t\t\ttags,\n\t\t\textras,\n\t\t}: {\n\t\t\torigin: string\n\t\t\twillCrashApp: boolean\n\t\t\ttags?: Record<string, string | boolean | number>\n\t\t\textras?: Record<string, unknown>\n\t\t}\n\t): this {\n\t\tconst defaultAnnotations = this.createErrorAnnotations(origin, willCrashApp)\n\t\tannotateError(error, {\n\t\t\ttags: { ...defaultAnnotations.tags, ...tags },\n\t\t\textras: { ...defaultAnnotations.extras, ...extras },\n\t\t})\n\t\tif (willCrashApp) {\n\t\t\tthis.store.markAsPossiblyCorrupted()\n\t\t}\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tcreateErrorAnnotations(origin: string, willCrashApp: boolean | 'unknown') {\n\t\ttry {\n\t\t\tconst editingShapeId = this.getEditingShapeId()\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {\n\t\t\t\t\tactiveStateNode: this.root.getPath(),\n\t\t\t\t\tselectedShapes: this.getSelectedShapes().map((s) => {\n\t\t\t\t\t\tconst { props, ...rest } = s\n\t\t\t\t\t\tconst { text: _text, richText: _richText, ...restProps } = props as any\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...rest,\n\t\t\t\t\t\t\tprops: restProps,\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tselectionCount: this.getSelectedShapes().length,\n\t\t\t\t\teditingShape: editingShapeId ? this.getShape(editingShapeId) : undefined,\n\t\t\t\t\tinputs: this.inputs,\n\t\t\t\t\tpageState: this.getCurrentPageState(),\n\t\t\t\t\tinstanceState: this.getInstanceState(),\n\t\t\t\t\tcollaboratorCount: this.getCollaboratorsOnCurrentPage().length,\n\t\t\t\t},\n\t\t\t}\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {},\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tprivate _crashingError: unknown | null = null\n\n\t/**\n\t * We can't use an `atom` here because there's a chance that when `crashAndReportError` is called,\n\t * we're in a transaction that's about to be rolled back due to the same error we're currently\n\t * reporting.\n\t *\n\t * Instead, to listen to changes to this value, you need to listen to app's `crash` event.\n\t *\n\t * @internal\n\t */\n\tgetCrashingError() {\n\t\treturn this._crashingError\n\t}\n\n\t/** @internal */\n\tcrash(error: unknown): this {\n\t\tthis._crashingError = error\n\t\tthis.store.markAsPossiblyCorrupted()\n\t\tthis.emit('crash', { error })\n\t\treturn this\n\t}\n\n\t/* ------------------- Statechart ------------------- */\n\n\t/**\n\t * The editor's current path of active states.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPath() // \"select.idle\"\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPath() {\n\t\treturn this.root.getPath().split('root.')[1]\n\t}\n\n\t/**\n\t * Get whether a certain tool (or other state node) is currently active.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isIn('select')\n\t * editor.isIn('select.brushing')\n\t * ```\n\t *\n\t * @param path - The path of active states, separated by periods.\n\t *\n\t * @public\n\t */\n\tisIn(path: string): boolean {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return true\n\t\t\tconst current = state.getCurrent()\n\t\t\tif (current?.id === id) {\n\t\t\t\tif (ids.length === 0) return true\n\t\t\t\tstate = current\n\t\t\t\tcontinue\n\t\t\t} else return false\n\t\t}\n\t\treturn false\n\t}\n\n\t/**\n\t * Get whether the state node is in any of the given active paths.\n\t *\n\t * @example\n\t * ```ts\n\t * state.isInAny('select', 'erase')\n\t * state.isInAny('select.brushing', 'erase.idle')\n\t * ```\n\t *\n\t * @public\n\t */\n\tisInAny(...paths: string[]): boolean {\n\t\treturn paths.some((path) => this.isIn(path))\n\t}\n\n\t/**\n\t * Set the selected tool.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentTool('hand')\n\t * editor.setCurrentTool('hand', { date: Date.now() })\n\t * ```\n\t *\n\t * @param id - The id of the tool to select.\n\t * @param info - Arbitrary data to pass along into the transition.\n\t *\n\t * @public\n\t */\n\tsetCurrentTool(id: string, info = {}): this {\n\t\tthis.root.transition(id, info)\n\t\treturn this\n\t}\n\n\t/**\n\t * The current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentTool(): StateNode {\n\t\treturn this.root.getCurrent()!\n\t}\n\n\t/**\n\t * The id of the current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentToolId(): string {\n\t\tconst currentTool = this.getCurrentTool()\n\t\tif (!currentTool) return ''\n\t\treturn currentTool.getCurrentToolIdMask() ?? currentTool.id\n\t}\n\n\t/**\n\t * Get a descendant by its path.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getStateDescendant('select')\n\t * editor.getStateDescendant('select.brushing')\n\t * ```\n\t *\n\t * @param path - The descendant's path of state ids, separated by periods.\n\t *\n\t * @public\n\t */\n\tgetStateDescendant<T extends StateNode>(path: string): T | undefined {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return state as T\n\t\t\tconst childState = state.children?.[id]\n\t\t\tif (!childState) return undefined\n\t\t\tstate = childState\n\t\t}\n\t\treturn state as T\n\t}\n\n\t/* ---------------- Document Settings --------------- */\n\n\t/**\n\t * The global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\t@computed getDocumentSettings() {\n\t\treturn this.store.get(TLDOCUMENT_ID)!\n\t}\n\n\t/**\n\t * Update the global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\tupdateDocumentSettings(settings: Partial<TLDocument>): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getDocumentSettings(), ...settings }])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/* ----------------- Instance State ----------------- */\n\n\t/**\n\t * The current instance's state.\n\t *\n\t * @public\n\t */\n\t@computed getInstanceState(): TLInstance {\n\t\treturn this.store.get(TLINSTANCE_ID)!\n\t}\n\n\t/**\n\t * Update the instance's state.\n\t *\n\t * @param partial - A partial object to update the instance state with.\n\t * @param historyOptions - History batch options.\n\t *\n\t * @public\n\t */\n\tupdateInstanceState(\n\t\tpartial: Partial<Omit<TLInstance, 'currentPageId'>>,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tthis._updateInstanceState(partial, { history: 'ignore', ...historyOptions })\n\n\t\tif (partial.isChangingStyle !== undefined) {\n\t\t\tclearTimeout(this._isChangingStyleTimeout)\n\t\t\tif (partial.isChangingStyle === true) {\n\t\t\t\t// If we've set to true, set a new reset timeout to change the value back to false after 1 seconds\n\t\t\t\tthis._isChangingStyleTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\tthis._updateInstanceState({ isChangingStyle: false }, { history: 'ignore' })\n\t\t\t\t}, 1000)\n\t\t\t}\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateInstanceState(\n\t\tpartial: Partial<Omit<TLInstance, 'currentPageId'>>,\n\t\topts?: TLHistoryBatchOptions\n\t) {\n\t\tthis.run(() => {\n\t\t\tthis.store.put([\n\t\t\t\t{\n\t\t\t\t\t...this.getInstanceState(),\n\t\t\t\t\t...partial,\n\t\t\t\t},\n\t\t\t])\n\t\t}, opts)\n\t}\n\n\t/** @internal */\n\tprivate _isChangingStyleTimeout = -1 as any\n\n\t// Menus\n\n\tmenus = tlmenus.forContext(this.contextId)\n\n\t/* --------------------- Cursor --------------------- */\n\n\t/**\n\t * Set the cursor.\n\t *\n\t * @param cursor - The cursor to set.\n\t * @public\n\t */\n\tsetCursor(cursor: Partial<TLCursor>) {\n\t\tthis.updateInstanceState({ cursor: { ...this.getInstanceState().cursor, ...cursor } })\n\t\treturn this\n\t}\n\n\t/* ------------------- Page State ------------------- */\n\n\t/**\n\t * Page states.\n\t *\n\t * @public\n\t */\n\t@computed getPageStates(): TLInstancePageState[] {\n\t\treturn this._getPageStatesQuery().get()\n\t}\n\n\t/** @internal */\n\t@computed private _getPageStatesQuery() {\n\t\treturn this.store.query.records('instance_page_state')\n\t}\n\n\t/**\n\t * The current page state.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageState(): TLInstancePageState {\n\t\treturn this.store.get(this._getCurrentPageStateId())!\n\t}\n\n\t/** @internal */\n\t@computed private _getCurrentPageStateId() {\n\t\treturn InstancePageStateRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * Update this instance's page state.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateCurrentPageState({ id: 'page1', editingShapeId: 'shape:123' })\n\t * ```\n\t *\n\t * @param partial - The partial of the page state object containing the changes.\n\t *\n\t * @public\n\t */\n\tupdateCurrentPageState(\n\t\tpartial: Partial<\n\t\t\tOmit<TLInstancePageState, 'selectedShapeIds' | 'editingShapeId' | 'pageId' | 'focusedGroupId'>\n\t\t>\n\t): this {\n\t\tthis._updateCurrentPageState(partial)\n\t\treturn this\n\t}\n\t_updateCurrentPageState(partial: Partial<Omit<TLInstancePageState, 'selectedShapeIds'>>) {\n\t\tthis.store.update(partial.id ?? this.getCurrentPageState().id, (state) => ({\n\t\t\t...state,\n\t\t\t...partial,\n\t\t}))\n\t}\n\n\t/**\n\t * The current selected ids.\n\t *\n\t * @public\n\t */\n\t@computed getSelectedShapeIds() {\n\t\treturn this.getCurrentPageState().selectedShapeIds\n\t}\n\n\t/**\n\t * An array containing all of the currently selected shapes.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getSelectedShapes(): TLShape[] {\n\t\treturn compact(this.getSelectedShapeIds().map((id) => this.store.get(id)))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setSelectedShapes(['id1'])\n\t * editor.setSelectedShapes(['id1', 'id2'])\n\t * ```\n\t *\n\t * @param shapes - The shape (or shape ids) to select.\n\t *\n\t * @public\n\t */\n\tsetSelectedShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tconst ids = shapes.map((shape) => (typeof shape === 'string' ? shape : shape.id))\n\t\t\t\tconst { selectedShapeIds: prevSelectedShapeIds } = this.getCurrentPageState()\n\t\t\t\tconst prevSet = new Set(prevSelectedShapeIds)\n\n\t\t\t\tif (ids.length === prevSet.size && ids.every((id) => prevSet.has(id))) return null\n\n\t\t\t\tthis.store.put([{ ...this.getCurrentPageState(), selectedShapeIds: ids }])\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Determine whether or not any of a shape's ancestors are selected.\n\t *\n\t * @param shape - The shape (or shape id) of the shape to check.\n\t *\n\t * @public\n\t */\n\tisAncestorSelected(shape: TLShape | TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : (shape?.id ?? null)\n\t\tconst _shape = this.getShape(id)\n\t\tif (!_shape) return false\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn !!this.findShapeAncestor(_shape, (parent) => selectedShapeIds.includes(parent.id))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.select('id1')\n\t * editor.select('id1', 'id2')\n\t * ```\n\t *\n\t * @param shapes - The shape (or the shape ids) to select.\n\t *\n\t * @public\n\t */\n\tselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tthis.setSelectedShapes(ids)\n\t\treturn this\n\t}\n\n\t/**\n\t * Remove a shape from the existing set of selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deselect(shape.id)\n\t * ```\n\t *\n\t * @public\n\t */\n\tdeselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tif (selectedShapeIds.length > 0 && ids.length > 0) {\n\t\t\tthis.setSelectedShapes(selectedShapeIds.filter((id) => !ids.includes(id)))\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Select all shapes. If the user has selected shapes that share a parent,\n\t * select all shapes within that parent. If the user has not selected any shapes,\n\t * or if the shapes shapes are only on select all shapes on the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectAll()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectAll(): this {\n\t\tlet parentToSelectWithinId: TLParentId | null = null\n\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\n\t\t// If we have selected shapes, try to find a parent to select within\n\t\tif (selectedShapeIds.length > 0) {\n\t\t\tfor (const id of selectedShapeIds) {\n\t\t\t\tconst shape = this.getShape(id)\n\t\t\t\tif (!shape) continue\n\t\t\t\tif (parentToSelectWithinId === null) {\n\t\t\t\t\t// If we haven't found a parent yet, set this parent as the parent to select within\n\t\t\t\t\tparentToSelectWithinId = shape.parentId\n\t\t\t\t} else if (parentToSelectWithinId !== shape.parentId) {\n\t\t\t\t\t// If we've found two different parents, we can't select all, do nothing\n\t\t\t\t\treturn this\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we haven't found a parent from our selected shapes, select the current page\n\t\tif (!parentToSelectWithinId) {\n\t\t\tparentToSelectWithinId = this.getCurrentPageId()\n\t\t}\n\n\t\t// Select all the unlocked shapes within the parent\n\t\tconst ids = this.getSortedChildIdsForParent(parentToSelectWithinId)\n\t\tif (ids.length <= 0) return this\n\t\tthis.setSelectedShapes(this._getUnlockedShapeIds(ids))\n\t\treturn this\n\t}\n\n\t/**\n\t * Select the next shape in the reading order or in cardinal order.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectAdjacentShape('next')\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectAdjacentShape(direction: TLAdjacentDirection) {\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tconst firstParentId = selectedShapeIds[0] ? this.getShape(selectedShapeIds[0])?.parentId : null\n\t\tconst isSelectedWithinContainer =\n\t\t\tfirstParentId &&\n\t\t\tselectedShapeIds.every((shapeId) => this.getShape(shapeId)?.parentId === firstParentId) &&\n\t\t\t!isPageId(firstParentId)\n\t\tconst filteredShapes = isSelectedWithinContainer\n\t\t\t? this.getCurrentPageShapes().filter((shape) => shape.parentId === firstParentId)\n\t\t\t: this.getCurrentPageShapes().filter((shape) => isPageId(shape.parentId))\n\t\tconst readingOrderShapes = isSelectedWithinContainer\n\t\t\t? this._getShapesInReadingOrder(filteredShapes)\n\t\t\t: this.getCurrentPageShapesInReadingOrder()\n\t\tconst currentShapeId: TLShapeId | undefined =\n\t\t\tselectedShapeIds.length === 1\n\t\t\t\t? selectedShapeIds[0]\n\t\t\t\t: readingOrderShapes.find((shape) => selectedShapeIds.includes(shape.id))?.id\n\n\t\tlet adjacentShapeId: TLShapeId\n\t\tif (direction === 'next' || direction === 'prev') {\n\t\t\tconst shapeIds = readingOrderShapes.map((shape) => shape.id)\n\n\t\t\tconst currentIndex = currentShapeId ? shapeIds.indexOf(currentShapeId) : -1\n\t\t\tconst adjacentIndex =\n\t\t\t\t(currentIndex + (direction === 'next' ? 1 : -1) + shapeIds.length) % shapeIds.length\n\t\t\tadjacentShapeId = shapeIds[adjacentIndex]\n\t\t} else {\n\t\t\tif (!currentShapeId) return\n\t\t\tadjacentShapeId = this.getNearestAdjacentShape(filteredShapes, currentShapeId, direction)\n\t\t}\n\n\t\tconst shape = this.getShape(adjacentShapeId)\n\t\tif (!shape) return\n\n\t\tthis._selectShapesAndZoom([shape.id])\n\t}\n\n\t/**\n\t * Generates a reading order for shapes based on rows grouping.\n\t * Tries to keep a natural reading order (left-to-right, top-to-bottom).\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapesInReadingOrder(): TLShape[] {\n\t\tconst shapes = this.getCurrentPageShapes().filter((shape) => isPageId(shape.parentId))\n\t\treturn this._getShapesInReadingOrder(shapes)\n\t}\n\n\tprivate _getShapesInReadingOrder(shapes: TLShape[]): TLShape[] {\n\t\tconst SHALLOW_ANGLE = 20\n\t\tconst ROW_THRESHOLD = 100\n\n\t\tconst tabbableShapes = shapes.filter((shape) => this.getShapeUtil(shape).canTabTo(shape))\n\n\t\tif (tabbableShapes.length <= 1) return tabbableShapes\n\n\t\tconst shapesWithCenters = tabbableShapes.map((shape) => ({\n\t\t\tshape,\n\t\t\tcenter: this.getShapePageBounds(shape)!.center,\n\t\t}))\n\t\tshapesWithCenters.sort((a, b) => a.center.y - b.center.y)\n\n\t\tconst rows: Array<typeof shapesWithCenters> = []\n\n\t\t// First, group shapes into rows based on y-coordinates.\n\t\tfor (const shapeWithCenter of shapesWithCenters) {\n\t\t\tlet rowIndex = -1\n\t\t\tfor (let i = rows.length - 1; i >= 0; i--) {\n\t\t\t\tconst row = rows[i]\n\t\t\t\tconst lastShapeInRow = row[row.length - 1]\n\n\t\t\t\t// If the shape is close enough vertically to the last shape in this row.\n\t\t\t\tif (Math.abs(shapeWithCenter.center.y - lastShapeInRow.center.y) < ROW_THRESHOLD) {\n\t\t\t\t\trowIndex = i\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If no suitable row found, create a new row.\n\t\t\tif (rowIndex === -1) {\n\t\t\t\trows.push([shapeWithCenter])\n\t\t\t} else {\n\t\t\t\trows[rowIndex].push(shapeWithCenter)\n\t\t\t}\n\t\t}\n\n\t\t// Then, sort each row by x-coordinate (left-to-right).\n\t\tfor (const row of rows) {\n\t\t\trow.sort((a, b) => a.center.x - b.center.x)\n\t\t}\n\n\t\t// Finally, apply angle/distance weight adjustments within rows for closely positioned shapes.\n\t\tfor (const row of rows) {\n\t\t\tif (row.length <= 2) continue\n\n\t\t\tfor (let i = 0; i < row.length - 2; i++) {\n\t\t\t\tconst currentShape = row[i]\n\t\t\t\tconst nextShape = row[i + 1]\n\t\t\t\tconst nextNextShape = row[i + 2]\n\n\t\t\t\t// Only consider adjustment if the next two shapes are relatively close to each other.\n\t\t\t\tconst dist1 = Vec.Dist2(currentShape.center, nextShape.center)\n\t\t\t\tconst dist2 = Vec.Dist2(currentShape.center, nextNextShape.center)\n\n\t\t\t\t// Check if the 2nd shape is actually closer to the current shape.\n\t\t\t\tif (dist2 < dist1 * 0.9) {\n\t\t\t\t\t// Check if it's a shallow enough angle.\n\t\t\t\t\tconst angle = Math.abs(\n\t\t\t\t\t\tVec.Angle(currentShape.center, nextNextShape.center) * (180 / Math.PI)\n\t\t\t\t\t)\n\t\t\t\t\tif (angle <= SHALLOW_ANGLE) {\n\t\t\t\t\t\t// Swap swap.\n\t\t\t\t\t\t;[row[i + 1], row[i + 2]] = [row[i + 2], row[i + 1]]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn rows.flat().map((item) => item.shape)\n\t}\n\n\t/**\n\t * Find the nearest adjacent shape in a specific direction.\n\t *\n\t * @public\n\t */\n\tgetNearestAdjacentShape(\n\t\tshapes: TLShape[],\n\t\tcurrentShapeId: TLShapeId,\n\t\tdirection: 'left' | 'right' | 'up' | 'down'\n\t): TLShapeId {\n\t\tconst directionToAngle = { right: 0, left: 180, down: 90, up: 270 }\n\t\tconst currentShape = this.getShape(currentShapeId)\n\t\tif (!currentShape) return currentShapeId\n\n\t\tconst tabbableShapes = shapes.filter(\n\t\t\t(shape) => this.getShapeUtil(shape).canTabTo(shape) && shape.id !== currentShapeId\n\t\t)\n\t\tif (!tabbableShapes.length) return currentShapeId\n\n\t\tconst currentCenter = this.getShapePageBounds(currentShape)!.center\n\t\tconst shapesWithCenters = tabbableShapes.map((shape) => ({\n\t\t\tshape,\n\t\t\tcenter: this.getShapePageBounds(shape)!.center,\n\t\t}))\n\n\t\t// Filter shapes that are in the same direction.\n\t\tconst shapesInDirection = shapesWithCenters.filter(({ center }) => {\n\t\t\tconst isRight = center.x > currentCenter.x\n\t\t\tconst isDown = center.y > currentCenter.y\n\t\t\tconst xDist = center.x - currentCenter.x\n\t\t\tconst yDist = center.y - currentCenter.y\n\t\t\tconst isInXDirection = Math.abs(yDist) < Math.abs(xDist) * 2\n\t\t\tconst isInYDirection = Math.abs(xDist) < Math.abs(yDist) * 2\n\t\t\tif (direction === 'left' || direction === 'right') {\n\t\t\t\treturn isInXDirection && (direction === 'right' ? isRight : !isRight)\n\t\t\t}\n\t\t\tif (direction === 'up' || direction === 'down') {\n\t\t\t\treturn isInYDirection && (direction === 'down' ? isDown : !isDown)\n\t\t\t}\n\t\t})\n\n\t\tif (shapesInDirection.length === 0) return currentShapeId\n\n\t\t// Ok, now score that subset of shapes.\n\t\tconst lowestScoringShape = minBy(shapesInDirection, ({ center }) => {\n\t\t\t// Distance is the primary weighting factor.\n\t\t\tconst distance = Vec.Dist2(currentCenter, center)\n\n\t\t\t// Distance along the primary axis.\n\t\t\tconst dirProp = ['left', 'right'].includes(direction) ? 'x' : 'y'\n\t\t\tconst directionalDistance = Math.abs(center[dirProp] - currentCenter[dirProp])\n\n\t\t\t// Distance off the perpendicular to the primary axis.\n\t\t\tconst offProp = ['left', 'right'].includes(direction) ? 'y' : 'x'\n\t\t\tconst offAxisDeviation = Math.abs(center[offProp] - currentCenter[offProp])\n\n\t\t\t// Angle in degrees\n\t\t\tconst angle = Math.abs(Vec.Angle(currentCenter, center) * (180 / Math.PI))\n\t\t\tconst angleDeviation = Math.abs(angle - directionToAngle[direction])\n\n\t\t\t// Calculate final score (lower is better).\n\t\t\t// Weight factors to prioritize:\n\t\t\t// 1. Shapes directly in line with the current shape\n\t\t\t// 2. Shapes closer to the current shape\n\t\t\t// 3. Shapes with less angular deviation from the primary direction\n\t\t\treturn (\n\t\t\t\tdistance * 1.0 + // Base distance\n\t\t\t\toffAxisDeviation * 2.0 + // Heavy penalty for off-axis deviation\n\t\t\t\t(distance - directionalDistance) * 1.5 + // Penalty for diagonal distance\n\t\t\t\tangleDeviation * 0.5\n\t\t\t) // Slight penalty for angular deviation\n\t\t})\n\n\t\treturn lowestScoringShape!.shape.id\n\t}\n\n\tselectParentShape() {\n\t\tconst selectedShape = this.getOnlySelectedShape()\n\t\tif (!selectedShape) return\n\t\tconst parentShape = this.getShape(selectedShape.parentId)\n\t\tif (!parentShape) return\n\t\tthis._selectShapesAndZoom([parentShape.id])\n\t}\n\n\tselectFirstChildShape() {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\t\tif (!selectedShapes.length) return\n\t\tconst selectedShape = selectedShapes[0]\n\t\tconst children = this.getSortedChildIdsForParent(selectedShape.id)\n\t\t\t.map((id) => this.getShape(id))\n\t\t\t.filter((i) => i) as TLShape[]\n\t\tconst sortedChildren = this._getShapesInReadingOrder(children)\n\t\tif (sortedChildren.length === 0) return\n\t\tthis._selectShapesAndZoom([sortedChildren[0].id])\n\t}\n\n\tprivate _selectShapesAndZoom(ids: TLShapeId[]) {\n\t\tthis.setSelectedShapes(ids)\n\t\tthis.zoomToSelectionIfOffscreen(256, {\n\t\t\tanimation: {\n\t\t\t\tduration: this.options.animationMediumMs,\n\t\t\t},\n\t\t\tinset: 0,\n\t\t})\n\t}\n\n\t/**\n\t * Clear the selection.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectNone()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectNone(): this {\n\t\tif (this.getSelectedShapeIds().length > 0) {\n\t\t\tthis.setSelectedShapes([])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The id of the app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape's id.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShapeId(): TLShapeId | null {\n\t\treturn this.getOnlySelectedShape()?.id ?? null\n\t}\n\n\t/**\n\t * The app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShape(): TLShape | null {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\t\treturn selectedShapes.length === 1 ? selectedShapes[0] : null\n\t}\n\n\t/**\n\t * Get the page bounds of all the provided shapes.\n\t *\n\t * @public\n\t */\n\tgetShapesPageBounds(shapeIds: TLShapeId[]): Box | null {\n\t\tconst bounds = compact(shapeIds.map((id) => this.getShapePageBounds(id)))\n\t\tif (bounds.length === 0) return null\n\t\treturn Box.Common(bounds)\n\t}\n\n\t/**\n\t * The current page bounds of all the selected shapes. If the\n\t * selection is rotated, then these bounds are the axis-aligned\n\t * box that the rotated bounds would fit inside of.\n\t *\n\t * @readonly\n\t *\n\t * @public\n\t */\n\t@computed getSelectionPageBounds(): Box | null {\n\t\treturn this.getShapesPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\tgetSelectionScreenBounds(): Box | undefined {\n\t\tconst bounds = this.getSelectionPageBounds()\n\t\tif (!bounds) return undefined\n\t\tconst { x, y } = this.pageToScreen(bounds.point)\n\t\tconst zoom = this.getZoomLevel()\n\t\treturn new Box(x, y, bounds.width * zoom, bounds.height * zoom)\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesSharedRotation(shapeIds: TLShapeId[]) {\n\t\tlet foundFirst = false // annoying but we can't use an i===0 check because we need to skip over undefineds\n\t\tlet rotation = 0\n\t\tfor (let i = 0, n = shapeIds.length; i < n; i++) {\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[i])\n\t\t\tif (!pageTransform) continue\n\t\t\tif (foundFirst) {\n\t\t\t\tif (pageTransform.rotation() !== rotation) {\n\t\t\t\t\t// There are at least 2 different rotations, so the common rotation is zero\n\t\t\t\t\treturn 0\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// First rotation found\n\t\t\t\tfoundFirst = true\n\t\t\t\trotation = pageTransform.rotation()\n\t\t\t}\n\t\t}\n\n\t\treturn rotation\n\t}\n\n\t/**\n\t * The rotation of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotation(): number {\n\t\treturn this.getShapesSharedRotation(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesRotatedPageBounds(shapeIds: TLShapeId[]): Box | undefined {\n\t\tif (shapeIds.length === 0) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tconst selectionRotation = this.getShapesSharedRotation(shapeIds)\n\t\tif (selectionRotation === 0) {\n\t\t\treturn this.getShapesPageBounds(shapeIds) ?? undefined\n\t\t}\n\n\t\tif (shapeIds.length === 1) {\n\t\t\tconst bounds = this.getShapeGeometry(shapeIds[0]).bounds.clone()\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[0])!\n\t\t\tbounds.point = pageTransform.applyToPoint(bounds.point)\n\t\t\treturn bounds\n\t\t}\n\n\t\t// need to 'un-rotate' all the outlines of the existing nodes so we can fit them inside a box\n\t\tconst boxFromRotatedVertices = Box.FromPoints(\n\t\t\tshapeIds\n\t\t\t\t.flatMap((id) => {\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(id)\n\t\t\t\t\tif (!pageTransform) return []\n\t\t\t\t\treturn pageTransform.applyToPoints(this.getShapeGeometry(id).bounds.corners)\n\t\t\t\t})\n\t\t\t\t.map((p) => p.rot(-selectionRotation))\n\t\t)\n\t\t// now position box so that it's top-left corner is in the right place\n\t\tboxFromRotatedVertices.point = boxFromRotatedVertices.point.rot(selectionRotation)\n\t\treturn boxFromRotatedVertices\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedPageBounds(): Box | undefined {\n\t\treturn this.getShapesRotatedPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedScreenBounds(): Box | undefined {\n\t\tconst bounds = this.getSelectionRotatedPageBounds()\n\t\tif (!bounds) return undefined\n\t\tconst { x, y } = this.pageToScreen(bounds.point)\n\t\tconst zoom = this.getZoomLevel()\n\t\treturn new Box(x, y, bounds.width * zoom, bounds.height * zoom)\n\t}\n\n\t// Focus Group\n\n\t/**\n\t * The current focused group id.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroupId(): TLShapeId | TLPageId {\n\t\treturn this.getCurrentPageState().focusedGroupId ?? this.getCurrentPageId()\n\t}\n\n\t/**\n\t * The current focused group.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroup(): TLShape | undefined {\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\t\treturn focusedGroupId ? this.getShape(focusedGroupId) : undefined\n\t}\n\n\t/**\n\t * Set the current focused group shape.\n\t *\n\t * @param shape - The group shape id (or group shape's id) to set as the focused group shape.\n\t *\n\t * @public\n\t */\n\tsetFocusedGroup(shape: TLShapeId | TLGroupShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : (shape?.id ?? null)\n\n\t\tif (id !== null) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) {\n\t\t\t\tthrow Error(`Editor.setFocusedGroup: Shape with id ${id} does not exist`)\n\t\t\t}\n\n\t\t\tif (!this.isShapeOfType<TLGroupShape>(shape, 'group')) {\n\t\t\t\tthrow Error(\n\t\t\t\t\t`Editor.setFocusedGroup: Cannot set focused group to shape of type ${shape.type}`\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tif (id === this.getFocusedGroupId()) return this\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.update(this.getCurrentPageState().id, (s) => ({ ...s, focusedGroupId: id }))\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Exit the current focused group, moving up to the next parent group if there is one.\n\t *\n\t * @public\n\t */\n\tpopFocusedGroupId(): this {\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\tif (focusedGroup) {\n\t\t\t// If we have a focused layer, look for an ancestor of the focused shape that is a group\n\t\t\tconst match = this.findShapeAncestor(focusedGroup, (shape) =>\n\t\t\t\tthis.isShapeOfType<TLGroupShape>(shape, 'group')\n\t\t\t)\n\t\t\t// If we have an ancestor that can become a focused layer, set it as the focused layer\n\t\t\tthis.setFocusedGroup(match?.id ?? null)\n\t\t\tthis.select(focusedGroup.id)\n\t\t} else {\n\t\t\t// If there's no parent focused group, then clear the focus layer and clear selection\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The current editing shape's id.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().editingShapeId\n\t}\n\n\t/**\n\t * The current editing shape.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShape(): TLShape | undefined {\n\t\tconst editingShapeId = this.getEditingShapeId()\n\t\treturn editingShapeId ? this.getShape(editingShapeId) : undefined\n\t}\n\n\t/**\n\t * Set the current editing shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setEditingShape(myShape)\n\t * editor.setEditingShape(myShape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to set as editing.\n\t *\n\t * @public\n\t */\n\tsetEditingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : (shape?.id ?? null)\n\t\tthis.setRichTextEditor(null)\n\t\tconst prevEditingShapeId = this.getEditingShapeId()\n\t\tif (id !== prevEditingShapeId) {\n\t\t\tif (id) {\n\t\t\t\tconst shape = this.getShape(id)\n\t\t\t\tif (shape && this.getShapeUtil(shape).canEdit(shape)) {\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: id })\n\t\t\t\t\t\t\tif (prevEditingShapeId) {\n\t\t\t\t\t\t\t\tconst prevEditingShape = this.getShape(prevEditingShapeId)\n\t\t\t\t\t\t\t\tif (prevEditingShape) {\n\t\t\t\t\t\t\t\t\tthis.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.getShapeUtil(shape).onEditStart?.(shape)\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t\treturn this\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Either we just set the editing id to null, or the shape was missing or not editable\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: null })\n\t\t\t\t\tthis._currentRichTextEditor.set(null)\n\t\t\t\t\tif (prevEditingShapeId) {\n\t\t\t\t\t\tconst prevEditingShape = this.getShape(prevEditingShapeId)\n\t\t\t\t\t\tif (prevEditingShape) {\n\t\t\t\t\t\t\tthis.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\t// Rich text editor\n\n\tprivate _currentRichTextEditor = atom('rich text editor', null as TiptapEditor | null)\n\n\t/**\n\t * The current editing shape's text editor.\n\t *\n\t * @public\n\t */\n\t@computed getRichTextEditor(): TiptapEditor | null {\n\t\treturn this._currentRichTextEditor.get()\n\t}\n\n\t/**\n\t * Set the current editing shape's rich text editor.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setRichTextEditor(richTextEditorView)\n\t * ```\n\t *\n\t * @param textEditor - The text editor to set as the current editing shape's text editor.\n\t *\n\t * @public\n\t */\n\tsetRichTextEditor(textEditor: TiptapEditor | null) {\n\t\tthis._currentRichTextEditor.set(textEditor)\n\t\treturn this\n\t}\n\n\t// Hovered\n\n\t/**\n\t * The current hovered shape id.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getHoveredShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().hoveredShapeId\n\t}\n\n\t/**\n\t * The current hovered shape.\n\t *\n\t * @public\n\t */\n\t@computed getHoveredShape(): TLShape | undefined {\n\t\tconst hoveredShapeId = this.getHoveredShapeId()\n\t\treturn hoveredShapeId ? this.getShape(hoveredShapeId) : undefined\n\t}\n\t/**\n\t * Set the editor's current hovered shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHoveredShape(myShape)\n\t * editor.setHoveredShape(myShape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to set as hovered.\n\t *\n\t * @public\n\t */\n\tsetHoveredShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : (shape?.id ?? null)\n\t\tif (id === this.getHoveredShapeId()) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.updateCurrentPageState({ hoveredShapeId: id })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Hinting\n\n\t/**\n\t * The editor's current hinting shape ids.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShapeIds() {\n\t\treturn this.getCurrentPageState().hintingShapeIds\n\t}\n\n\t/**\n\t * The editor's current hinting shapes.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShape() {\n\t\tconst hintingShapeIds = this.getHintingShapeIds()\n\t\treturn compact(hintingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current hinting shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHintingShapes([myShape])\n\t * editor.setHintingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetHintingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\t// always ephemeral\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis._updateCurrentPageState({ hintingShapeIds: dedupe(ids) })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Erasing\n\n\t/**\n\t * The editor's current erasing ids.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapeIds() {\n\t\treturn this.getCurrentPageState().erasingShapeIds\n\t}\n\n\t/**\n\t * The editor's current erasing shapes.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapes() {\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\treturn compact(erasingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current erasing shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setErasingShapes([myShape])\n\t * editor.setErasingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetErasingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tids.sort() // sort the incoming ids\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tif (ids.length === erasingShapeIds.length) {\n\t\t\t\t\t// if the new ids are the same length as the current ids, they might be the same.\n\t\t\t\t\t// presuming the current ids are also sorted, check each item to see if it's the same;\n\t\t\t\t\t// if we find any unequal, then we know the new ids are different.\n\t\t\t\t\tfor (let i = 0; i < ids.length; i++) {\n\t\t\t\t\t\tif (ids[i] !== erasingShapeIds[i]) {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// if the ids are a different length, then we know they're different.\n\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t// Cropping\n\n\t/**\n\t * The current cropping shape's id.\n\t *\n\t * @public\n\t */\n\tgetCroppingShapeId() {\n\t\treturn this.getCurrentPageState().croppingShapeId\n\t}\n\n\t/**\n\t * Set the current cropping shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCroppingShape(myShape)\n\t * editor.setCroppingShape(myShape.id)\n\t * ```\n\t *\n\t *\n\t * @param shape - The shape (or shape id) to set as cropping.\n\t *\n\t * @public\n\t */\n\tsetCroppingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : (shape?.id ?? null)\n\t\tif (id !== this.getCroppingShapeId()) {\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tif (!id) {\n\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: null })\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst shape = this.getShape(id)!\n\t\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\t\tif (shape && util.canCrop(shape)) {\n\t\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: id })\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\tprivate _textOptions: Atom<TLTextOptions | null>\n\n\t/**\n\t * Get the current text options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getTextOptions()\n\t * ```\n\t *\n\t * @public */\n\tgetTextOptions() {\n\t\treturn assertExists(this._textOptions.get(), 'Cannot use text without setting textOptions')\n\t}\n\n\t/* --------------------- Camera --------------------- */\n\n\t/** @internal */\n\t@computed\n\tprivate _unsafe_getCameraId() {\n\t\treturn CameraRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * The current camera.\n\t *\n\t * @public\n\t */\n\t@computed getCamera(): TLCamera {\n\t\tconst baseCamera = this.store.get(this._unsafe_getCameraId())!\n\t\tif (this._isLockedOnFollowingUser.get()) {\n\t\t\tconst followingCamera = this.getCameraForFollowing()\n\t\t\tif (followingCamera) {\n\t\t\t\treturn { ...baseCamera, ...followingCamera }\n\t\t\t}\n\t\t}\n\t\treturn baseCamera\n\t}\n\n\tprivate _getFollowingPresence(targetUserId: string | null) {\n\t\tconst visited = [this.user.getId()]\n\t\tconst collaborators = this.getCollaborators()\n\t\tlet leaderPresence = null as null | TLInstancePresence\n\t\twhile (targetUserId && !visited.includes(targetUserId)) {\n\t\t\tleaderPresence = collaborators.find((c) => c.userId === targetUserId) ?? null\n\t\t\ttargetUserId = leaderPresence?.followingUserId ?? null\n\t\t\tif (leaderPresence) {\n\t\t\t\tvisited.push(leaderPresence.userId)\n\t\t\t}\n\t\t}\n\t\treturn leaderPresence\n\t}\n\n\t@computed\n\tprivate getViewportPageBoundsForFollowing(): null | Box {\n\t\tconst leaderPresence = this._getFollowingPresence(this.getInstanceState().followingUserId)\n\n\t\tif (!leaderPresence?.camera || !leaderPresence?.screenBounds) return null\n\n\t\t// Fit their viewport inside of our screen bounds\n\t\t// 1. calculate their viewport in page space\n\t\tconst { w: lw, h: lh } = leaderPresence.screenBounds\n\t\tconst { x: lx, y: ly, z: lz } = leaderPresence.camera\n\t\tconst theirViewport = new Box(-lx, -ly, lw / lz, lh / lz)\n\n\t\t// resize our screenBounds to contain their viewport\n\t\tconst ourViewport = this.getViewportScreenBounds().clone()\n\t\tconst ourAspectRatio = ourViewport.width / ourViewport.height\n\n\t\tourViewport.width = theirViewport.width\n\t\tourViewport.height = ourViewport.width / ourAspectRatio\n\t\tif (ourViewport.height < theirViewport.height) {\n\t\t\tourViewport.height = theirViewport.height\n\t\t\tourViewport.width = ourViewport.height * ourAspectRatio\n\t\t}\n\n\t\tourViewport.center = theirViewport.center\n\t\treturn ourViewport\n\t}\n\n\t@computed\n\tprivate getCameraForFollowing(): null | { x: number; y: number; z: number } {\n\t\tconst viewport = this.getViewportPageBoundsForFollowing()\n\t\tif (!viewport) return null\n\n\t\treturn {\n\t\t\tx: -viewport.x,\n\t\t\ty: -viewport.y,\n\t\t\tz: this.getViewportScreenBounds().w / viewport.width,\n\t\t}\n\t}\n\n\t/**\n\t * The current camera zoom level.\n\t *\n\t * @public\n\t */\n\t@computed getZoomLevel() {\n\t\treturn this.getCamera().z\n\t}\n\n\t/**\n\t * Get the camera's initial or reset zoom level.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetInitialZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.initialZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.initialZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.initialZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the camera's base level for calculating actual zoom levels based on the zoom steps.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getBaseZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetBaseZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.baseZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.baseZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.baseZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _cameraOptions = atom('camera options', DEFAULT_CAMERA_OPTIONS)\n\n\t/**\n\t * Get the current camera options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraOptions()\n\t * ```\n\t *\n\t * @public */\n\tgetCameraOptions() {\n\t\treturn this._cameraOptions.get()\n\t}\n\n\t/**\n\t * Set the camera options. Changing the options won't immediately change the camera itself, so you may want to call `setCamera` after changing the options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCameraOptions(myCameraOptions)\n\t * editor.setCamera(editor.getCamera())\n\t * ```\n\t *\n\t * @param opts - The camera options to set.\n\t *\n\t * @public */\n\tsetCameraOptions(opts: Partial<TLCameraOptions>) {\n\t\tconst next = structuredClone({\n\t\t\t...this._cameraOptions.__unsafe__getWithoutCapture(),\n\t\t\t...opts,\n\t\t})\n\t\tif (next.zoomSteps?.length < 1) next.zoomSteps = [1]\n\t\tthis._cameraOptions.set(next)\n\t\tthis.setCamera(this.getCamera())\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate getConstrainedCamera(\n\t\tpoint: VecLike,\n\t\topts?: TLCameraMoveOptions\n\t): {\n\t\tx: number\n\t\ty: number\n\t\tz: number\n\t} {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tlet { x, y, z = currentCamera.z } = point\n\n\t\t// If force is true, then we'll set the camera to the point regardless of\n\t\t// the camera options, so that we can handle gestures that permit elasticity\n\t\t// or decay, or animations that occur while the camera is locked.\n\t\tif (!opts?.force) {\n\t\t\t// Apply any adjustments based on the camera options\n\n\t\t\tconst cameraOptions = this.getCameraOptions()\n\n\t\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\t\tconst vsb = this.getViewportScreenBounds()\n\n\t\t\t// If bounds are provided, then we'll keep those bounds on screen\n\t\t\tif (cameraOptions.constraints) {\n\t\t\t\tconst { constraints } = cameraOptions\n\n\t\t\t\t// Clamp padding to half the viewport size on either dimension\n\t\t\t\tconst py = Math.min(constraints.padding.y, vsb.w / 2)\n\t\t\t\tconst px = Math.min(constraints.padding.x, vsb.h / 2)\n\n\t\t\t\t// Expand the bounds by the padding\n\t\t\t\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\n\t\t\t\t// For each axis, the \"natural zoom\" is the zoom at\n\t\t\t\t// which the expanded bounds (with padding) would fit\n\t\t\t\t// the current viewport screen bounds. Paddings are\n\t\t\t\t// equal to screen pixels at 100%\n\t\t\t\t// The min and max zooms are factors of the smaller natural zoom axis\n\n\t\t\t\tconst zx = (vsb.w - px * 2) / bounds.w\n\t\t\t\tconst zy = (vsb.h - py * 2) / bounds.h\n\n\t\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\t\tconst maxZ = zoomMax * baseZoom\n\t\t\t\tconst minZ = zoomMin * baseZoom\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\tz = this.getInitialZoom()\n\t\t\t\t}\n\n\t\t\t\tif (z < minZ || z > maxZ) {\n\t\t\t\t\t// We're trying to zoom out past the minimum zoom level,\n\t\t\t\t\t// or in past the maximum zoom level, so stop the camera\n\t\t\t\t\t// but keep the current center\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tconst cxA = -cx + vsb.w / cz / 2\n\t\t\t\t\tconst cyA = -cy + vsb.h / cz / 2\n\t\t\t\t\tz = clamp(z, minZ, maxZ)\n\t\t\t\t\tconst cxB = -cx + vsb.w / z / 2\n\t\t\t\t\tconst cyB = -cy + vsb.h / z / 2\n\t\t\t\t\tx = cx + cxB - cxA\n\t\t\t\t\ty = cy + cyB - cyA\n\t\t\t\t}\n\n\t\t\t\t// Calculate available space\n\t\t\t\tconst minX = px / z - bounds.x\n\t\t\t\tconst minY = py / z - bounds.y\n\t\t\t\tconst freeW = (vsb.w - px * 2) / z - bounds.w\n\t\t\t\tconst freeH = (vsb.h - py * 2) / z - bounds.h\n\t\t\t\tconst originX = minX + freeW * constraints.origin.x\n\t\t\t\tconst originY = minY + freeH * constraints.origin.y\n\n\t\t\t\tconst behaviorX =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.x\n\t\t\t\tconst behaviorY =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.y\n\n\t\t\t\t// x axis\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\t// Reset the camera according to the origin\n\t\t\t\t\tx = originX\n\t\t\t\t\ty = originY\n\t\t\t\t} else {\n\t\t\t\t\t// Apply constraints to the camera\n\t\t\t\t\tswitch (behaviorX) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\t// Center according to the origin\n\t\t\t\t\t\t\tx = originX\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\t// When below fit zoom, center the camera\n\t\t\t\t\t\t\tif (z < zx) x = originX\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\t// When below fit zoom, constrain the camera so that the bounds stay completely within the viewport\n\t\t\t\t\t\t\tif (z < zx) x = clamp(x, minX, (vsb.w - px) / z - bounds.w)\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\t// Constrain the camera so that the bounds never leaves the viewport\n\t\t\t\t\t\t\tx = clamp(x, px / z - bounds.w, (vsb.w - px) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorX)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// y axis\n\n\t\t\t\t\tswitch (behaviorY) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\ty = originY\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\tif (z < zy) y = originY\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\tif (z < zy) y = clamp(y, minY, (vsb.h - py) / z - bounds.h)\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\ty = clamp(y, py / z - bounds.h, (vsb.h - py) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorY)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// constrain the zoom, preserving the center\n\t\t\t\tif (z > zoomMax || z < zoomMin) {\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tz = clamp(z, zoomMin, zoomMax)\n\t\t\t\t\tx = cx + (-cx + vsb.w / z / 2) - (-cx + vsb.w / cz / 2)\n\t\t\t\t\ty = cy + (-cy + vsb.h / z / 2) - (-cy + vsb.h / cz / 2)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { x, y, z }\n\t}\n\n\t/** @internal */\n\tprivate _setCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tconst { x, y, z } = this.getConstrainedCamera(point, opts)\n\n\t\tif (currentCamera.x === x && currentCamera.y === y && currentCamera.z === z) {\n\t\t\treturn this\n\t\t}\n\n\t\ttransact(() => {\n\t\t\tconst camera = { ...currentCamera, x, y, z }\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis.store.put([camera]) // include id and meta here\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\n\t\t\t// Dispatch a new pointer move because the pointer's page will have changed\n\t\t\t// (its screen position will compute to a new page position given the new camera position)\n\t\t\tconst { currentScreenPoint, currentPagePoint } = this.inputs\n\n\t\t\t// compare the next page point (derived from the current camera) to the current page point\n\t\t\tif (\n\t\t\t\tcurrentScreenPoint.x / z - x !== currentPagePoint.x ||\n\t\t\t\tcurrentScreenPoint.y / z - y !== currentPagePoint.y\n\t\t\t) {\n\t\t\t\t// If it's changed, dispatch a pointer event\n\t\t\t\tthis.updatePointer({\n\t\t\t\t\timmediate: opts?.immediate,\n\t\t\t\t\tpointerId: INTERNAL_POINTER_IDS.CAMERA_MOVE,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tthis._tickCameraState()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current camera.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCamera({ x: 0, y: 0})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5}, { animation: { duration: 1000, easing: (t) => t * t } })\n\t * ```\n\t *\n\t * @param point - The new camera position.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tsetCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\t// Stop any camera animations\n\t\tthis.stopCameraAnimation()\n\n\t\t// Stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tconst _point = Vec.Cast(point)\n\n\t\tif (!Number.isFinite(_point.x)) _point.x = 0\n\t\tif (!Number.isFinite(_point.y)) _point.y = 0\n\t\tif (_point.z === undefined || !Number.isFinite(_point.z)) point.z = this.getZoomLevel()\n\n\t\tconst camera = this.getConstrainedCamera(_point, opts)\n\n\t\tif (opts?.animation) {\n\t\t\tconst { width, height } = this.getViewportScreenBounds()\n\t\t\tthis._animateToViewport(\n\t\t\t\tnew Box(-camera.x, -camera.y, width / camera.z, height / camera.z),\n\t\t\t\topts\n\t\t\t)\n\t\t} else {\n\t\t\tthis._setCamera(camera, {\n\t\t\t\t...opts,\n\t\t\t\t// we already did the constraining, so we don't need to do it again\n\t\t\t\tforce: true,\n\t\t\t})\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Center the camera on a point (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.centerOnPoint({ x: 100, y: 100 })\n\t * editor.centerOnPoint({ x: 100, y: 100 }, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The point in the current page space to center on.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tcenterOnPoint(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { width: pw, height: ph } = this.getViewportPageBounds()\n\t\tthis.setCamera(new Vec(-(point.x - pw / 2), -(point.y - ph / 2), this.getCamera().z), opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current page's content in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToFit()\n\t * editor.zoomToFit({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToFit(opts?: TLCameraMoveOptions): this {\n\t\tconst ids = [...this.getCurrentPageShapeIds()]\n\t\tif (ids.length <= 0) return this\n\t\tconst pageBounds = Box.Common(compact(ids.map((id) => this.getShapePageBounds(id))))\n\t\tthis.zoomToBounds(pageBounds, opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the zoom back to 100%.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.resetZoom()\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tresetZoom(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked, constraints: constraints } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst currentCamera = this.getCamera()\n\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\tconst { x, y } = point\n\n\t\tlet z = 1\n\n\t\tif (constraints) {\n\t\t\t// For non-infinite fit, we'll set the camera to the natural zoom level...\n\t\t\t// unless it's already there, in which case we'll set zoom to 100%\n\t\t\tconst initialZoom = this.getInitialZoom()\n\t\t\tif (cz !== initialZoom) {\n\t\t\t\tz = initialZoom\n\t\t\t}\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(cx + (x / z - x) - (x / cz - x), cy + (y / z - y) - (y / cz - y), z),\n\t\t\topts\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera in.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomIn()\n\t * editor.zoomIn(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.zoomIn(editor.inputs.currentScreenPoint, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom in on. Defaults to the screen center\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomIn(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tlet zoom = last(zoomSteps)! * baseZoom\n\t\t\tfor (let i = 1; i < zoomSteps.length; i++) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz <= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z2\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera out.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomOut()\n\t * editor.zoomOut(editor.getViewportScreenCenter(), { animation: { duration: 120 } })\n\t * editor.zoomOut(editor.inputs.currentScreenPoint, { animation: { duration: 120 } })\n\t * ```\n\t *\n\t * @param point - The point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomOut(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\t// start at the max\n\t\t\tlet zoom = zoomSteps[0] * baseZoom\n\t\t\tfor (let i = zoomSteps.length - 1; i > 0; i--) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz >= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z1\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current selection in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToSelection()\n\t * editor.zoomToSelection({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToSelection(opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\tif (selectionPageBounds) {\n\t\t\tthis.zoomToBounds(selectionPageBounds, {\n\t\t\t\ttargetZoom: Math.max(1, this.getZoomLevel()),\n\t\t\t\t...opts,\n\t\t\t})\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to the current selection if offscreen.\n\t *\n\t * @public\n\t */\n\tzoomToSelectionIfOffscreen(\n\t\tpadding = 16,\n\t\topts?: { targetZoom?: number; inset?: number } & TLCameraMoveOptions\n\t) {\n\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\tif (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {\n\t\t\tconst eb = selectionPageBounds\n\t\t\t\t.clone()\n\t\t\t\t// Expand the bounds by the padding\n\t\t\t\t.expandBy(padding / this.getZoomLevel())\n\t\t\t\t// then expand the bounds to include the viewport bounds\n\t\t\t\t.expand(viewportPageBounds)\n\n\t\t\t// then use the difference between the centers to calculate the offset\n\t\t\tconst nextBounds = viewportPageBounds.clone().translate({\n\t\t\t\tx: (eb.center.x - viewportPageBounds.center.x) * 2,\n\t\t\t\ty: (eb.center.y - viewportPageBounds.center.y) * 2,\n\t\t\t})\n\t\t\tthis.zoomToBounds(nextBounds, opts)\n\t\t}\n\t}\n\n\t/**\n\t * Zoom the camera to fit a bounding box (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToBounds(myBounds)\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 } })\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 }, inset: 0, targetZoom: 1 })\n\t * ```\n\t *\n\t * @param bounds - The bounding box.\n\t * @param opts - The camera move options, target zoom, or custom inset amount.\n\t *\n\t * @public\n\t */\n\tzoomToBounds(\n\t\tbounds: BoxLike,\n\t\topts?: { targetZoom?: number; inset?: number } & TLCameraMoveOptions\n\t): this {\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (cameraOptions.isLocked && !opts?.force) return this\n\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\n\t\tconst inset = opts?.inset ?? Math.min(ZOOM_TO_FIT_PADDING, viewportScreenBounds.width * 0.28)\n\n\t\tconst baseZoom = this.getBaseZoom()\n\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\tlet zoom = clamp(\n\t\t\tMath.min(\n\t\t\t\t(viewportScreenBounds.width - inset) / bounds.w,\n\t\t\t\t(viewportScreenBounds.height - inset) / bounds.h\n\t\t\t),\n\t\t\tzoomMin * baseZoom,\n\t\t\tzoomMax * baseZoom\n\t\t)\n\n\t\tif (opts?.targetZoom !== undefined) {\n\t\t\tzoom = Math.min(opts.targetZoom, zoom)\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(\n\t\t\t\t-bounds.x + (viewportScreenBounds.width - bounds.w * zoom) / 2 / zoom,\n\t\t\t\t-bounds.y + (viewportScreenBounds.height - bounds.h * zoom) / 2 / zoom,\n\t\t\t\tzoom\n\t\t\t),\n\t\t\topts\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop the current camera animation, if any.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopCameraAnimation()\n\t * ```\n\t *\n\t * @public\n\t */\n\tstopCameraAnimation(): this {\n\t\tthis.emit('stop-camera-animation')\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _viewportAnimation = null as null | {\n\t\telapsed: number\n\t\tduration: number\n\t\teasing(t: number): number\n\t\tstart: Box\n\t\tend: Box\n\t}\n\n\t/** @internal */\n\tprivate _animateViewport(ms: number): void {\n\t\tif (!this._viewportAnimation) return\n\n\t\tthis._viewportAnimation.elapsed += ms\n\n\t\tconst { elapsed, easing, duration, start, end } = this._viewportAnimation\n\n\t\tif (elapsed > duration) {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t\tthis._setCamera(new Vec(-end.x, -end.y, this.getViewportScreenBounds().width / end.width))\n\t\t\treturn\n\t\t}\n\n\t\tconst remaining = duration - elapsed\n\t\tconst t = easing(1 - remaining / duration)\n\n\t\tconst left = start.minX + (end.minX - start.minX) * t\n\t\tconst top = start.minY + (end.minY - start.minY) * t\n\t\tconst right = start.maxX + (end.maxX - start.maxX) * t\n\n\t\tthis._setCamera(new Vec(-left, -top, this.getViewportScreenBounds().width / (right - left)), {\n\t\t\tforce: true,\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _animateToViewport(\n\t\ttargetViewportPage: Box,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t) {\n\t\tconst { animation, ...rest } = opts\n\t\tif (!animation) return\n\t\tconst { duration = 0, easing = EASINGS.easeInOutCubic } = animation\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\n\t\t// If we have an existing animation, then stop it\n\t\tthis.stopCameraAnimation()\n\n\t\t// also stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tif (duration === 0 || animationSpeed === 0) {\n\t\t\t// If we have no animation, then skip the animation and just set the camera\n\t\t\treturn this._setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\t-targetViewportPage.x,\n\t\t\t\t\t-targetViewportPage.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / targetViewportPage.width\n\t\t\t\t),\n\t\t\t\t{ ...rest }\n\t\t\t)\n\t\t}\n\n\t\t// Set our viewport animation\n\t\tthis._viewportAnimation = {\n\t\t\telapsed: 0,\n\t\t\tduration: duration / animationSpeed,\n\t\t\teasing,\n\t\t\tstart: viewportPageBounds.clone(),\n\t\t\tend: targetViewportPage.clone(),\n\t\t}\n\n\t\t// If we ever get a \"stop-camera-animation\" event, we stop\n\t\tthis.once('stop-camera-animation', () => {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t})\n\n\t\t// On each tick, animate the viewport\n\t\tthis.on('tick', this._animateViewport)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Slide the camera in a certain direction.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.slideCamera({ speed: 1, direction: { x: 1, y: 0 }, friction: 0.1 })\n\t * ```\n\t *\n\t * @param opts - Options for the slide\n\t * @public\n\t */\n\tslideCamera(\n\t\topts = {} as {\n\t\t\tspeed: number\n\t\t\tdirection: VecLike\n\t\t\tfriction?: number\n\t\t\tspeedThreshold?: number\n\t\t\tforce?: boolean\n\t\t}\n\t): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tif (animationSpeed === 0) return this\n\n\t\tthis.stopCameraAnimation()\n\n\t\tconst {\n\t\t\tspeed,\n\t\t\tfriction = this.options.cameraSlideFriction,\n\t\t\tdirection,\n\t\t\tspeedThreshold = 0.01,\n\t\t} = opts\n\t\tlet currentSpeed = Math.min(speed, 1)\n\n\t\tconst cancel = () => {\n\t\t\tthis.off('tick', moveCamera)\n\t\t\tthis.off('stop-camera-animation', cancel)\n\t\t}\n\n\t\tthis.once('stop-camera-animation', cancel)\n\n\t\tconst moveCamera = (elapsed: number) => {\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\tconst movementVec = Vec.Mul(direction, (currentSpeed * elapsed) / cz)\n\n\t\t\t// Apply friction\n\t\t\tcurrentSpeed *= 1 - friction\n\t\t\tif (currentSpeed < speedThreshold) {\n\t\t\t\tcancel()\n\t\t\t} else {\n\t\t\t\tthis._setCamera(new Vec(cx + movementVec.x, cy + movementVec.y, cz))\n\t\t\t}\n\t\t}\n\n\t\tthis.on('tick', moveCamera)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Animate the camera to a user's cursor position. This also briefly show the user's cursor if it's not currently visible.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToUser(myUserId)\n\t * editor.zoomToUser(myUserId, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param userId - The id of the user to animate to.\n\t * @param opts - The camera move options.\n\t * @public\n\t */\n\tzoomToUser(userId: string, opts: TLCameraMoveOptions = { animation: { duration: 500 } }): this {\n\t\tconst presence = this.getCollaborators().find((c) => c.userId === userId)\n\n\t\tif (!presence) return this\n\n\t\tconst cursor = presence.cursor\n\t\tif (!cursor) return this\n\n\t\tthis.run(() => {\n\t\t\t// If we're following someone, stop following them\n\t\t\tif (this.getInstanceState().followingUserId !== null) {\n\t\t\t\tthis.stopFollowingUser()\n\t\t\t}\n\n\t\t\t// If we're not on the same page, move to the page they're on\n\t\t\tconst isOnSamePage = presence.currentPageId === this.getCurrentPageId()\n\t\t\tif (!isOnSamePage) {\n\t\t\t\tthis.setCurrentPage(presence.currentPageId)\n\t\t\t}\n\n\t\t\t// Only animate the camera if the user is on the same page as us\n\t\t\tif (opts && opts.animation && !isOnSamePage) {\n\t\t\t\topts.animation = undefined\n\t\t\t}\n\n\t\t\tthis.centerOnPoint(cursor, opts)\n\n\t\t\t// Highlight the user's cursor\n\t\t\tconst { highlightedUserIds } = this.getInstanceState()\n\t\t\tthis.updateInstanceState({ highlightedUserIds: [...highlightedUserIds, userId] })\n\n\t\t\t// Unhighlight the user's cursor after a few seconds\n\t\t\tthis.timers.setTimeout(() => {\n\t\t\t\tconst highlightedUserIds = [...this.getInstanceState().highlightedUserIds]\n\t\t\t\tconst index = highlightedUserIds.indexOf(userId)\n\t\t\t\tif (index < 0) return\n\t\t\t\thighlightedUserIds.splice(index, 1)\n\t\t\t\tthis.updateInstanceState({ highlightedUserIds })\n\t\t\t}, this.options.collaboratorIdleTimeoutMs)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t// Viewport\n\n\t/** @internal */\n\tprivate _willSetInitialBounds = true\n\n\t/**\n\t * Update the viewport. The viewport will measure the size and screen position of its container\n\t * element. This should be done whenever the container's position on the screen changes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024))\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024), true)\n\t * ```\n\t *\n\t * @param screenBounds - The new screen bounds of the viewport.\n\t * @param center - Whether to preserve the viewport page center as the viewport changes.\n\t *\n\t * @public\n\t */\n\tupdateViewportScreenBounds(screenBounds: Box | HTMLElement, center = false): this {\n\t\tif (!(screenBounds instanceof Box)) {\n\t\t\tconst rect = screenBounds.getBoundingClientRect()\n\t\t\tscreenBounds = new Box(\n\t\t\t\trect.left || rect.x,\n\t\t\t\trect.top || rect.y,\n\t\t\t\tMath.max(rect.width, 1),\n\t\t\t\tMath.max(rect.height, 1)\n\t\t\t)\n\t\t} else {\n\t\t\tscreenBounds.width = Math.max(screenBounds.width, 1)\n\t\t\tscreenBounds.height = Math.max(screenBounds.height, 1)\n\t\t}\n\n\t\tconst insets = [\n\t\t\t// top\n\t\t\tscreenBounds.minY !== 0,\n\t\t\t// right\n\t\t\t!approximately(document.body.scrollWidth, screenBounds.maxX, 1),\n\t\t\t// bottom\n\t\t\t!approximately(document.body.scrollHeight, screenBounds.maxY, 1),\n\t\t\t// left\n\t\t\tscreenBounds.minX !== 0,\n\t\t]\n\n\t\tconst { _willSetInitialBounds } = this\n\n\t\tthis._willSetInitialBounds = false\n\n\t\tconst { screenBounds: prevScreenBounds, insets: prevInsets } = this.getInstanceState()\n\t\tif (screenBounds.equals(prevScreenBounds) && insets.every((v, i) => v === prevInsets[i])) {\n\t\t\t// nothing to do\n\t\t\treturn this\n\t\t}\n\n\t\tif (_willSetInitialBounds) {\n\t\t\t// If we have just received the initial bounds, don't center the camera.\n\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\tthis.setCamera(this.getCamera())\n\t\t} else {\n\t\t\tif (center && !this.getInstanceState().followingUserId) {\n\t\t\t\t// Get the page center before the change, make the change, and restore it\n\t\t\t\tconst before = this.getViewportPageBounds().center\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis.centerOnPoint(before)\n\t\t\t} else {\n\t\t\t\t// Otherwise,\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis._setCamera(Vec.From({ ...this.getCamera() }))\n\t\t\t}\n\t\t}\n\n\t\tthis._tickCameraState()\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The bounds of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenBounds() {\n\t\tconst { x, y, w, h } = this.getInstanceState().screenBounds\n\t\treturn new Box(x, y, w, h)\n\t}\n\n\t/**\n\t * The center of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenCenter() {\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\t\treturn new Vec(viewportScreenBounds.w / 2, viewportScreenBounds.h / 2)\n\t}\n\n\t/**\n\t * The current viewport in the current page space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportPageBounds() {\n\t\tconst { w, h } = this.getViewportScreenBounds()\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\treturn new Box(-cx, -cy, w / cz, h / cz)\n\t}\n\n\t/**\n\t * Convert a point in screen space to a point in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.screenToPage({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in screen space.\n\t *\n\t * @public\n\t */\n\tscreenToPage(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x - screenBounds.x) / cz - cx,\n\t\t\t(point.y - screenBounds.y) / cz - cy,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current screen space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToScreen({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToScreen(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x + cx) * cz + screenBounds.x,\n\t\t\t(point.y + cy) * cz + screenBounds.y,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current viewport space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToViewport({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToViewport(point: VecLike) {\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec((point.x + cx) * cz, (point.y + cy) * cz, point.z ?? 0.5)\n\t}\n\t// Collaborators\n\n\t@computed\n\tprivate _getCollaboratorsQuery() {\n\t\treturn this.store.query.records('instance_presence', () => ({\n\t\t\tuserId: { neq: this.user.getId() },\n\t\t}))\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaborators() {\n\t\tconst allPresenceRecords = this._getCollaboratorsQuery().get()\n\t\tif (!allPresenceRecords.length) return EMPTY_ARRAY\n\t\tconst userIds = [...new Set(allPresenceRecords.map((c) => c.userId))].sort()\n\t\treturn userIds.map((id) => {\n\t\t\tconst latestPresence = maxBy(\n\t\t\t\tallPresenceRecords.filter((c) => c.userId === id),\n\t\t\t\t(p) => p.lastActivityTimestamp ?? 0\n\t\t\t)\n\t\t\treturn latestPresence!\n\t\t})\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators on the current page.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaboratorsOnCurrentPage() {\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\treturn this.getCollaborators().filter((c) => c.currentPageId === currentPageId)\n\t}\n\n\t// Following\n\n\t// When we are 'locked on' to a user, our camera is derived from their camera.\n\tprivate _isLockedOnFollowingUser = atom('isLockedOnFollowingUser', false)\n\n\t/**\n\t * Start viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.startFollowingUser(myUserId)\n\t * ```\n\t *\n\t * @param userId - The id of the user to follow.\n\t *\n\t * @public\n\t */\n\tstartFollowingUser(userId: string): this {\n\t\t// if we were already following someone, stop following them\n\t\tthis.stopFollowingUser()\n\n\t\tconst thisUserId = this.user.getId()\n\n\t\tif (!thisUserId) {\n\t\t\tconsole.warn('You should set the userId for the current instance before following a user')\n\t\t\t// allow to continue since it's probably fine most of the time.\n\t\t}\n\n\t\tconst leaderPresence = this._getFollowingPresence(userId)\n\n\t\tif (!leaderPresence) {\n\t\t\treturn this\n\t\t}\n\n\t\tconst latestLeaderPresence = computed('latestLeaderPresence', () => {\n\t\t\treturn this._getFollowingPresence(userId)\n\t\t})\n\n\t\ttransact(() => {\n\t\t\tthis.updateInstanceState({ followingUserId: userId }, { history: 'ignore' })\n\n\t\t\t// we listen for page changes separately from the 'moveTowardsUser' tick\n\t\t\tconst dispose = react('update current page', () => {\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tleaderPresence.currentPageId !== this.getCurrentPageId() &&\n\t\t\t\t\tthis.getPage(leaderPresence.currentPageId)\n\t\t\t\t) {\n\t\t\t\t\t// if the page changed, switch page\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t// sneaky store.put here, we can't go through setCurrentPage because it calls stopFollowingUser\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t{ ...this.getInstanceState(), currentPageId: leaderPresence.currentPageId },\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst cancel = () => {\n\t\t\t\tdispose()\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.off('frame', moveTowardsUser)\n\t\t\t\tthis.off('stop-following', cancel)\n\t\t\t}\n\n\t\t\tconst moveTowardsUser = () => {\n\t\t\t\t// Stop following if we can't find the user\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (this._isLockedOnFollowingUser.get()) return\n\n\t\t\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\n\t\t\t\tif (animationSpeed === 0) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst targetViewport = this.getViewportPageBoundsForFollowing()\n\t\t\t\tif (!targetViewport) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst currentViewport = this.getViewportPageBounds()\n\n\t\t\t\tconst diffX =\n\t\t\t\t\tMath.abs(targetViewport.minX - currentViewport.minX) +\n\t\t\t\t\tMath.abs(targetViewport.maxX - currentViewport.maxX)\n\t\t\t\tconst diffY =\n\t\t\t\t\tMath.abs(targetViewport.minY - currentViewport.minY) +\n\t\t\t\t\tMath.abs(targetViewport.maxY - currentViewport.maxY)\n\n\t\t\t\t// Stop chasing if we're close enough!\n\t\t\t\tif (\n\t\t\t\t\tdiffX < this.options.followChaseViewportSnap &&\n\t\t\t\t\tdiffY < this.options.followChaseViewportSnap\n\t\t\t\t) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Chase the user's viewport!\n\t\t\t\t// Interpolate between the current viewport and the target viewport based on animation speed.\n\t\t\t\t// This will produce an 'ease-out' effect.\n\t\t\t\tconst t = clamp(animationSpeed * 0.5, 0.1, 0.8)\n\n\t\t\t\tconst nextViewport = new Box(\n\t\t\t\t\tlerp(currentViewport.minX, targetViewport.minX, t),\n\t\t\t\t\tlerp(currentViewport.minY, targetViewport.minY, t),\n\t\t\t\t\tlerp(currentViewport.width, targetViewport.width, t),\n\t\t\t\t\tlerp(currentViewport.height, targetViewport.height, t)\n\t\t\t\t)\n\n\t\t\t\tconst nextCamera = new Vec(\n\t\t\t\t\t-nextViewport.x,\n\t\t\t\t\t-nextViewport.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / nextViewport.width\n\t\t\t\t)\n\n\t\t\t\t// Update the camera!\n\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\tthis._setCamera(nextCamera)\n\t\t\t}\n\n\t\t\tthis.once('stop-following', cancel)\n\t\t\tthis.addListener('frame', moveTowardsUser)\n\n\t\t\t// call once to start synchronously\n\t\t\tmoveTowardsUser()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopFollowingUser()\n\t * ```\n\t * @public\n\t */\n\tstopFollowingUser(): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\t// commit the current camera to the store\n\t\t\t\tthis.store.put([this.getCamera()])\n\t\t\t\t// this must happen after the camera is committed\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.updateInstanceState({ followingUserId: null })\n\t\t\t\tthis.emit('stop-following')\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tgetUnorderedRenderingShapes(\n\t\t// The rendering state. We use this method both for rendering, which\n\t\t// is based on other state, and for computing order for SVG export,\n\t\t// which should work even when things are for example off-screen.\n\t\tuseEditorState: boolean\n\t): TLRenderingShape[] {\n\t\t// Here we get the shape as well as any of its children, as well as their\n\t\t// opacities. If the shape is being erased, and none of its ancestors are\n\t\t// being erased, then we reduce the opacity of the shape and all of its\n\t\t// ancestors; but we don't apply this effect more than once among a set\n\t\t// of descendants so that it does not compound.\n\n\t\t// This is designed to keep all the shapes in a single list which\n\t\t// allows the DOM nodes to be reused even when they become children\n\t\t// of other nodes.\n\n\t\tconst renderingShapes: TLRenderingShape[] = []\n\n\t\tlet nextIndex = this.options.maxShapesPerPage * 2\n\t\tlet nextBackgroundIndex = this.options.maxShapesPerPage\n\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\n\t\tconst addShapeById = (id: TLShapeId, opacity: number, isAncestorErasing: boolean) => {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) return\n\n\t\t\tif (this.isShapeHidden(shape)) {\n\t\t\t\t// process children just in case they are overriding the hidden state\n\t\t\t\tconst isErasing = isAncestorErasing || erasingShapeIds.includes(id)\n\t\t\t\tfor (const childId of this.getSortedChildIdsForParent(id)) {\n\t\t\t\t\taddShapeById(childId, opacity, isErasing)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\topacity *= shape.opacity\n\t\t\tlet isShapeErasing = false\n\t\t\tconst util = this.getShapeUtil(shape)\n\n\t\t\tif (useEditorState) {\n\t\t\t\tisShapeErasing = !isAncestorErasing && erasingShapeIds.includes(id)\n\t\t\t\tif (isShapeErasing) {\n\t\t\t\t\topacity *= 0.32\n\t\t\t\t}\n\t\t\t}\n\n\t\t\trenderingShapes.push({\n\t\t\t\tid,\n\t\t\t\tshape,\n\t\t\t\tutil,\n\t\t\t\tindex: nextIndex,\n\t\t\t\tbackgroundIndex: nextBackgroundIndex,\n\t\t\t\topacity,\n\t\t\t})\n\n\t\t\tnextIndex += 1\n\t\t\tnextBackgroundIndex += 1\n\n\t\t\tconst childIds = this.getSortedChildIdsForParent(id)\n\t\t\tif (!childIds.length) return\n\n\t\t\tlet backgroundIndexToRestore = null\n\t\t\tif (util.providesBackgroundForChildren(shape)) {\n\t\t\t\tbackgroundIndexToRestore = nextBackgroundIndex\n\t\t\t\tnextBackgroundIndex = nextIndex\n\t\t\t\tnextIndex += this.options.maxShapesPerPage\n\t\t\t}\n\n\t\t\tfor (const childId of childIds) {\n\t\t\t\taddShapeById(childId, opacity, isAncestorErasing || isShapeErasing)\n\t\t\t}\n\n\t\t\tif (backgroundIndexToRestore !== null) {\n\t\t\t\tnextBackgroundIndex = backgroundIndexToRestore\n\t\t\t}\n\t\t}\n\n\t\t// If we're using editor state, then we're only interested in on-screen shapes.\n\t\t// If we're not using the editor state, then we're interested in ALL shapes, even those from other pages.\n\t\tconst pages = useEditorState ? [this.getCurrentPage()] : this.getPages()\n\t\tfor (const page of pages) {\n\t\t\tfor (const childId of this.getSortedChildIdsForParent(page.id)) {\n\t\t\t\taddShapeById(childId, 1, false)\n\t\t\t}\n\t\t}\n\n\t\treturn renderingShapes\n\t}\n\n\t// Camera state\n\t// Camera state does two things: first, it allows us to subscribe to whether\n\t// the camera is moving or not; and second, it allows us to update the rendering\n\t// shapes on the canvas. Changing the rendering shapes may cause shapes to\n\t// unmount / remount in the DOM, which is expensive; and computing visibility is\n\t// also expensive in large projects. For this reason, we use a second bounding\n\t// box just for rendering, and we only update after the camera stops moving.\n\tprivate _cameraState = atom('camera state', 'idle' as 'idle' | 'moving')\n\tprivate _cameraStateTimeoutRemaining = 0\n\t_decayCameraStateTimeout(elapsed: number) {\n\t\tthis._cameraStateTimeoutRemaining -= elapsed\n\t\tif (this._cameraStateTimeoutRemaining > 0) return\n\t\tthis.off('tick', this._decayCameraStateTimeout)\n\t\tthis._cameraState.set('idle')\n\t}\n\t_tickCameraState() {\n\t\t// always reset the timeout\n\t\tthis._cameraStateTimeoutRemaining = this.options.cameraMovingTimeoutMs\n\t\t// If the state is idle, then start the tick\n\t\tif (this._cameraState.__unsafe__getWithoutCapture() !== 'idle') return\n\t\tthis._cameraState.set('moving')\n\t\tthis.on('tick', this._decayCameraStateTimeout)\n\t}\n\n\t/**\n\t * Whether the camera is moving or idle.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraState()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCameraState() {\n\t\treturn this._cameraState.get()\n\t}\n\n\t/**\n\t * Get the shapes that should be displayed in the current viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getRenderingShapes()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getRenderingShapes() {\n\t\tconst renderingShapes = this.getUnorderedRenderingShapes(true)\n\n\t\t// Its IMPORTANT that the result be sorted by id AND include the index\n\t\t// that the shape should be displayed at. Steve, this is the past you\n\t\t// telling the present you not to change this.\n\n\t\t// We want to sort by id because moving elements about in the DOM will\n\t\t// cause the element to get removed by react as it moves the DOM node. This\n\t\t// causes <iframes/> to re-render which is hella annoying and a perf\n\t\t// drain. By always sorting by 'id' we keep the shapes always in the\n\t\t// same order; but we later use index to set the element's 'z-index'\n\t\t// to change the \"rendered\" position in z-space.\n\t\treturn renderingShapes.sort(sortById)\n\t}\n\n\t/* --------------------- Pages ---------------------- */\n\n\t@computed private _getAllPagesQuery() {\n\t\treturn this.store.query.records('page')\n\t}\n\n\t/**\n\t * Info about the project's current pages.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPages()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPages(): TLPage[] {\n\t\treturn Array.from(this._getAllPagesQuery().get()).sort(sortByIndex)\n\t}\n\n\t/**\n\t * The current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPage()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPage(): TLPage {\n\t\treturn this.getPage(this.getCurrentPageId())!\n\t}\n\n\t/**\n\t * The current page id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageId()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageId(): TLPageId {\n\t\treturn this.getInstanceState().currentPageId\n\t}\n\n\t/**\n\t * Get a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPage(myPage.id)\n\t * editor.getPage(myPage)\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to get.\n\t *\n\t * @public\n\t */\n\tgetPage(page: TLPageId | TLPage): TLPage | undefined {\n\t\treturn this.store.get(typeof page === 'string' ? page : page.id)\n\t}\n\n\t/* @internal */\n\tprivate readonly _currentPageShapeIds: ReturnType<typeof deriveShapeIdsInCurrentPage>\n\n\t/**\n\t * An array of all of the shapes on the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageIds()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPageShapeIds() {\n\t\treturn this._currentPageShapeIds.get()\n\t}\n\n\t/**\n\t * @internal\n\t */\n\t@computed\n\tgetCurrentPageShapeIdsSorted() {\n\t\treturn Array.from(this.getCurrentPageShapeIds()).sort()\n\t}\n\n\t/**\n\t * Get the ids of shapes on a page.\n\t *\n\t * @example\n\t * ```ts\n\t * const idsOnPage1 = editor.getPageShapeIds('page1')\n\t * const idsOnPage2 = editor.getPageShapeIds(myPage2)\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to get the shape ids for.\n\t *\n\t * @public\n\t **/\n\tgetPageShapeIds(page: TLPageId | TLPage): Set<TLShapeId> {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tconst result = this.store.query.exec('shape', { parentId: { eq: pageId } })\n\t\treturn this.getShapeAndDescendantIds(result.map((s) => s.id))\n\t}\n\n\t/**\n\t * Set the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentPage('page1')\n\t * editor.setCurrentPage(myPage1)\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to set as the current page.\n\t *\n\t * @public\n\t */\n\tsetCurrentPage(page: TLPageId | TLPage): this {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tif (!this.store.has(pageId)) {\n\t\t\tconsole.error(\"Tried to set the current page id to a page that doesn't exist.\")\n\t\t\treturn this\n\t\t}\n\n\t\tthis.stopFollowingUser()\n\t\t// finish off any in-progress interactions\n\t\tthis.complete()\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: pageId }])\n\t\t\t\t// ensure camera constraints are applied\n\t\t\t\tthis.setCamera(this.getCamera())\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Update a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updatePage({ id: 'page2', name: 'Page 2' })\n\t * ```\n\t *\n\t * @param partial - The partial of the shape to update.\n\t *\n\t * @public\n\t */\n\tupdatePage(partial: RequiredKeys<Partial<TLPage>, 'id'>): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst prev = this.getPage(partial.id)\n\t\tif (!prev) return this\n\n\t\treturn this.run(() => this.store.update(partial.id, (page) => ({ ...page, ...partial })))\n\t}\n\n\t/**\n\t * Create a page whilst ensuring that the page name is unique.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createPage(myPage)\n\t * editor.createPage({ name: 'Page 2' })\n\t * ```\n\t *\n\t * @param page - The page (or page partial) to create.\n\t *\n\t * @public\n\t */\n\tcreatePage(page: Partial<TLPage>): this {\n\t\tthis.run(() => {\n\t\t\tif (this.getIsReadonly()) return\n\t\t\tif (this.getPages().length >= this.options.maxPages) return\n\t\t\tconst pages = this.getPages()\n\n\t\t\tconst name = getIncrementedName(\n\t\t\t\tpage.name ?? 'Page 1',\n\t\t\t\tpages.map((p) => p.name)\n\t\t\t)\n\n\t\t\tlet index = page.index\n\n\t\t\tif (!index || pages.some((p) => p.index === index)) {\n\t\t\t\tindex = getIndexAbove(pages[pages.length - 1].index)\n\t\t\t}\n\n\t\t\tconst newPage = PageRecordType.create({\n\t\t\t\tmeta: {},\n\t\t\t\t...page,\n\t\t\t\tname,\n\t\t\t\tindex,\n\t\t\t})\n\n\t\t\tthis.store.put([newPage])\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deletePage('page1')\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to delete.\n\t *\n\t * @public\n\t */\n\tdeletePage(page: TLPageId | TLPage): this {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tif (this.getIsReadonly()) return\n\t\t\t\tconst pages = this.getPages()\n\t\t\t\tif (pages.length === 1) return\n\n\t\t\t\tconst deletedPage = this.getPage(id)\n\t\t\t\tif (!deletedPage) return\n\n\t\t\t\tif (id === this.getCurrentPageId()) {\n\t\t\t\t\tconst index = pages.findIndex((page) => page.id === id)\n\t\t\t\t\tconst next = pages[index - 1] ?? pages[index + 1]\n\t\t\t\t\tthis.setCurrentPage(next.id)\n\t\t\t\t}\n\n\t\t\t\tconst shapes = this.getSortedChildIdsForParent(deletedPage.id)\n\t\t\t\tthis.deleteShapes(shapes)\n\n\t\t\t\tthis.store.remove([deletedPage.id])\n\t\t\t},\n\t\t\t{ ignoreShapeLock: true }\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate a page.\n\t *\n\t * @param page - The page (or the page id) to duplicate. Defaults to the current page.\n\t * @param createId - The id of the new page. Defaults to a new id.\n\t *\n\t * @public\n\t */\n\tduplicatePage(page: TLPageId | TLPage, createId: TLPageId = PageRecordType.createId()): this {\n\t\tif (this.getPages().length >= this.options.maxPages) return this\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tconst freshPage = this.getPage(id) // get the most recent version of the page anyway\n\t\tif (!freshPage) return this\n\n\t\tconst prevCamera = { ...this.getCamera() }\n\t\tconst content = this.getContentFromCurrentPage(this.getSortedChildIdsForParent(freshPage.id))\n\n\t\tthis.run(() => {\n\t\t\tconst pages = this.getPages()\n\t\t\tconst index = getIndexBetween(freshPage.index, pages[pages.indexOf(freshPage) + 1]?.index)\n\n\t\t\t// create the page (also creates the pagestate and camera for the new page)\n\t\t\tthis.createPage({ name: freshPage.name + ' Copy', id: createId, index })\n\t\t\t// set the new page as the current page\n\t\t\tthis.setCurrentPage(createId)\n\t\t\t// update the new page's camera to the previous page's camera\n\t\t\tthis.setCamera(prevCamera)\n\n\t\t\tif (content) {\n\t\t\t\t// If we had content on the previous page, put it on the new page\n\t\t\t\treturn this.putContentOntoCurrentPage(content)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Rename a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.renamePage('page1', 'My Page')\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to rename.\n\t * @param name - The new name.\n\t *\n\t * @public\n\t */\n\trenamePage(page: TLPageId | TLPage, name: string) {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tif (this.getIsReadonly()) return this\n\t\tthis.updatePage({ id, name })\n\t\treturn this\n\t}\n\n\t/* --------------------- Assets --------------------- */\n\n\t/** @internal */\n\t@computed private _getAllAssetsQuery() {\n\t\treturn this.store.query.records('asset')\n\t}\n\n\t/**\n\t * Get all assets in the editor.\n\t *\n\t * @public\n\t */\n\tgetAssets() {\n\t\treturn this._getAllAssetsQuery().get()\n\t}\n\n\t/**\n\t * Create one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createAssets([...myAssets])\n\t * ```\n\t *\n\t * @param assets - The assets to create.\n\t *\n\t * @public\n\t */\n\tcreateAssets(assets: TLAsset[]): this {\n\t\tif (this.getIsReadonly()) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(() => this.store.put(assets), { history: 'ignore' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Update one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateAssets([{ id: 'asset1', name: 'New name' }])\n\t * ```\n\t *\n\t * @param assets - The assets to update.\n\t *\n\t * @public\n\t */\n\tupdateAssets(assets: TLAssetPartial[]): this {\n\t\tif (this.getIsReadonly()) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put(\n\t\t\t\t\tassets.map((partial) => ({\n\t\t\t\t\t\t...this.store.get(partial.id)!,\n\t\t\t\t\t\t...partial,\n\t\t\t\t\t}))\n\t\t\t\t)\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteAssets(['asset1', 'asset2'])\n\t * ```\n\t *\n\t * @param assets - The assets (or asset ids) to delete.\n\t *\n\t * @public\n\t */\n\tdeleteAssets(assets: TLAssetId[] | TLAsset[]): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst ids =\n\t\t\ttypeof assets[0] === 'string'\n\t\t\t\t? (assets as TLAssetId[])\n\t\t\t\t: (assets as TLAsset[]).map((a) => a.id)\n\t\tif (ids.length <= 0) return this\n\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.props.assets.remove?.(ids)\n\t\t\t\tthis.store.remove(ids)\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an asset by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getAsset('asset1')\n\t * ```\n\t *\n\t * @param asset - The asset (or asset id) to get.\n\t *\n\t * @public\n\t */\n\tgetAsset<T extends TLAsset>(asset: T | T['id']): T | undefined {\n\t\treturn this.store.get(typeof asset === 'string' ? asset : asset.id) as T | undefined\n\t}\n\n\tasync resolveAssetUrl(\n\t\tassetId: TLAssetId | null,\n\t\tcontext: {\n\t\t\tscreenScale?: number\n\t\t\tshouldResolveToOriginal?: boolean\n\t\t\tdpr?: number\n\t\t}\n\t): Promise<string | null> {\n\t\tif (!assetId) return null\n\t\tconst asset = this.getAsset(assetId)\n\t\tif (!asset) return null\n\n\t\tconst {\n\t\t\tscreenScale = 1,\n\t\t\tshouldResolveToOriginal = false,\n\t\t\tdpr = this.getInstanceState().devicePixelRatio,\n\t\t} = context\n\n\t\t// We only look at the zoom level at powers of 2.\n\t\tconst zoomStepFunction = (zoom: number) => Math.pow(2, Math.ceil(Math.log2(zoom)))\n\t\tconst steppedScreenScale = zoomStepFunction(screenScale)\n\t\tconst networkEffectiveType: string | null =\n\t\t\t'connection' in navigator ? (navigator as any).connection.effectiveType : null\n\n\t\treturn await this.store.props.assets.resolve(asset, {\n\t\t\tscreenScale: screenScale || 1,\n\t\t\tsteppedScreenScale,\n\t\t\tdpr,\n\t\t\tnetworkEffectiveType,\n\t\t\tshouldResolveToOriginal,\n\t\t})\n\t}\n\t/**\n\t * Upload an asset to the store's asset service, returning a URL that can be used to resolve the\n\t * asset.\n\t */\n\tasync uploadAsset(\n\t\tasset: TLAsset,\n\t\tfile: File,\n\t\tabortSignal?: AbortSignal\n\t): Promise<{ src: string; meta?: JsonObject }> {\n\t\treturn await this.store.props.assets.upload(asset, file, abortSignal)\n\t}\n\n\t/* --------------------- Shapes --------------------- */\n\n\tprivate _shapeGeometryCaches: Record<string, ComputedCache<Geometry2d, TLShape>> = {}\n\n\t/**\n\t * Get the geometry of a shape in shape-space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeGeometry(myShape)\n\t * editor.getShapeGeometry(myShapeId)\n\t * editor.getShapeGeometry(myShapeId, { context: \"arrow\" })\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the geometry for.\n\t * @param opts - Additional options about the request for geometry. Passed to {@link ShapeUtil.getGeometry}.\n\t *\n\t * @public\n\t */\n\tgetShapeGeometry<T extends Geometry2d>(shape: TLShape | TLShapeId, opts?: TLGeometryOpts): T {\n\t\tconst context = opts?.context ?? 'none'\n\t\tif (!this._shapeGeometryCaches[context]) {\n\t\t\tthis._shapeGeometryCaches[context] = this.store.createComputedCache(\n\t\t\t\t'bounds',\n\t\t\t\t(shape) => {\n\t\t\t\t\tthis.fonts.trackFontsForShape(shape)\n\t\t\t\t\treturn this.getShapeUtil(shape).getGeometry(shape, opts)\n\t\t\t\t},\n\t\t\t\t{ areRecordsEqual: areShapesContentEqual }\n\t\t\t)\n\t\t}\n\t\treturn this._shapeGeometryCaches[context].get(\n\t\t\ttypeof shape === 'string' ? shape : shape.id\n\t\t)! as T\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeHandlesCache(): ComputedCache<TLHandle[] | undefined, TLShape> {\n\t\treturn this.store.createComputedCache(\n\t\t\t'handles',\n\t\t\t(shape) => {\n\t\t\t\treturn this.getShapeUtil(shape).getHandles?.(shape)\n\t\t\t},\n\t\t\t{\n\t\t\t\tareRecordsEqual: areShapesContentEqual,\n\t\t\t}\n\t\t)\n\t}\n\n\t/**\n\t * Get the handles (if any) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeHandles(myShape)\n\t * editor.getShapeHandles(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the handles for.\n\t * @public\n\t */\n\tgetShapeHandles<T extends TLShape>(shape: T | T['id']): TLHandle[] | undefined {\n\t\treturn this._getShapeHandlesCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the local transform for a shape as a matrix model. This transform reflects both its\n\t * translation (x, y) from from either its parent's top left corner, if the shape's parent is\n\t * another shape, or else from the 0,0 of the page, if the shape's parent is the page; and the\n\t * shape's rotation.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeLocalTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to get the local transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeLocalTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) throw Error('Editor.getTransform: shape not found')\n\t\treturn Mat.Identity().translate(freshShape.x, freshShape.y).rotate(freshShape.rotation)\n\t}\n\n\t/**\n\t * A cache of page transforms.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapePageTransformCache(): ComputedCache<Mat, TLShape> {\n\t\treturn this.store.createComputedCache<Mat, TLShape>('pageTransformCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) {\n\t\t\t\treturn this.getShapeLocalTransform(shape)\n\t\t\t}\n\n\t\t\t// If the shape's parent doesn't exist yet (e.g. when merging in changes from remote in the wrong order)\n\t\t\t// then we can't compute the transform yet, so just return the identity matrix.\n\t\t\t// In the future we should look at creating a store update mechanism that understands and preserves\n\t\t\t// ordering.\n\t\t\tconst parentTransform =\n\t\t\t\tthis._getShapePageTransformCache().get(shape.parentId) ?? Mat.Identity()\n\t\t\treturn Mat.Compose(parentTransform, this.getShapeLocalTransform(shape)!)\n\t\t})\n\t}\n\n\t/**\n\t * Get the local transform of a shape's parent as a matrix model.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParentTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the parent transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeParentTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape || isPageId(freshShape.parentId)) return Mat.Identity()\n\t\treturn this._getShapePageTransformCache().get(freshShape.parentId) ?? Mat.Identity()\n\t}\n\n\t/**\n\t * Get the transform of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageTransform(myShape)\n\t * editor.getShapePageTransform(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the page transform for.\n\t *\n\t * @public\n\t */\n\tgetShapePageTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id) ?? Mat.Identity()\n\t}\n\n\t/** @internal */\n\t@computed private _getShapePageBoundsCache(): ComputedCache<Box, TLShape> {\n\t\treturn this.store.createComputedCache<Box, TLShape>('pageBoundsCache', (shape) => {\n\t\t\tconst pageTransform = this.getShapePageTransform(shape)\n\t\t\tif (!pageTransform) return undefined\n\n\t\t\treturn Box.FromPoints(\n\t\t\t\tpageTransform.applyToPoints(this.getShapeGeometry(shape).boundsVertices)\n\t\t\t)\n\t\t})\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageBounds(myShape)\n\t * editor.getShapePageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapePageBounds(shape: TLShape | TLShapeId): Box | undefined {\n\t\treturn this._getShapePageBoundsCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * A cache of clip paths used for clipping.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapeClipPathCache(): ComputedCache<string, TLShape> {\n\t\treturn this.store.createComputedCache<string, TLShape>('clipPathCache', (shape) => {\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (!pageMask) return undefined\n\t\t\tif (pageMask.length === 0) {\n\t\t\t\treturn `polygon(0px 0px, 0px 0px, 0px 0px)`\n\t\t\t}\n\n\t\t\tconst pageTransform = this._getShapePageTransformCache().get(shape.id)\n\t\t\tif (!pageTransform) return undefined\n\n\t\t\tconst localMask = Mat.applyToPoints(Mat.Inverse(pageTransform), pageMask)\n\n\t\t\treturn `polygon(${localMask.map((p) => `${p.x}px ${p.y}px`).join(',')})`\n\t\t})\n\t}\n\n\t/**\n\t * Get the clip path for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const clipPath = editor.getShapeClipPath(shape)\n\t * const clipPath = editor.getShapeClipPath(shape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the clip path for.\n\t *\n\t * @returns The clip path or undefined.\n\t *\n\t * @public\n\t */\n\tgetShapeClipPath(shape: TLShape | TLShapeId): string | undefined {\n\t\treturn this._getShapeClipPathCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskCache(): ComputedCache<Vec[], TLShape> {\n\t\treturn this.store.createComputedCache('pageMaskCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) return undefined\n\n\t\t\tconst clipPaths: Vec[][] = []\n\t\t\t// Get all ancestors that can potentially clip this shape\n\t\t\tfor (const ancestor of this.getShapeAncestors(shape.id)) {\n\t\t\t\tconst util = this.getShapeUtil(ancestor)\n\t\t\t\tconst clipPath = util.getClipPath?.(ancestor)\n\t\t\t\tif (!clipPath) continue\n\t\t\t\tif (util.shouldClipChild?.(shape) === false) continue\n\t\t\t\tconst pageTransform = this.getShapePageTransform(ancestor.id)\n\t\t\t\tclipPaths.push(pageTransform.applyToPoints(clipPath))\n\t\t\t}\n\t\t\tif (clipPaths.length === 0) return undefined\n\n\t\t\tconst pageMask = clipPaths.reduce((acc, b) => {\n\t\t\t\tconst intersection = intersectPolygonPolygon(acc, b)\n\t\t\t\tif (intersection) {\n\t\t\t\t\treturn intersection.map(Vec.Cast)\n\t\t\t\t}\n\t\t\t\treturn []\n\t\t\t})\n\n\t\t\treturn pageMask\n\t\t})\n\t}\n\n\t/**\n\t * Get the mask (in the current page space) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const pageMask = editor.getShapeMask(shape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or the shape id) of the shape to get the mask for.\n\t *\n\t * @returns The mask for the shape.\n\t *\n\t * @public\n\t */\n\tgetShapeMask(shape: TLShapeId | TLShape): VecLike[] | undefined {\n\t\treturn this._getShapeMaskCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space, incorporating any masks. For example, if the\n\t * shape were the child of a frame and was half way out of the frame, the bounds would be the half\n\t * of the shape that was in the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeMaskedPageBounds(myShape)\n\t * editor.getShapeMaskedPageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape to get the masked bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapeMaskedPageBounds(shape: TLShapeId | TLShape): Box | undefined {\n\t\tif (typeof shape !== 'string') shape = shape.id\n\t\treturn this._getShapeMaskedPageBoundsCache().get(shape)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskedPageBoundsCache(): ComputedCache<Box, TLShape> {\n\t\treturn this.store.createComputedCache('shapeMaskedPageBoundsCache', (shape) => {\n\t\t\tconst pageBounds = this._getShapePageBoundsCache().get(shape.id)\n\t\t\tif (!pageBounds) return\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (pageMask) {\n\t\t\t\tif (pageMask.length === 0) return undefined\n\t\t\t\tconst { corners } = pageBounds\n\t\t\t\tif (corners.every((p, i) => p && Vec.Equals(p, pageMask[i]))) return pageBounds.clone()\n\t\t\t\tconst intersection = intersectPolygonPolygon(pageMask, corners)\n\t\t\t\tif (!intersection) return\n\t\t\t\treturn Box.FromPoints(intersection)\n\t\t\t}\n\t\t\treturn pageBounds\n\t\t})\n\t}\n\n\t/**\n\t * Get the ancestors of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestors = editor.getShapeAncestors(myShape)\n\t * const ancestors = editor.getShapeAncestors(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the ancestors for.\n\t * @param acc - The accumulator.\n\t *\n\t * @public\n\t */\n\tgetShapeAncestors(shape: TLShapeId | TLShape, acc: TLShape[] = []): TLShape[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return acc\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) {\n\t\t\tacc.reverse()\n\t\t\treturn acc\n\t\t}\n\n\t\tconst parent = this.store.get(parentId)\n\t\tif (!parent) return acc\n\t\tacc.push(parent)\n\t\treturn this.getShapeAncestors(parent, acc)\n\t}\n\n\t/**\n\t * Find the first ancestor matching the given predicate\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestor = editor.findShapeAncestor(myShape)\n\t * const ancestor = editor.findShapeAncestor(myShape.id)\n\t * const ancestor = editor.findShapeAncestor(myShape.id, (shape) => shape.type === 'frame')\n\t * ```\n\t *\n\t * @param shape - The shape to check the ancestors for.\n\t * @param predicate - The predicate to match.\n\t *\n\t * @public\n\t */\n\tfindShapeAncestor(\n\t\tshape: TLShape | TLShapeId,\n\t\tpredicate: (parent: TLShape) => boolean\n\t): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return\n\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) return\n\n\t\tconst parent = this.getShape(parentId)\n\t\tif (!parent) return\n\t\treturn predicate(parent) ? parent : this.findShapeAncestor(parent, predicate)\n\t}\n\n\t/**\n\t * Returns true if the the given shape has the given ancestor.\n\t *\n\t * @param shape - The shape.\n\t * @param ancestorId - The id of the ancestor.\n\t *\n\t * @public\n\t */\n\thasAncestor(shape: TLShape | TLShapeId | undefined, ancestorId: TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst freshShape = id && this.getShape(id)\n\t\tif (!freshShape) return false\n\t\tif (freshShape.parentId === ancestorId) return true\n\t\treturn this.hasAncestor(this.getShapeParent(freshShape), ancestorId)\n\t}\n\n\t/**\n\t * Get the common ancestor of two or more shapes that matches a predicate.\n\t *\n\t * @param shapes - The shapes (or shape ids) to check.\n\t * @param predicate - The predicate to match.\n\t */\n\tfindCommonAncestor(\n\t\tshapes: TLShape[] | TLShapeId[],\n\t\tpredicate?: (shape: TLShape) => boolean\n\t): TLShapeId | undefined {\n\t\tif (shapes.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst freshShapes = compact(ids.map((id) => this.getShape(id)))\n\n\t\tif (freshShapes.length === 1) {\n\t\t\tconst parentId = freshShapes[0].parentId\n\t\t\tif (isPageId(parentId)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\treturn predicate ? this.findShapeAncestor(freshShapes[0], predicate)?.id : parentId\n\t\t}\n\n\t\tconst [nodeA, ...others] = freshShapes\n\t\tlet ancestor = this.getShapeParent(nodeA)\n\t\twhile (ancestor) {\n\t\t\t// TODO: this is not ideal, optimize\n\t\t\tif (predicate && !predicate(ancestor)) {\n\t\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (others.every((shape) => this.hasAncestor(shape, ancestor!.id))) {\n\t\t\t\treturn ancestor!.id\n\t\t\t}\n\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t}\n\t\treturn undefined\n\t}\n\n\t/**\n\t * Check whether a shape or its parent is locked.\n\t *\n\t * @param shape - The shape (or shape id) to check.\n\t *\n\t * @public\n\t */\n\tisShapeOrAncestorLocked(shape?: TLShape | TLShapeId): boolean {\n\t\tconst _shape = shape && this.getShape(shape)\n\t\tif (_shape === undefined) return false\n\t\tif (_shape.isLocked) return true\n\t\treturn this.isShapeOrAncestorLocked(this.getShapeParent(_shape))\n\t}\n\n\t/**\n\t * Get shapes that are outside of the viewport.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetNotVisibleShapes() {\n\t\treturn this._notVisibleShapes.get()\n\t}\n\n\tprivate _notVisibleShapes = notVisibleShapes(this)\n\n\t/**\n\t * Get culled shapes (those that should not render), taking into account which shapes are selected or editing.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCulledShapes() {\n\t\tconst notVisibleShapes = this.getNotVisibleShapes()\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tconst editingId = this.getEditingShapeId()\n\t\tconst culledShapes = new Set<TLShapeId>(notVisibleShapes)\n\t\t// we don't cull the shape we are editing\n\t\tif (editingId) {\n\t\t\tculledShapes.delete(editingId)\n\t\t}\n\t\t// we also don't cull selected shapes\n\t\tselectedShapeIds.forEach((id) => {\n\t\t\tculledShapes.delete(id)\n\t\t})\n\t\treturn culledShapes\n\t}\n\n\t/**\n\t * The bounds of the current page (the common bounds of all of the shapes on the page).\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageBounds(): Box | undefined {\n\t\tlet commonBounds: Box | undefined\n\n\t\tthis.getCurrentPageShapeIdsSorted().forEach((shapeId) => {\n\t\t\tconst bounds = this.getShapeMaskedPageBounds(shapeId)\n\t\t\tif (!bounds) return\n\t\t\tif (!commonBounds) {\n\t\t\t\tcommonBounds = bounds.clone()\n\t\t\t} else {\n\t\t\t\tcommonBounds = commonBounds.expand(bounds)\n\t\t\t}\n\t\t})\n\n\t\treturn commonBounds\n\t}\n\n\t/**\n\t * Get the top-most selected shape at the given point, ignoring groups.\n\t *\n\t * @param point - The point to check.\n\t *\n\t * @returns The top-most selected shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetSelectedShapeAtPoint(point: VecLike): TLShape | undefined {\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn this.getCurrentPageShapesSorted()\n\t\t\t.filter((shape) => shape.type !== 'group' && selectedShapeIds.includes(shape.id))\n\t\t\t.reverse() // find last\n\t\t\t.find((shape) => this.isPointInShape(shape, point, { hitInside: true, margin: 0 }))\n\t}\n\n\t/**\n\t * Get the shape at the current point.\n\t *\n\t * @param point - The point to check.\n\t * @param opts - Options for the check: `hitInside` to check if the point is inside the shape, `margin` to check if the point is within a margin of the shape, `hitFrameInside` to check if the point is inside the frame, and `filter` to filter the shapes to check.\n\t *\n\t * @returns The shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetShapeAtPoint(point: VecLike, opts: TLGetShapeAtPointOptions = {}): TLShape | undefined {\n\t\tconst zoomLevel = this.getZoomLevel()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\tconst {\n\t\t\tfilter,\n\t\t\tmargin = 0,\n\t\t\thitLocked = false,\n\t\t\thitLabels = false,\n\t\t\thitInside = false,\n\t\t\thitFrameInside = false,\n\t\t} = opts\n\n\t\tconst [innerMargin, outerMargin] = Array.isArray(margin) ? margin : [margin, margin]\n\n\t\tlet inHollowSmallestArea = Infinity\n\t\tlet inHollowSmallestAreaHit: TLShape | null = null\n\n\t\tlet inMarginClosestToEdgeDistance = Infinity\n\t\tlet inMarginClosestToEdgeHit: TLShape | null = null\n\n\t\tconst shapesToCheck = (\n\t\t\topts.renderingOnly\n\t\t\t\t? this.getCurrentPageRenderingShapesSorted()\n\t\t\t\t: this.getCurrentPageShapesSorted()\n\t\t).filter((shape) => {\n\t\t\tif (\n\t\t\t\t(shape.isLocked && !hitLocked) ||\n\t\t\t\tthis.isShapeHidden(shape) ||\n\t\t\t\tthis.isShapeOfType(shape, 'group')\n\t\t\t)\n\t\t\t\treturn false\n\t\t\tconst pageMask = this.getShapeMask(shape)\n\t\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\t\t\tif (filter && !filter(shape)) return false\n\t\t\treturn true\n\t\t})\n\n\t\tfor (let i = shapesToCheck.length - 1; i >= 0; i--) {\n\t\t\tconst shape = shapesToCheck[i]\n\t\t\tconst geometry = this.getShapeGeometry(shape)\n\t\t\tconst isGroup = geometry instanceof Group2d\n\n\t\t\tconst pointInShapeSpace = this.getPointInShapeSpace(shape, point)\n\n\t\t\t// Check labels first\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType<TLFrameShape>(shape, 'frame') ||\n\t\t\t\t((this.isShapeOfType<TLNoteShape>(shape, 'note') ||\n\t\t\t\t\tthis.isShapeOfType<TLArrowShape>(shape, 'arrow') ||\n\t\t\t\t\t(this.isShapeOfType<TLGeoShape>(shape, 'geo') && shape.props.fill === 'none')) &&\n\t\t\t\t\tthis.getShapeUtil(shape).getText(shape)?.trim())\n\t\t\t) {\n\t\t\t\tfor (const childGeometry of (geometry as Group2d).children) {\n\t\t\t\t\tif (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {\n\t\t\t\t\t\treturn shape\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.isShapeOfType<TLFrameShape>(shape, 'frame')) {\n\t\t\t\t// On the rare case that we've hit a frame (not its label), test again hitInside to be forced true;\n\t\t\t\t// this prevents clicks from passing through the body of a frame to shapes behind it.\n\n\t\t\t\t// If the hit is within the frame's outer margin, then select the frame\n\t\t\t\tconst distance = geometry.distanceToPoint(pointInShapeSpace, hitFrameInside)\n\t\t\t\tif (\n\t\t\t\t\thitFrameInside\n\t\t\t\t\t\t? (distance > 0 && distance <= outerMargin) ||\n\t\t\t\t\t\t\t(distance <= 0 && distance > -innerMargin)\n\t\t\t\t\t\t: distance > 0 && distance <= outerMargin\n\t\t\t\t) {\n\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t}\n\n\t\t\t\tif (geometry.hitTestPoint(pointInShapeSpace, 0, true)) {\n\t\t\t\t\t// Once we've hit a frame, we want to end the search. If we have hit a shape\n\t\t\t\t\t// already, then this would either be above the frame or a child of the frame,\n\t\t\t\t\t// so we want to return that. Otherwise, the point is in the empty space of the\n\t\t\t\t\t// frame. If `hitFrameInside` is true (e.g. used drawing an arrow into the\n\t\t\t\t\t// frame) we the frame itself; other wise, (e.g. when hovering or pointing)\n\t\t\t\t\t// we would want to return null.\n\t\t\t\t\treturn (\n\t\t\t\t\t\tinMarginClosestToEdgeHit ||\n\t\t\t\t\t\tinHollowSmallestAreaHit ||\n\t\t\t\t\t\t(hitFrameInside ? shape : undefined)\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlet distance: number\n\n\t\t\tif (isGroup) {\n\t\t\t\tlet minDistance = Infinity\n\t\t\t\tfor (const childGeometry of geometry.children) {\n\t\t\t\t\tif (childGeometry.isLabel && !hitLabels) continue\n\n\t\t\t\t\t// hit test the all of the child geometries that aren't labels\n\t\t\t\t\tconst tDistance = childGeometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\tif (tDistance < minDistance) {\n\t\t\t\t\t\tminDistance = tDistance\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tdistance = minDistance\n\t\t\t} else {\n\t\t\t\t// If the margin is zero and the geometry has a very small width or height,\n\t\t\t\t// then check the actual distance. This is to prevent a bug where straight\n\t\t\t\t// lines would never pass the broad phase (point-in-bounds) check.\n\t\t\t\tif (outerMargin === 0 && (geometry.bounds.w < 1 || geometry.bounds.h < 1)) {\n\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t} else {\n\t\t\t\t\t// Broad phase\n\t\t\t\t\tif (geometry.bounds.containsPoint(pointInShapeSpace, outerMargin)) {\n\t\t\t\t\t\t// Narrow phase (actual distance)\n\t\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Failed the broad phase, geddafugaotta'ere!\n\t\t\t\t\t\tdistance = Infinity\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (geometry.isClosed) {\n\t\t\t\t// For closed shapes, the distance will be positive if outside of\n\t\t\t\t// the shape or negative if inside of the shape. If the distance\n\t\t\t\t// is greater than the margin, then it's a miss. Otherwise...\n\n\t\t\t\t// Are we close to the shape's edge?\n\t\t\t\tif (distance <= outerMargin || (hitInside && distance <= 0 && distance > -innerMargin)) {\n\t\t\t\t\tif (geometry.isFilled || (isGroup && geometry.children[0].isFilled)) {\n\t\t\t\t\t\t// If the shape is filled, then it's a hit. Remember, we're\n\t\t\t\t\t\t// starting from the TOP-MOST shape in z-index order, so any\n\t\t\t\t\t\t// other hits would be occluded by the shape.\n\t\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the shape is bigger than the viewport, then skip it.\n\t\t\t\t\t\tif (this.getShapePageBounds(shape)!.contains(viewportPageBounds)) continue\n\n\t\t\t\t\t\t// If we're close to the edge of the shape, and if it's the closest edge among\n\t\t\t\t\t\t// all the edges that we've gotten close to so far, then we will want to hit the\n\t\t\t\t\t\t// shape unless we hit something else or closer in later iterations.\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\thitInside\n\t\t\t\t\t\t\t\t? // On hitInside, the distance will be negative for hits inside\n\t\t\t\t\t\t\t\t\t// If the distance is positive, check against the outer margin\n\t\t\t\t\t\t\t\t\t(distance > 0 && distance <= outerMargin) ||\n\t\t\t\t\t\t\t\t\t// If the distance is negative, check against the inner margin\n\t\t\t\t\t\t\t\t\t(distance <= 0 && distance > -innerMargin)\n\t\t\t\t\t\t\t\t: // If hitInside is false, then sadly _we do not know_ whether the\n\t\t\t\t\t\t\t\t\t// point is inside or outside of the shape, so we check against\n\t\t\t\t\t\t\t\t\t// the max of the two margins\n\t\t\t\t\t\t\t\t\tMath.abs(distance) <= Math.max(innerMargin, outerMargin)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tif (Math.abs(distance) < inMarginClosestToEdgeDistance) {\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeDistance = Math.abs(distance)\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (!inMarginClosestToEdgeHit) {\n\t\t\t\t\t\t\t// If we're not within margin distance to any edge, and if the\n\t\t\t\t\t\t\t// shape is hollow, then we want to hit the shape with the\n\t\t\t\t\t\t\t// smallest area. (There's a bug here with self-intersecting\n\t\t\t\t\t\t\t// shapes, like a closed drawing of an \"8\", but that's a bigger\n\t\t\t\t\t\t\t// problem to solve.)\n\t\t\t\t\t\t\tconst { area } = geometry\n\t\t\t\t\t\t\tif (area < inHollowSmallestArea) {\n\t\t\t\t\t\t\t\tinHollowSmallestArea = area\n\t\t\t\t\t\t\t\tinHollowSmallestAreaHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// For open shapes (e.g. lines or draw shapes) always use the margin.\n\t\t\t\t// If the distance is less than the margin, return the shape as the hit.\n\t\t\t\t// Use the editor's configurable hit test margin.\n\t\t\t\tif (distance < this.options.hitTestMargin / zoomLevel) {\n\t\t\t\t\treturn shape\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we haven't hit any filled shapes or frames, then return either\n\t\t// the shape who we hit within the margin (and of those, the one that\n\t\t// had the shortest distance between the point and the shape edge),\n\t\t// or else the hollow shape with the smallest area\u2014or if we didn't hit\n\t\t// any margins or any hollow shapes, then null.\n\t\treturn inMarginClosestToEdgeHit || inHollowSmallestAreaHit || undefined\n\t}\n\n\t/**\n\t * Get the shapes, if any, at a given page point.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapesAtPoint({ x: 100, y: 100 })\n\t * editor.getShapesAtPoint({ x: 100, y: 100 }, { hitInside: true, margin: 8 })\n\t * ```\n\t *\n\t * @param point - The page point to test.\n\t * @param opts - The options for the hit point testing.\n\t *\n\t * @returns An array of shapes at the given point, sorted in reverse order of their absolute z-index (top-most shape first).\n\t *\n\t * @public\n\t */\n\tgetShapesAtPoint(\n\t\tpoint: VecLike,\n\t\topts = {} as { margin?: number; hitInside?: boolean }\n\t): TLShape[] {\n\t\treturn this.getCurrentPageShapesSorted()\n\t\t\t.filter((shape) => !this.isShapeHidden(shape) && this.isPointInShape(shape, point, opts))\n\t\t\t.reverse()\n\t}\n\n\t/**\n\t * Test whether a point (in the current page space) will will a shape. This method takes into account masks,\n\t * such as when a shape is the child of a frame and is partially clipped by the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isPointInShape({ x: 100, y: 100 }, myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to test against.\n\t * @param point - The page point to test (in the current page space).\n\t * @param opts - The options for the hit point testing.\n\t *\n\t * @public\n\t */\n\tisPointInShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tpoint: VecLike,\n\t\topts = {} as {\n\t\t\tmargin?: number\n\t\t\thitInside?: boolean\n\t\t}\n\t): boolean {\n\t\tconst { hitInside = false, margin = 0 } = opts\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\t// If the shape is masked, and if the point falls outside of that\n\t\t// mask, then it's definitely a miss\u2014we don't need to test further.\n\t\tconst pageMask = this.getShapeMask(id)\n\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\n\t\treturn this.getShapeGeometry(id).hitTestPoint(\n\t\t\tthis.getPointInShapeSpace(shape, point),\n\t\t\tmargin,\n\t\t\thitInside\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in the local space of a shape. For example, if a\n\t * shape's page point were `{ x: 100, y: 100 }`, a page point at `{ x: 110, y: 110 }` would be at\n\t * `{ x: 10, y: 10 }` in the shape's local space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInShapeSpace(myShape, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInShapeSpace(shape: TLShape | TLShapeId, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id)!.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * Convert a delta in the current page space to a point in the local space of a shape's parent.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInParentSpace(myShape.id, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInParentSpace(shape: TLShapeId | TLShape, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return new Vec(0, 0)\n\t\tif (isPageId(freshShape.parentId)) return Vec.From(point)\n\n\t\tconst parentTransform = this.getShapePageTransform(freshShape.parentId)\n\t\tif (!parentTransform) return Vec.From(point)\n\t\treturn parentTransform.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapes(): TLShape[] {\n\t\treturn Array.from(this.getCurrentPageShapeIds(), (id) => this.store.get(id)! as TLShape)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapesSorted(): TLShape[] {\n\t\tconst result: TLShape[] = []\n\t\tconst topLevelShapes = this.getSortedChildIdsForParent(this.getCurrentPageId())\n\n\t\tfor (let i = 0, n = topLevelShapes.length; i < n; i++) {\n\t\t\tpushShapeWithDescendants(this, topLevelShapes[i], result)\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * An array containing all of the rendering shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageRenderingShapesSorted(): TLShape[] {\n\t\tconst culledShapes = this.getCulledShapes()\n\t\treturn this.getCurrentPageShapesSorted().filter(\n\t\t\t({ id }) => !culledShapes.has(id) && !this.isShapeHidden(id)\n\t\t)\n\t}\n\n\t/**\n\t * Get whether a shape matches the type of a TLShapeUtil.\n\t *\n\t * @example\n\t * ```ts\n\t * const isArrowShape = isShapeOfType<TLArrowShape>(someShape, 'arrow')\n\t * ```\n\t *\n\t * @param util - the TLShapeUtil constructor to test against\n\t * @param shape - the shape to test\n\t *\n\t * @public\n\t */\n\tisShapeOfType<T extends TLUnknownShape>(shape: TLUnknownShape, type: T['type']): shape is T\n\tisShapeOfType<T extends TLUnknownShape>(\n\t\tshapeId: TLUnknownShape['id'],\n\t\ttype: T['type']\n\t): shapeId is T['id']\n\tisShapeOfType<T extends TLUnknownShape>(\n\t\targ: TLUnknownShape | TLUnknownShape['id'],\n\t\ttype: T['type']\n\t) {\n\t\tconst shape = typeof arg === 'string' ? this.getShape(arg) : arg\n\t\tif (!shape) return false\n\t\treturn shape.type === type\n\t}\n\n\t/**\n\t * Get a shape by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShape('box1')\n\t * ```\n\t *\n\t * @param shape - The shape (or the id of the shape) to get.\n\t *\n\t * @public\n\t */\n\tgetShape<T extends TLShape = TLShape>(shape: TLShape | TLParentId): T | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (!isShapeId(id)) return undefined\n\t\treturn this.store.get(id) as T\n\t}\n\n\t/**\n\t * Get the parent shape for a given shape. Returns undefined if the shape is the direct child of\n\t * the page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParent(myShape)\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetShapeParent(shape?: TLShape | TLShapeId): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tif (!id) return undefined\n\t\tconst freshShape = this.getShape(id)\n\t\tif (freshShape === undefined || !isShapeId(freshShape.parentId)) return undefined\n\t\treturn this.getShape(freshShape.parentId)\n\t}\n\n\t/**\n\t * If siblingShape and targetShape are siblings, this returns targetShape. If targetShape has an\n\t * ancestor who is a sibling of siblingShape, this returns that ancestor. Otherwise, this returns\n\t * undefined.\n\t *\n\t * @internal\n\t */\n\tgetShapeNearestSibling(\n\t\tsiblingShape: TLShape,\n\t\ttargetShape: TLShape | undefined\n\t): TLShape | undefined {\n\t\tif (!targetShape) {\n\t\t\treturn undefined\n\t\t}\n\t\tif (targetShape.parentId === siblingShape.parentId) {\n\t\t\treturn targetShape\n\t\t}\n\n\t\tconst ancestor = this.findShapeAncestor(\n\t\t\ttargetShape,\n\t\t\t(ancestor) => ancestor.parentId === siblingShape.parentId\n\t\t)\n\n\t\treturn ancestor\n\t}\n\n\t/**\n\t * Get whether the given shape is the descendant of the given page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isShapeInPage(myShape)\n\t * editor.isShapeInPage(myShape, 'page1')\n\t * ```\n\t *\n\t * @param shape - The shape to check.\n\t * @param pageId - The id of the page to check against. Defaults to the current page.\n\t *\n\t * @public\n\t */\n\tisShapeInPage(shape: TLShape | TLShapeId, pageId = this.getCurrentPageId()): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst shapeToCheck = this.getShape(id)\n\t\tif (!shapeToCheck) return false\n\n\t\tlet shapeIsInPage = false\n\n\t\tif (shapeToCheck.parentId === pageId) {\n\t\t\tshapeIsInPage = true\n\t\t} else {\n\t\t\tlet parent = this.getShape(shapeToCheck.parentId)\n\t\t\tisInPageSearch: while (parent) {\n\t\t\t\tif (parent.parentId === pageId) {\n\t\t\t\t\tshapeIsInPage = true\n\t\t\t\t\tbreak isInPageSearch\n\t\t\t\t}\n\t\t\t\tparent = this.getShape(parent.parentId)\n\t\t\t}\n\t\t}\n\n\t\treturn shapeIsInPage\n\t}\n\n\t/**\n\t * Get the id of the containing page for a given shape.\n\t *\n\t * @param shape - The shape to get the page id for.\n\t *\n\t * @returns The id of the page that contains the shape, or undefined if the shape is undefined.\n\t *\n\t * @public\n\t */\n\tgetAncestorPageId(shape?: TLShape | TLShapeId): TLPageId | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst _shape = id && this.getShape(id)\n\t\tif (!_shape) return undefined\n\t\tif (isPageId(_shape.parentId)) {\n\t\t\treturn _shape.parentId\n\t\t} else {\n\t\t\treturn this.getAncestorPageId(this.getShape(_shape.parentId))\n\t\t}\n\t}\n\n\t// Parents and children\n\n\t/**\n\t * A cache of parents to children.\n\t *\n\t * @internal\n\t */\n\tprivate readonly _parentIdsToChildIds: ReturnType<typeof parentsToChildren>\n\n\t/**\n\t * Reparent shapes to a new parent. This operation preserves the shape's current page positions /\n\t * rotations.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.reparentShapes([box1, box2], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1', 4)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to reparent.\n\t * @param parentId - The id of the new parent shape.\n\t * @param insertIndex - The index to insert the children.\n\t *\n\t * @public\n\t */\n\treparentShapes(shapes: TLShapeId[] | TLShape[], parentId: TLParentId, insertIndex?: IndexKey) {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string' ? (shapes as TLShapeId[]) : shapes.map((s) => (s as TLShape).id)\n\t\tif (ids.length === 0) return this\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tconst parentTransform = isPageId(parentId)\n\t\t\t? Mat.Identity()\n\t\t\t: this.getShapePageTransform(parentId)!\n\n\t\tconst parentPageRotation = parentTransform.rotation()\n\n\t\tlet indices: IndexKey[] = []\n\n\t\tconst sibs = compact(this.getSortedChildIdsForParent(parentId).map((id) => this.getShape(id)))\n\n\t\tif (insertIndex) {\n\t\t\tconst sibWithInsertIndex = sibs.find((s) => s.index === insertIndex)\n\t\t\tif (sibWithInsertIndex) {\n\t\t\t\t// If there's a sibling with the same index as the insert index...\n\t\t\t\tconst sibAbove = sibs[sibs.indexOf(sibWithInsertIndex) + 1]\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the sibling has a sibling above it, insert the shapes\n\t\t\t\t\t// between the sibling and its sibling above it.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Or if the sibling is the top sibling, insert the shapes\n\t\t\t\t\t// above the sibling\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If there's no collision, then we can start at the insert index\n\t\t\t\tconst sibAbove = sibs.sort(sortByIndex).find((s) => s.index > insertIndex)\n\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the siblings include a sibling with a higher index, insert the shapes\n\t\t\t\t\t// between the insert index and the sibling with the higher index.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, we're at the top of the order, so insert the shapes above\n\t\t\t\t\t// the insert index.\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// If insert index is not specified, start the index at the top.\n\t\t\tconst sib = sibs.length && sibs[sibs.length - 1]\n\t\t\tindices = sib ? getIndicesAbove(sib.index, ids.length) : getIndices(ids.length)\n\t\t}\n\n\t\tconst invertedParentTransform = parentTransform.clone().invert()\n\n\t\tconst shapesToReparent = compact(ids.map((id) => this.getShape(id))).sort(sortByIndex)\n\n\t\t// Ignore locked shapes so that we can reparent locked shapes, for example\n\t\t// when a locked shape's parent is deleted.\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tfor (let i = 0; i < shapesToReparent.length; i++) {\n\t\t\t\t\tconst shape = shapesToReparent[i]\n\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape)!\n\t\t\t\t\tif (!pageTransform) continue\n\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tif (!pagePoint) continue\n\n\t\t\t\t\tconst newPoint = invertedParentTransform.applyToPoint(pagePoint)\n\t\t\t\t\tconst newRotation = pageTransform.rotation() - parentPageRotation\n\n\t\t\t\t\tif (shape.id === parentId) {\n\t\t\t\t\t\tthrow Error('Attempted to reparent a shape to itself!')\n\t\t\t\t\t}\n\n\t\t\t\t\tchanges.push({\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\tparentId: parentId,\n\t\t\t\t\t\tx: newPoint.x,\n\t\t\t\t\t\ty: newPoint.y,\n\t\t\t\t\t\trotation: newRotation,\n\t\t\t\t\t\tindex: indices[i],\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tthis.updateShapes(changes)\n\t\t\t},\n\t\t\t{ ignoreShapeLock: true }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the index above the highest child of a given parent.\n\t *\n\t * @param parent - The parent (or the id) of the parent.\n\t *\n\t * @returns The index.\n\t *\n\t * @public\n\t */\n\tgetHighestIndexForParent(parent: TLParentId | TLPage | TLShape): IndexKey {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst children = this._parentIdsToChildIds.get()[parentId]\n\n\t\tif (!children || children.length === 0) {\n\t\t\treturn getIndexAbove(ZERO_INDEX_KEY)\n\t\t}\n\t\tconst shape = this.getShape(children[children.length - 1])!\n\t\treturn getIndexAbove(shape.index)\n\t}\n\n\t/**\n\t * Get an array of all the children of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getSortedChildIdsForParent('frame1')\n\t * ```\n\t *\n\t * @param parent - The parent (or the id) of the parent shape.\n\t *\n\t * @public\n\t */\n\tgetSortedChildIdsForParent(parent: TLParentId | TLPage | TLShape): TLShapeId[] {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst ids = this._parentIdsToChildIds.get()[parentId]\n\t\tif (!ids) return EMPTY_ARRAY\n\t\treturn ids\n\t}\n\n\t/**\n\t * Run a visitor function for all descendants of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.visitDescendants('frame1', myCallback)\n\t * ```\n\t *\n\t * @param parent - The parent (or the id) of the parent shape.\n\t * @param visitor - The visitor function.\n\t *\n\t * @public\n\t */\n\tvisitDescendants(\n\t\tparent: TLParentId | TLPage | TLShape,\n\t\tvisitor: (id: TLShapeId) => void | false\n\t): this {\n\t\tconst children = this.getSortedChildIdsForParent(parent)\n\t\tfor (const id of children) {\n\t\t\tif (visitor(id) === false) continue\n\t\t\tthis.visitDescendants(id, visitor)\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the shape ids of all descendants of the given shapes (including the shapes themselves). IDs are returned in z-index order.\n\t *\n\t * @param ids - The ids of the shapes to get descendants of.\n\t *\n\t * @returns The descendant ids.\n\t *\n\t * @public\n\t */\n\tgetShapeAndDescendantIds(ids: TLShapeId[]): Set<TLShapeId> {\n\t\tconst shapeIds = new Set<TLShapeId>()\n\t\tfor (const shape of ids.map((id) => this.getShape(id)!).sort(sortByIndex)) {\n\t\t\tshapeIds.add(shape.id)\n\t\t\tthis.visitDescendants(shape, (descendantId) => {\n\t\t\t\tshapeIds.add(descendantId)\n\t\t\t})\n\t\t}\n\t\treturn shapeIds\n\t}\n\n\t/**\n\t * Get the shape that some shapes should be dropped on at a given point.\n\t *\n\t * @param point - The point to find the parent for.\n\t * @param droppingShapes - The shapes that are being dropped.\n\t *\n\t * @returns The shape to drop on.\n\t *\n\t * @public\n\t */\n\tgetDraggingOverShape(point: Vec, droppingShapes: TLShape[]): TLShape | undefined {\n\t\t// get fresh moving shapes\n\t\tconst draggingShapes = compact(droppingShapes.map((s) => this.getShape(s))).filter(\n\t\t\t(s) => !s.isLocked && !this.isShapeHidden(s)\n\t\t)\n\n\t\tconst maybeDraggingOverShapes = this.getShapesAtPoint(point, {\n\t\t\thitInside: true,\n\t\t\tmargin: 0,\n\t\t}).filter(\n\t\t\t(s) =>\n\t\t\t\t!droppingShapes.includes(s) &&\n\t\t\t\t!s.isLocked &&\n\t\t\t\t!this.isShapeHidden(s) &&\n\t\t\t\t!draggingShapes.includes(s)\n\t\t)\n\n\t\tfor (const maybeDraggingOverShape of maybeDraggingOverShapes) {\n\t\t\tconst shapeUtil = this.getShapeUtil(maybeDraggingOverShape)\n\t\t\t// Any shape that can handle any dragging interactions is a valid target\n\t\t\tif (\n\t\t\t\tshapeUtil.onDragShapesOver ||\n\t\t\t\tshapeUtil.onDragShapesIn ||\n\t\t\t\tshapeUtil.onDragShapesOut ||\n\t\t\t\tshapeUtil.onDropShapesOver\n\t\t\t) {\n\t\t\t\treturn maybeDraggingOverShape\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the shape that should be selected when you click on a given shape, assuming there is\n\t * nothing already selected. It will not return anything higher than or including the current\n\t * focus layer.\n\t *\n\t * @param shape - The shape to get the outermost selectable shape for.\n\t * @param filter - A function to filter the selectable shapes.\n\t *\n\t * @returns The outermost selectable shape.\n\t *\n\t * @public\n\t */\n\tgetOutermostSelectableShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tfilter?: (shape: TLShape) => boolean\n\t): TLShape {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)!\n\t\tlet match = freshShape\n\t\tlet node = freshShape as TLShape | undefined\n\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\twhile (node) {\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType<TLGroupShape>(node, 'group') &&\n\t\t\t\tfocusedGroup?.id !== node.id &&\n\t\t\t\t!this.hasAncestor(focusedGroup, node.id) &&\n\t\t\t\t(filter?.(node) ?? true)\n\t\t\t) {\n\t\t\t\tmatch = node\n\t\t\t} else if (focusedGroup?.id === node.id) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tnode = this.getShapeParent(node)\n\t\t}\n\n\t\treturn match\n\t}\n\n\t/* -------------------- Bindings -------------------- */\n\n\t@computed\n\tprivate _getBindingsIndexCache() {\n\t\tconst index = bindingsIndex(this)\n\t\treturn this.store.createComputedCache<TLBinding[], TLShape>(\n\t\t\t'bindingsIndex',\n\t\t\t(shape) => {\n\t\t\t\treturn index.get().get(shape.id)\n\t\t\t},\n\t\t\t// we can ignore the shape equality check here because the index is\n\t\t\t// computed incrementally based on what bindings are in the store\n\t\t\t{ areRecordsEqual: () => true }\n\t\t)\n\t}\n\n\t/**\n\t * Get a binding from the store by its ID if it exists.\n\t */\n\tgetBinding(id: TLBindingId): TLBinding | undefined {\n\t\treturn this.store.get(id) as TLBinding | undefined\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _from_ a particular shape. These are the bindings whose\n\t * `fromId` matched the shape's ID.\n\t */\n\tgetBindingsFromShape<Binding extends TLUnknownBinding = TLBinding>(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.fromId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _to_ a particular shape. These are the bindings whose\n\t * `toId` matches the shape's ID.\n\t */\n\tgetBindingsToShape<Binding extends TLUnknownBinding = TLBinding>(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.toId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings involving a particular shape. This includes bindings where the shape is the\n\t * `fromId` or `toId`. If a type is provided, only bindings of that type are returned.\n\t */\n\tgetBindingsInvolvingShape<Binding extends TLUnknownBinding = TLBinding>(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype?: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst result = this._getBindingsIndexCache().get(id) ?? EMPTY_ARRAY\n\t\tif (!type) return result as Binding[]\n\t\treturn result.filter((b) => b.type === type) as Binding[]\n\t}\n\n\t/**\n\t * Create bindings from a list of partial bindings. You can omit the ID and most props of a\n\t * binding, but the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBindings<B extends TLBinding = TLBinding>(partials: TLBindingCreate<B>[]) {\n\t\tconst bindings: TLBinding[] = []\n\t\tfor (const partial of partials) {\n\t\t\tconst fromShape = this.getShape(partial.fromId)\n\t\t\tconst toShape = this.getShape(partial.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: partial })) continue\n\n\t\t\tconst util = this.getBindingUtil<TLUnknownBinding>(partial.type)\n\t\t\tconst defaultProps = util.getDefaultProps()\n\t\t\tconst binding = this.store.schema.types.binding.create({\n\t\t\t\t...partial,\n\t\t\t\tid: partial.id ?? createBindingId(),\n\t\t\t\tprops: {\n\t\t\t\t\t...defaultProps,\n\t\t\t\t\t...partial.props,\n\t\t\t\t},\n\t\t\t}) as TLBinding\n\n\t\t\tbindings.push(binding)\n\t\t}\n\n\t\tthis.store.put(bindings)\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a single binding from a partial. You can omit the ID and most props of a binding, but\n\t * the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBinding<B extends TLBinding = TLBinding>(partial: TLBindingCreate<B>) {\n\t\treturn this.createBindings([partial])\n\t}\n\n\t/**\n\t * Update bindings from a list of partial bindings. Each partial must include an ID, which will\n\t * be used to match the binding to it's existing record. If there is no existing record, that\n\t * binding is skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBindings(partials: (TLBindingUpdate | null | undefined)[]) {\n\t\tconst updated: TLBinding[] = []\n\n\t\tfor (const partial of partials) {\n\t\t\tif (!partial) continue\n\n\t\t\tconst current = this.getBinding(partial.id)\n\t\t\tif (!current) continue\n\n\t\t\tconst updatedBinding = applyPartialToRecordWithProps(current, partial)\n\t\t\tif (updatedBinding === current) continue\n\n\t\t\tconst fromShape = this.getShape(updatedBinding.fromId)\n\t\t\tconst toShape = this.getShape(updatedBinding.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: updatedBinding })) continue\n\n\t\t\tupdated.push(updatedBinding)\n\t\t}\n\n\t\tthis.store.put(updated)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a binding from a partial binding. Each partial must include an ID, which will be used\n\t * to match the binding to it's existing record. If there is no existing record, that binding is\n\t * skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBinding<B extends TLBinding = TLBinding>(partial: TLBindingUpdate<B>) {\n\t\treturn this.updateBindings([partial])\n\t}\n\n\t/**\n\t * Delete several bindings by their IDs. If a binding ID doesn't exist, it's ignored.\n\t */\n\tdeleteBindings(bindings: (TLBinding | TLBindingId)[], { isolateShapes = false } = {}) {\n\t\tconst ids = bindings.map((binding) => (typeof binding === 'string' ? binding : binding.id))\n\t\tif (isolateShapes) {\n\t\t\tthis.store.atomic(() => {\n\t\t\t\tfor (const id of ids) {\n\t\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\t\tif (!binding) continue\n\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: this.getShape(binding.toId)! })\n\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: this.getShape(binding.fromId)! })\n\t\t\t\t\tthis.store.remove([id])\n\t\t\t\t}\n\t\t\t})\n\t\t} else {\n\t\t\tthis.store.remove(ids)\n\t\t}\n\t\treturn this\n\t}\n\t/**\n\t * Delete a binding by its ID. If the binding doesn't exist, it's ignored.\n\t */\n\tdeleteBinding(binding: TLBinding | TLBindingId, opts?: Parameters<this['deleteBindings']>[1]) {\n\t\treturn this.deleteBindings([binding], opts)\n\t}\n\tcanBindShapes({\n\t\tfromShape,\n\t\ttoShape,\n\t\tbinding,\n\t}: {\n\t\tfromShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\ttoShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\tbinding: TLBinding | { type: TLBinding['type'] } | TLBinding['type']\n\t}): boolean {\n\t\tconst fromShapeType = typeof fromShape === 'string' ? fromShape : fromShape.type\n\t\tconst toShapeType = typeof toShape === 'string' ? toShape : toShape.type\n\t\tconst bindingType = typeof binding === 'string' ? binding : binding.type\n\n\t\tconst canBindOpts = { fromShapeType, toShapeType, bindingType }\n\n\t\tif (fromShapeType === toShapeType) {\n\t\t\treturn this.getShapeUtil(fromShapeType).canBind(canBindOpts)\n\t\t}\n\n\t\treturn (\n\t\t\tthis.getShapeUtil(fromShapeType).canBind(canBindOpts) &&\n\t\t\tthis.getShapeUtil(toShapeType).canBind(canBindOpts)\n\t\t)\n\t}\n\n\t/* -------------------- Commands -------------------- */\n\n\t/**\n\t * Rotate shapes by a delta in radians.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI)\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI / 2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param delta - The delta in radians to apply to the selection rotation.\n\t * @param opts - The options for the rotation.\n\t */\n\trotateShapesBy(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\tdelta: number,\n\t\topts?: { center?: VecLike }\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\n\t\tconst snapshot = getRotationSnapshot({ editor: this, ids })\n\t\tif (!snapshot) return this\n\t\tapplyRotationToSnapshotShapes({\n\t\t\tdelta,\n\t\t\tsnapshot,\n\t\t\teditor: this,\n\t\t\tstage: 'one-off',\n\t\t\tcenterOverride: opts?.center,\n\t\t})\n\n\t\treturn this\n\t}\n\n\t// Gets a shape partial that includes life cycle changes: on translate start, on translate, on translate end\n\tprivate getChangesToTranslateShape(initialShape: TLShape, newShapeCoords: VecLike): TLShape {\n\t\tlet workingShape = initialShape\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tconst afterTranslateStart = util.onTranslateStart?.(workingShape)\n\t\tif (afterTranslateStart) {\n\t\t\tworkingShape = applyPartialToRecordWithProps(workingShape, afterTranslateStart)\n\t\t}\n\n\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\tid: initialShape.id,\n\t\t\ttype: initialShape.type,\n\t\t\tx: newShapeCoords.x,\n\t\t\ty: newShapeCoords.y,\n\t\t})\n\n\t\tconst afterTranslate = util.onTranslate?.(initialShape, workingShape)\n\t\tif (afterTranslate) {\n\t\t\tworkingShape = applyPartialToRecordWithProps(workingShape, afterTranslate)\n\t\t}\n\n\t\tconst afterTranslateEnd = util.onTranslateEnd?.(initialShape, workingShape)\n\t\tif (afterTranslateEnd) {\n\t\t\tworkingShape = applyPartialToRecordWithProps(workingShape, afterTranslateEnd)\n\t\t}\n\n\t\treturn workingShape\n\t}\n\n\t/**\n\t * Move shapes by a delta.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.nudgeShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t * @param offset - The offset to apply to the shapes.\n\t */\n\tnudgeShapes(shapes: TLShapeId[] | TLShape[], offset: VecLike): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)!\n\t\t\tconst localDelta = Vec.From(offset)\n\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\tif (parentTransform) localDelta.rot(-parentTransform.rotation())\n\n\t\t\tchanges.push(this.getChangesToTranslateShape(shape, localDelta.add(shape)))\n\t\t}\n\n\t\tthis.updateShapes(changes)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.duplicateShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * editor.duplicateShapes(editor.getSelectedShapes(), { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to duplicate.\n\t * @param offset - The offset (in pixels) to apply to the duplicated shapes.\n\t *\n\t * @public\n\t */\n\tduplicateShapes(shapes: TLShapeId[] | TLShape[], offset?: VecLike): this {\n\t\tthis.run(() => {\n\t\t\tconst _ids =\n\t\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t\tconst ids = this._shouldIgnoreShapeLock ? _ids : this._getUnlockedShapeIds(_ids)\n\t\t\tif (ids.length <= 0) return this\n\n\t\t\tconst initialIds = new Set(ids)\n\t\t\tconst shapeIdSet = this.getShapeAndDescendantIds(ids)\n\n\t\t\tconst orderedShapeIds = [...shapeIdSet].reverse()\n\t\t\tconst shapeIds = new Map<TLShapeId, TLShapeId>()\n\t\t\tfor (const shapeId of shapeIdSet) {\n\t\t\t\tshapeIds.set(shapeId, createShapeId())\n\t\t\t}\n\n\t\t\tconst { shapesToCreateWithOriginals, bindingsToCreate } = withIsolatedShapes(\n\t\t\t\tthis,\n\t\t\t\tshapeIdSet,\n\t\t\t\t(bindingIdsToMaintain) => {\n\t\t\t\t\tconst bindingsToCreate: TLBinding[] = []\n\t\t\t\t\tfor (const originalId of bindingIdsToMaintain) {\n\t\t\t\t\t\tconst originalBinding = this.getBinding(originalId)\n\t\t\t\t\t\tif (!originalBinding) continue\n\n\t\t\t\t\t\tconst duplicatedId = createBindingId()\n\t\t\t\t\t\tbindingsToCreate.push({\n\t\t\t\t\t\t\t...originalBinding,\n\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\tfromId: assertExists(shapeIds.get(originalBinding.fromId)),\n\t\t\t\t\t\t\ttoId: assertExists(shapeIds.get(originalBinding.toId)),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapesToCreateWithOriginals: { shape: TLShape; originalShape: TLShape }[] = []\n\t\t\t\t\tfor (const originalId of orderedShapeIds) {\n\t\t\t\t\t\tconst duplicatedId = assertExists(shapeIds.get(originalId))\n\t\t\t\t\t\tconst originalShape = this.getShape(originalId)\n\t\t\t\t\t\tif (!originalShape) continue\n\n\t\t\t\t\t\tlet ox = 0\n\t\t\t\t\t\tlet oy = 0\n\n\t\t\t\t\t\tif (offset && initialIds.has(originalId)) {\n\t\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(originalShape)\n\t\t\t\t\t\t\tconst vec = new Vec(offset.x, offset.y).rot(-parentTransform!.rotation())\n\t\t\t\t\t\t\tox = vec.x\n\t\t\t\t\t\t\toy = vec.y\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tshapesToCreateWithOriginals.push({\n\t\t\t\t\t\t\tshape: {\n\t\t\t\t\t\t\t\t...originalShape,\n\t\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\t\tx: originalShape.x + ox,\n\t\t\t\t\t\t\t\ty: originalShape.y + oy,\n\t\t\t\t\t\t\t\t// Use a dummy index for now, it will get updated outside of the `withIsolatedShapes`\n\t\t\t\t\t\t\t\tindex: 'a1' as IndexKey,\n\t\t\t\t\t\t\t\tparentId:\n\t\t\t\t\t\t\t\t\tshapeIds.get(originalShape.parentId as TLShapeId) ?? originalShape.parentId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toriginalShape,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\treturn { shapesToCreateWithOriginals, bindingsToCreate }\n\t\t\t\t}\n\t\t\t)\n\n\t\t\t// We will update the indexes after the `withIsolatedShapes`, since we cannot rely on the indexes\n\t\t\t// to be correct inside of it.\n\t\t\tshapesToCreateWithOriginals.forEach(({ shape, originalShape }) => {\n\t\t\t\tconst parentId = originalShape.parentId\n\t\t\t\tconst siblings = this.getSortedChildIdsForParent(parentId)\n\t\t\t\tconst currentIndex = siblings.indexOf(originalShape.id)\n\t\t\t\tconst siblingAboveId = siblings[currentIndex + 1]\n\t\t\t\tconst siblingAbove = siblingAboveId ? this.getShape(siblingAboveId) : undefined\n\n\t\t\t\tconst index = getIndexBetween(originalShape.index, siblingAbove?.index)\n\n\t\t\t\tshape.index = index\n\t\t\t})\n\t\t\tconst shapesToCreate = shapesToCreateWithOriginals.map(({ shape }) => shape)\n\n\t\t\tif (!this.canCreateShapes(shapesToCreate)) {\n\t\t\t\talertMaxShapes(this)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.createShapes(shapesToCreate)\n\t\t\tthis.createBindings(bindingsToCreate)\n\n\t\t\tthis.setSelectedShapes(\n\t\t\t\tcompact(\n\t\t\t\t\tids.map((oldId) => {\n\t\t\t\t\t\tconst newId = shapeIds.get(oldId)\n\t\t\t\t\t\tif (!newId) return null\n\t\t\t\t\t\tif (!this.getShape(newId)) return null\n\t\t\t\t\t\treturn newId\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t)\n\n\t\t\tif (offset !== undefined) {\n\t\t\t\t// If we've offset the duplicated shapes, check to see whether their new bounds is entirely\n\t\t\t\t// contained in the current viewport. If not, then animate the camera to be centered on the\n\t\t\t\t// new shapes.\n\t\t\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\tif (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {\n\t\t\t\t\tthis.centerOnPoint(selectionPageBounds.center, {\n\t\t\t\t\t\tanimation: { duration: this.options.animationMediumMs },\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Move shapes to page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.moveShapesToPage(['box1', 'box2'], 'page1')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param pageId - The id of the page where the shapes will be moved.\n\t *\n\t * @public\n\t */\n\tmoveShapesToPage(shapes: TLShapeId[] | TLShape[], pageId: TLPageId): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return this\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\n\t\tif (pageId === currentPageId) return this\n\t\tif (!this.store.has(pageId)) return this\n\n\t\t// Basically copy the shapes\n\t\tconst content = this.getContentFromCurrentPage(ids)\n\n\t\t// Just to be sure\n\t\tif (!content) return this\n\n\t\t// If there is no space on pageId, or if the selected shapes\n\t\t// would take the new page above the limit, don't move the shapes\n\t\tif (this.getPageShapeIds(pageId).size + content.shapes.length > this.options.maxShapesPerPage) {\n\t\t\talertMaxShapes(this, pageId)\n\t\t\treturn this\n\t\t}\n\n\t\tconst fromPageZ = this.getCamera().z\n\n\t\tthis.run(() => {\n\t\t\t// Delete the shapes on the current page\n\t\t\tthis.deleteShapes(ids)\n\n\t\t\t// Move to the next page\n\t\t\tthis.setCurrentPage(pageId)\n\n\t\t\t// Put the shape content onto the new page; parents and indices will\n\t\t\t// be taken care of by the putContent method; make sure to pop any focus\n\t\t\t// layers so that the content will be put onto the page.\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t\tthis.putContentOntoCurrentPage(content, {\n\t\t\t\tselect: true,\n\t\t\t\tpreserveIds: true,\n\t\t\t\tpreservePosition: true,\n\t\t\t})\n\n\t\t\t// Force the new page's camera to be at the same zoom level as the\n\t\t\t// \"from\" page's camera, then center the \"to\" page's camera on the\n\t\t\t// pasted shapes\n\t\t\tthis.setCamera({ ...this.getCamera(), z: fromPageZ })\n\t\t\tthis.centerOnPoint(this.getSelectionRotatedPageBounds()!.center)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Toggle the lock state of one or more shapes. If there is a mix of locked and unlocked shapes, all shapes will be locked.\n\t *\n\t * @param shapes - The shapes (or shape ids) to toggle.\n\t *\n\t * @public\n\t */\n\ttoggleLock(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly() || ids.length === 0) return this\n\n\t\tlet allLocked = true,\n\t\t\tallUnlocked = true\n\t\tconst shapesToToggle: TLShape[] = []\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (shape) {\n\t\t\t\tshapesToToggle.push(shape)\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\tallUnlocked = false\n\t\t\t\t} else {\n\t\t\t\t\tallLocked = false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.run(() => {\n\t\t\tif (allUnlocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t\tthis.setSelectedShapes([])\n\t\t\t} else if (allLocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: false }))\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes to the back of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendToBack(['id1', 'id2'])\n\t * editor.sendToBack(box1, box2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tsendToBack(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toBack', ids as TLShapeId[], {\n\t\t\tconsiderAllShapes: true,\n\t\t})\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes backward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendBackward(['id1', 'id2'])\n\t * editor.sendBackward([box1, box2])\n\t * ```\n\t *\n\t * By default, the operation will only consider overlapping shapes.\n\t * To consider all shapes, pass `{ considerAllShapes: true }` in the options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendBackward(['id1', 'id2'], { considerAllShapes: true })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t * @param opts - The options for the backward operation.\n\t *\n\t * @public\n\t */\n\tsendBackward(shapes: TLShapeId[] | TLShape[], opts: { considerAllShapes?: boolean } = {}): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'backward', ids as TLShapeId[], opts)\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes forward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringForward(['id1', 'id2'])\n\t * editor.bringForward(box1, box2)\n\t * ```\n\t *\n\t * By default, the operation will only consider overlapping shapes.\n\t * To consider all shapes, pass `{ considerAllShapes: true }` in the options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringForward(['id1', 'id2'], { considerAllShapes: true })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t * @param opts - The options for the forward operation.\n\t *\n\t * @public\n\t */\n\tbringForward(shapes: TLShapeId[] | TLShape[], opts: { considerAllShapes?: boolean } = {}): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'forward', ids as TLShapeId[], opts)\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes to the front of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringToFront(['id1', 'id2'])\n\t * editor.bringToFront([box1, box2])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tbringToFront(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toFront', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tprivate collectShapesViaArrowBindings(info: {\n\t\tinitialShapes: TLShape[]\n\t\tresultShapes: TLShape[]\n\t\tresultBounds: Box[]\n\t\tbindings: TLBinding[]\n\t\tvisited: Set<TLShapeId>\n\t}) {\n\t\tconst { initialShapes, resultShapes, resultBounds, bindings, visited } = info\n\t\tfor (const binding of bindings) {\n\t\t\tfor (const id of [binding.fromId, binding.toId]) {\n\t\t\t\tif (!visited.has(id)) {\n\t\t\t\t\tconst aligningShape = initialShapes.find((s) => s.id === id)\n\t\t\t\t\tif (aligningShape && !visited.has(aligningShape.id)) {\n\t\t\t\t\t\tvisited.add(aligningShape.id)\n\t\t\t\t\t\tconst shapePageBounds = this.getShapePageBounds(aligningShape)\n\t\t\t\t\t\tif (!shapePageBounds) continue\n\t\t\t\t\t\tresultShapes.push(aligningShape)\n\t\t\t\t\t\tresultBounds.push(shapePageBounds)\n\t\t\t\t\t\tthis.collectShapesViaArrowBindings({\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\tbindings: this.getBindingsInvolvingShape(aligningShape, 'arrow'),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Flip shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.flipShapes([box1, box2], 'horizontal', 32)\n\t * editor.flipShapes(editor.getSelectedShapeIds(), 'horizontal', 32)\n\t * ```\n\t *\n\t * @param shapes - The ids of the shapes to flip.\n\t * @param operation - Whether to flip horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tflipShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t// Collect a greedy list of shapes to flip\n\t\tconst shapesToFlipFirstPass = compact(ids.map((id) => this.getShape(id)))\n\n\t\tfor (const shape of shapesToFlipFirstPass) {\n\t\t\tif (this.isShapeOfType<TLGroupShape>(shape, 'group')) {\n\t\t\t\tconst childrenOfGroups = compact(\n\t\t\t\t\tthis.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id))\n\t\t\t\t)\n\t\t\t\tshapesToFlipFirstPass.push(...childrenOfGroups)\n\t\t\t}\n\t\t}\n\n\t\t// exclude shapes that can't be flipped\n\t\tconst shapesToFlip: {\n\t\t\tshape: TLShape\n\t\t\tlocalBounds: Box\n\t\t\tpageTransform: Mat\n\t\t\tisAspectRatioLocked: boolean\n\t\t}[] = []\n\n\t\tconst allBounds: Box[] = []\n\n\t\tfor (const shape of shapesToFlipFirstPass) {\n\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\tif (\n\t\t\t\t!util.canBeLaidOut(shape, {\n\t\t\t\t\ttype: 'flip',\n\t\t\t\t\tshapes: shapesToFlipFirstPass,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst pageBounds = this.getShapePageBounds(shape)\n\t\t\tconst localBounds = this.getShapeGeometry(shape).bounds\n\t\t\tconst pageTransform = this.getShapePageTransform(shape.id)\n\t\t\tif (!(pageBounds && localBounds && pageTransform)) continue\n\t\t\tshapesToFlip.push({\n\t\t\t\tshape,\n\t\t\t\tlocalBounds,\n\t\t\t\tpageTransform,\n\t\t\t\tisAspectRatioLocked: util.isAspectRatioLocked(shape),\n\t\t\t})\n\t\t\tallBounds.push(pageBounds)\n\t\t}\n\n\t\tif (!shapesToFlip.length) return this\n\n\t\tconst scaleOriginPage = Box.Common(allBounds).center\n\n\t\tthis.run(() => {\n\t\t\tfor (const { shape, localBounds, pageTransform, isAspectRatioLocked } of shapesToFlip) {\n\t\t\t\tthis.resizeShape(\n\t\t\t\t\tshape.id,\n\t\t\t\t\t{ x: operation === 'horizontal' ? -1 : 1, y: operation === 'vertical' ? -1 : 1 },\n\t\t\t\t\t{\n\t\t\t\t\t\tinitialBounds: localBounds,\n\t\t\t\t\t\tinitialPageTransform: pageTransform,\n\t\t\t\t\t\tinitialShape: shape,\n\t\t\t\t\t\tisAspectRatioLocked,\n\t\t\t\t\t\tmode: 'scale_shape',\n\t\t\t\t\t\tscaleOrigin: scaleOriginPage,\n\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stack shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stackShapes([box1, box2], 'horizontal')\n\t * editor.stackShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stack.\n\t * @param operation - Whether to stack horizontally or vertically.\n\t * @param gap - The gap to leave between shapes. By default, uses the editor's `adjacentShapeMargin` option.\n\t *\n\t * @public\n\t */\n\tstackShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'horizontal' | 'vertical',\n\t\tgap?: number\n\t): this {\n\t\tconst _gap = gap ?? this.options.adjacentShapeMargin\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tif (this.getIsReadonly()) return this\n\n\t\t// todo: this has a lot of extra code to handle stacking with custom gaps or auto gaps or other things like that. I don't think anyone has ever used this stuff.\n\n\t\t// always fresh shapes\n\t\tconst shapesToStackFirstPass = compact(ids.map((id) => this.getShape(id)))\n\n\t\tconst shapeClustersToStack: {\n\t\t\tshapes: TLShape[]\n\t\t\tpageBounds: Box\n\t\t}[] = []\n\t\tconst allBounds: Box[] = []\n\t\tconst visited = new Set<TLShapeId>()\n\n\t\tfor (const shape of shapesToStackFirstPass) {\n\t\t\tif (visited.has(shape.id)) continue\n\t\t\tvisited.add(shape.id)\n\n\t\t\tconst shapePageBounds = this.getShapePageBounds(shape)\n\t\t\tif (!shapePageBounds) continue\n\n\t\t\tif (\n\t\t\t\t!this.getShapeUtil(shape).canBeLaidOut?.(shape, {\n\t\t\t\t\ttype: 'stack',\n\t\t\t\t\tshapes: shapesToStackFirstPass,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst shapesMovingTogether = [shape]\n\t\t\tconst boundsOfShapesMovingTogether: Box[] = [shapePageBounds]\n\n\t\t\tthis.collectShapesViaArrowBindings({\n\t\t\t\tbindings: this.getBindingsToShape(shape.id, 'arrow'),\n\t\t\t\tinitialShapes: shapesToStackFirstPass,\n\t\t\t\tresultShapes: shapesMovingTogether,\n\t\t\t\tresultBounds: boundsOfShapesMovingTogether,\n\t\t\t\tvisited,\n\t\t\t})\n\n\t\t\tconst commonPageBounds = Box.Common(boundsOfShapesMovingTogether)\n\t\t\tif (!commonPageBounds) continue\n\n\t\t\tshapeClustersToStack.push({\n\t\t\t\tshapes: shapesMovingTogether,\n\t\t\t\tpageBounds: commonPageBounds,\n\t\t\t})\n\n\t\t\tallBounds.push(commonPageBounds)\n\t\t}\n\n\t\tconst len = shapeClustersToStack.length\n\t\tif ((_gap === 0 && len < 3) || len < 2) return this\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tdim = 'height'\n\t\t}\n\n\t\tlet shapeGap: number = 0\n\n\t\tif (_gap === 0) {\n\t\t\t// note: this is not used in the current tldraw.com; there we use a specified stack\n\n\t\t\tconst gaps: Record<number, number> = {}\n\n\t\t\tshapeClustersToStack.sort((a, b) => a.pageBounds[min] - b.pageBounds[min])\n\n\t\t\t// Collect all of the gaps between shapes. We want to find\n\t\t\t// patterns (equal gaps between shapes) and use the most common\n\t\t\t// one as the gap for all of the shapes.\n\t\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\t\tconst currCluster = shapeClustersToStack[i]\n\t\t\t\tconst nextCluster = shapeClustersToStack[i + 1]\n\t\t\t\tconst gap = nextCluster.pageBounds[min] - currCluster.pageBounds[max]\n\t\t\t\tif (!gaps[gap]) {\n\t\t\t\t\tgaps[gap] = 0\n\t\t\t\t}\n\t\t\t\tgaps[gap]++\n\t\t\t}\n\n\t\t\t// Which gap is the most common?\n\t\t\tlet maxCount = 1\n\t\t\tfor (const [gap, count] of Object.entries(gaps)) {\n\t\t\t\tif (count > maxCount) {\n\t\t\t\t\tmaxCount = count\n\t\t\t\t\tshapeGap = parseFloat(gap)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If there is no most-common gap, use the average gap.\n\t\t\tif (maxCount === 1) {\n\t\t\t\tlet totalCount = 0\n\t\t\t\tfor (const [gap, count] of Object.entries(gaps)) {\n\t\t\t\t\tshapeGap += parseFloat(gap) * count\n\t\t\t\t\ttotalCount += count\n\t\t\t\t}\n\t\t\t\tshapeGap /= totalCount\n\t\t\t}\n\t\t} else {\n\t\t\t// If a gap was provided, then use that instead.\n\t\t\tshapeGap = _gap\n\t\t}\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tlet v = shapeClustersToStack[0].pageBounds[max]\n\n\t\tfor (let i = 1; i < shapeClustersToStack.length; i++) {\n\t\t\tconst { shapes, pageBounds } = shapeClustersToStack[i]\n\t\t\tconst delta = new Vec()\n\t\t\tdelta[val] = v + shapeGap - pageBounds[val]\n\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tconst shapeDelta = delta.clone()\n\n\t\t\t\t// If the shape has another shape as its parent, and if the parent has a rotation, we need to rotate the counter-rotate delta\n\t\t\t\t// todo: ensure that the parent isn't being aligned together with its children\n\t\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\t\tif (parent) {\n\t\t\t\t\tconst parentTransform = this.getShapePageTransform(parent)\n\t\t\t\t\tif (parentTransform) shapeDelta.rot(-parentTransform.rotation())\n\t\t\t\t}\n\n\t\t\t\tshapeDelta.add(shape) // add the shape's x and y to the delta\n\t\t\t\tchanges.push(this.getChangesToTranslateShape(shape, shapeDelta))\n\t\t\t}\n\n\t\t\tv += pageBounds[dim] + shapeGap\n\t\t}\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Pack shapes into a grid centered on their current position. Based on potpack (https://github.com/mapbox/potpack).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.packShapes([box1, box2])\n\t * editor.packShapes(editor.getSelectedShapeIds(), 32)\n\t * ```\n\t *\n\t *\n\t * @param shapes - The shapes (or shape ids) to pack.\n\t * @param gap - The padding to apply to the packed shapes. Defaults to the editor's `adjacentShapeMargin` option.\n\t */\n\tpackShapes(shapes: TLShapeId[] | TLShape[], _gap?: number): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst gap = _gap ?? this.options.adjacentShapeMargin\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t// Always fresh shapes\n\t\tconst shapesToPackFirstPass = compact(ids.map((id) => this.getShape(id)))\n\n\t\tconst shapeClustersToPack: {\n\t\t\tshapes: TLShape[]\n\t\t\tpageBounds: Box\n\t\t\tnextPageBounds: Box\n\t\t}[] = []\n\n\t\tconst allBounds: Box[] = []\n\t\tconst visited = new Set<TLShapeId>()\n\n\t\tfor (const shape of shapesToPackFirstPass) {\n\t\t\tif (visited.has(shape.id)) continue\n\t\t\tvisited.add(shape.id)\n\n\t\t\tconst shapePageBounds = this.getShapePageBounds(shape)\n\t\t\tif (!shapePageBounds) continue\n\n\t\t\tif (\n\t\t\t\t!this.getShapeUtil(shape).canBeLaidOut?.(shape, {\n\t\t\t\t\ttype: 'pack',\n\t\t\t\t\tshapes: shapesToPackFirstPass,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst shapesMovingTogether = [shape]\n\t\t\tconst boundsOfShapesMovingTogether: Box[] = [shapePageBounds]\n\n\t\t\tthis.collectShapesViaArrowBindings({\n\t\t\t\tbindings: this.getBindingsToShape(shape.id, 'arrow'),\n\t\t\t\tinitialShapes: shapesToPackFirstPass,\n\t\t\t\tresultShapes: shapesMovingTogether,\n\t\t\t\tresultBounds: boundsOfShapesMovingTogether,\n\t\t\t\tvisited,\n\t\t\t})\n\n\t\t\tconst commonPageBounds = Box.Common(boundsOfShapesMovingTogether)\n\t\t\tif (!commonPageBounds) continue\n\n\t\t\tshapeClustersToPack.push({\n\t\t\t\tshapes: shapesMovingTogether,\n\t\t\t\tpageBounds: commonPageBounds,\n\t\t\t\tnextPageBounds: commonPageBounds.clone(),\n\t\t\t})\n\n\t\t\tallBounds.push(commonPageBounds)\n\t\t}\n\n\t\tif (shapeClustersToPack.length < 2) return this\n\n\t\tlet area = 0\n\t\tfor (const { pageBounds } of shapeClustersToPack) {\n\t\t\tarea += pageBounds.width * pageBounds.height\n\t\t}\n\n\t\tconst commonBounds = Box.Common(allBounds)\n\n\t\tconst maxWidth = commonBounds.width\n\n\t\t// sort the shape clusters by width and then height, descending\n\t\tshapeClustersToPack\n\t\t\t.sort((a, b) => a.pageBounds.width - b.pageBounds.width)\n\t\t\t.sort((a, b) => a.pageBounds.height - b.pageBounds.height)\n\n\t\t// Start with is (sort of) the square of the area\n\t\tconst startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth)\n\n\t\t// first shape fills the width and is infinitely tall\n\t\tconst spaces: Box[] = [new Box(commonBounds.x, commonBounds.y, startWidth, Infinity)]\n\n\t\tlet width = 0\n\t\tlet height = 0\n\t\tlet space: Box\n\t\tlet last: Box\n\n\t\tfor (const { nextPageBounds } of shapeClustersToPack) {\n\t\t\t// starting at the back (smaller shapes)\n\t\t\tfor (let i = spaces.length - 1; i >= 0; i--) {\n\t\t\t\tspace = spaces[i]\n\n\t\t\t\t// find a space that is big enough to contain the shape\n\t\t\t\tif (nextPageBounds.width > space.width || nextPageBounds.height > space.height) continue\n\n\t\t\t\t// add the shape to its top-left corner\n\t\t\t\tnextPageBounds.x = space.x\n\t\t\t\tnextPageBounds.y = space.y\n\n\t\t\t\theight = Math.max(height, nextPageBounds.maxY)\n\t\t\t\twidth = Math.max(width, nextPageBounds.maxX)\n\n\t\t\t\tif (nextPageBounds.width === space.width && nextPageBounds.height === space.height) {\n\t\t\t\t\t// remove the space on a perfect fit\n\t\t\t\t\tlast = spaces.pop()!\n\t\t\t\t\tif (i < spaces.length) spaces[i] = last\n\t\t\t\t} else if (nextPageBounds.height === space.height) {\n\t\t\t\t\t// fit the shape into the space (width)\n\t\t\t\t\tspace.x += nextPageBounds.width + gap\n\t\t\t\t\tspace.width -= nextPageBounds.width + gap\n\t\t\t\t} else if (nextPageBounds.width === space.width) {\n\t\t\t\t\t// fit the shape into the space (height)\n\t\t\t\t\tspace.y += nextPageBounds.height + gap\n\t\t\t\t\tspace.height -= nextPageBounds.height + gap\n\t\t\t\t} else {\n\t\t\t\t\t// split the space into two spaces\n\t\t\t\t\tspaces.push(\n\t\t\t\t\t\tnew Box(\n\t\t\t\t\t\t\tspace.x + (nextPageBounds.width + gap),\n\t\t\t\t\t\t\tspace.y,\n\t\t\t\t\t\t\tspace.width - (nextPageBounds.width + gap),\n\t\t\t\t\t\t\tnextPageBounds.height\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t\tspace.y += nextPageBounds.height + gap\n\t\t\t\t\tspace.height -= nextPageBounds.height + gap\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tconst commonAfter = Box.Common(shapeClustersToPack.map((s) => s.nextPageBounds))\n\t\tconst centerDelta = Vec.Sub(commonBounds.center, commonAfter.center)\n\n\t\tconst changes: TLShapePartial<any>[] = []\n\n\t\tfor (const { shapes, pageBounds, nextPageBounds } of shapeClustersToPack) {\n\t\t\tconst delta = Vec.Sub(nextPageBounds.point, pageBounds.point).add(centerDelta)\n\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tconst shapeDelta = delta.clone()\n\n\t\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\t\tif (parent) {\n\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\tif (parentTransform) shapeDelta.rot(-parentTransform.rotation())\n\t\t\t\t}\n\n\t\t\t\tshapeDelta.add(shape)\n\t\t\t\tchanges.push(this.getChangesToTranslateShape(shape, shapeDelta))\n\t\t\t}\n\t\t}\n\n\t\tif (changes.length) {\n\t\t\tthis.updateShapes(changes)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Align shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.alignShapes([box1, box2], 'left')\n\t * editor.alignShapes(editor.getSelectedShapeIds(), 'left')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to align.\n\t * @param operation - The align operation to apply.\n\t *\n\t * @public\n\t */\n\talignShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'left' | 'center-horizontal' | 'right' | 'top' | 'center-vertical' | 'bottom'\n\t): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t// Always get fresh shapes\n\t\tconst shapesToAlignFirstPass = compact(ids.map((id) => this.getShape(id)))\n\n\t\tconst shapeClustersToAlign: {\n\t\t\tshapes: TLShape[]\n\t\t\tpageBounds: Box\n\t\t}[] = []\n\t\tconst allBounds: Box[] = []\n\t\tconst visited = new Set<TLShapeId>()\n\n\t\tfor (const shape of shapesToAlignFirstPass) {\n\t\t\tif (visited.has(shape.id)) continue\n\t\t\tvisited.add(shape.id)\n\n\t\t\tconst shapePageBounds = this.getShapePageBounds(shape)\n\t\t\tif (!shapePageBounds) continue\n\n\t\t\tif (\n\t\t\t\t!this.getShapeUtil(shape).canBeLaidOut?.(shape, {\n\t\t\t\t\ttype: 'align',\n\t\t\t\t\tshapes: shapesToAlignFirstPass,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// In this implementation, we want to create psuedo-groups out of shapes that\n\t\t\t// are moving together. At the moment shapes only move together if they're connected\n\t\t\t// by arrows. So let's say A -> B -> C -> D and A, B, and C are selected. If we're\n\t\t\t// aligning A, B, and C, then we want these to move together as one unit.\n\n\t\t\tconst shapesMovingTogether = [shape]\n\t\t\tconst boundsOfShapesMovingTogether: Box[] = [shapePageBounds]\n\n\t\t\tthis.collectShapesViaArrowBindings({\n\t\t\t\tbindings: this.getBindingsToShape(shape.id, 'arrow'),\n\t\t\t\tinitialShapes: shapesToAlignFirstPass,\n\t\t\t\tresultShapes: shapesMovingTogether,\n\t\t\t\tresultBounds: boundsOfShapesMovingTogether,\n\t\t\t\tvisited,\n\t\t\t})\n\n\t\t\tconst commonPageBounds = Box.Common(boundsOfShapesMovingTogether)\n\t\t\tif (!commonPageBounds) continue\n\n\t\t\tshapeClustersToAlign.push({\n\t\t\t\tshapes: shapesMovingTogether,\n\t\t\t\tpageBounds: commonPageBounds,\n\t\t\t})\n\n\t\t\tallBounds.push(commonPageBounds)\n\t\t}\n\n\t\tif (shapeClustersToAlign.length < 2) return this\n\n\t\tconst commonBounds = Box.Common(allBounds)\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapeClustersToAlign.forEach(({ shapes, pageBounds }) => {\n\t\t\tconst delta = new Vec()\n\n\t\t\tswitch (operation) {\n\t\t\t\tcase 'top': {\n\t\t\t\t\tdelta.y = commonBounds.minY - pageBounds.minY\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-vertical': {\n\t\t\t\t\tdelta.y = commonBounds.midY - pageBounds.minY - pageBounds.height / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'bottom': {\n\t\t\t\t\tdelta.y = commonBounds.maxY - pageBounds.minY - pageBounds.height\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'left': {\n\t\t\t\t\tdelta.x = commonBounds.minX - pageBounds.minX\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-horizontal': {\n\t\t\t\t\tdelta.x = commonBounds.midX - pageBounds.minX - pageBounds.width / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'right': {\n\t\t\t\t\tdelta.x = commonBounds.maxX - pageBounds.minX - pageBounds.width\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tconst shapeDelta = delta.clone()\n\n\t\t\t\t// If the shape has another shape as its parent, and if the parent has a rotation, we need to rotate the counter-rotate delta\n\t\t\t\t// todo: ensure that the parent isn't being aligned together with its children\n\t\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\t\tif (parent) {\n\t\t\t\t\tconst parentTransform = this.getShapePageTransform(parent)\n\t\t\t\t\tif (parentTransform) shapeDelta.rot(-parentTransform.rotation())\n\t\t\t\t}\n\n\t\t\t\tshapeDelta.add(shape) // add the shape's x and y to the delta\n\t\t\t\tchanges.push(this.getChangesToTranslateShape(shape, shapeDelta))\n\t\t\t}\n\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Distribute shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.distributeShapes([box1, box2], 'horizontal')\n\t * editor.distributeShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to distribute.\n\t * @param operation - Whether to distribute shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tdistributeShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t// always fresh shapes\n\t\tconst shapesToDistributeFirstPass = compact(ids.map((id) => this.getShape(id)))\n\n\t\tconst shapeClustersToDistribute: {\n\t\t\tshapes: TLShape[]\n\t\t\tpageBounds: Box\n\t\t}[] = []\n\n\t\tconst allBounds: Box[] = []\n\t\tconst visited = new Set<TLShapeId>()\n\n\t\tfor (const shape of shapesToDistributeFirstPass) {\n\t\t\tif (visited.has(shape.id)) continue\n\t\t\tvisited.add(shape.id)\n\n\t\t\tconst shapePageBounds = this.getShapePageBounds(shape)\n\t\t\tif (!shapePageBounds) continue\n\n\t\t\tif (\n\t\t\t\t!this.getShapeUtil(shape).canBeLaidOut?.(shape, {\n\t\t\t\t\ttype: 'distribute',\n\t\t\t\t\tshapes: shapesToDistributeFirstPass,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst shapesMovingTogether = [shape]\n\t\t\tconst boundsOfShapesMovingTogether: Box[] = [shapePageBounds]\n\n\t\t\tthis.collectShapesViaArrowBindings({\n\t\t\t\tbindings: this.getBindingsToShape(shape.id, 'arrow'),\n\t\t\t\tinitialShapes: shapesToDistributeFirstPass,\n\t\t\t\tresultShapes: shapesMovingTogether,\n\t\t\t\tresultBounds: boundsOfShapesMovingTogether,\n\t\t\t\tvisited,\n\t\t\t})\n\n\t\t\tconst commonPageBounds = Box.Common(boundsOfShapesMovingTogether)\n\t\t\tif (!commonPageBounds) continue\n\n\t\t\tshapeClustersToDistribute.push({\n\t\t\t\tshapes: shapesMovingTogether,\n\t\t\t\tpageBounds: commonPageBounds,\n\t\t\t})\n\n\t\t\tallBounds.push(commonPageBounds)\n\t\t}\n\n\t\tif (shapeClustersToDistribute.length < 3) return this\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tdim = 'height'\n\t\t}\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tconst first = shapeClustersToDistribute.sort((a, b) => a.pageBounds[min] - b.pageBounds[min])[0]\n\t\tconst last = shapeClustersToDistribute.sort((a, b) => b.pageBounds[max] - a.pageBounds[max])[0]\n\n\t\t// If the first shape group is also the last shape group, distribute without it\n\t\tif (first === last) {\n\t\t\tconst excludedShapeIds = new Set(first.shapes.map((s) => s.id))\n\t\t\treturn this.distributeShapes(\n\t\t\t\tids.filter((id) => !excludedShapeIds.has(id)),\n\t\t\t\toperation\n\t\t\t)\n\t\t}\n\n\t\tconst shapeClustersToMove = shapeClustersToDistribute\n\t\t\t.filter((shape) => shape !== first && shape !== last)\n\t\t\t.sort((a, b) => {\n\t\t\t\tif (a.pageBounds[min] === b.pageBounds[min]) {\n\t\t\t\t\treturn a.shapes[0].id < b.shapes[0].id ? -1 : 1\n\t\t\t\t}\n\t\t\t\treturn a.pageBounds[min] - b.pageBounds[min]\n\t\t\t})\n\n\t\t// The gap is the amount of space \"left over\" between the first and last shape. This can be a negative number if the shapes are overlapping.\n\t\tconst maxFirst = first.pageBounds[max]\n\t\tconst range = last.pageBounds[min] - maxFirst\n\t\tconst summedShapeDimensions = shapeClustersToMove.reduce((acc, s) => acc + s.pageBounds[dim], 0)\n\t\tconst gap = (range - summedShapeDimensions) / (shapeClustersToMove.length + 1)\n\n\t\tfor (let v = maxFirst + gap, i = 0; i < shapeClustersToMove.length; i++) {\n\t\t\tconst { shapes, pageBounds } = shapeClustersToMove[i]\n\t\t\tconst delta = new Vec()\n\t\t\tdelta[val] = v - pageBounds[val]\n\n\t\t\t// If for some reason the new position would be more than the maximum, we need to adjust the delta\n\t\t\t// This will likely throw off some of the other placements but hey, it's better than changing the common bounds\n\t\t\tif (v + pageBounds[dim] > last.pageBounds[max] - 1) {\n\t\t\t\tdelta[val] = last.pageBounds[max] - pageBounds[max] - 1\n\t\t\t}\n\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tconst shapeDelta = delta.clone()\n\n\t\t\t\t// If the shape has another shape as its parent, and if the parent has a rotation, we need to rotate the counter-rotate delta\n\t\t\t\t// todo: ensure that the parent isn't being aligned together with its children\n\t\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\t\tif (parent) {\n\t\t\t\t\tconst parentTransform = this.getShapePageTransform(parent)\n\t\t\t\t\tif (parentTransform) shapeDelta.rot(-parentTransform.rotation())\n\t\t\t\t}\n\n\t\t\t\tshapeDelta.add(shape) // add the shape's x and y to the delta\n\t\t\t\tchanges.push(this.getChangesToTranslateShape(shape, shapeDelta))\n\t\t\t}\n\n\t\t\tv += pageBounds[dim] + gap\n\t\t}\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Stretch shape sizes and positions to fill their common bounding box.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stretchShapes([box1, box2], 'horizontal')\n\t * editor.stretchShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stretch.\n\t * @param operation - Whether to stretch shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tstretchShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly()) return this\n\n\t\t// always fresh shapes, skip anything that isn't rotated 90 deg\n\t\tconst shapesToStretchFirstPass = compact(ids.map((id) => this.getShape(id))).filter(\n\t\t\t(s) => this.getShapePageTransform(s)?.rotation() % (PI / 2) === 0\n\t\t)\n\n\t\tconst shapeClustersToStretch: {\n\t\t\tshapes: TLShape[]\n\t\t\tpageBounds: Box\n\t\t}[] = []\n\n\t\tconst allBounds: Box[] = []\n\t\tconst visited = new Set<TLShapeId>()\n\n\t\tfor (const shape of shapesToStretchFirstPass) {\n\t\t\tif (visited.has(shape.id)) continue\n\t\t\tvisited.add(shape.id)\n\n\t\t\tconst shapePageBounds = this.getShapePageBounds(shape)\n\t\t\tif (!shapePageBounds) continue\n\n\t\t\tconst shapesMovingTogether = [shape]\n\t\t\tconst boundsOfShapesMovingTogether: Box[] = [shapePageBounds]\n\n\t\t\tif (\n\t\t\t\t!this.getShapeUtil(shape).canBeLaidOut?.(shape, {\n\t\t\t\t\ttype: 'stretch',\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tthis.collectShapesViaArrowBindings({\n\t\t\t\tbindings: this.getBindingsToShape(shape.id, 'arrow'),\n\t\t\t\tinitialShapes: shapesToStretchFirstPass,\n\t\t\t\tresultShapes: shapesMovingTogether,\n\t\t\t\tresultBounds: boundsOfShapesMovingTogether,\n\t\t\t\tvisited,\n\t\t\t})\n\n\t\t\tconst commonPageBounds = Box.Common(boundsOfShapesMovingTogether)\n\t\t\tif (!commonPageBounds) continue\n\n\t\t\tshapeClustersToStretch.push({\n\t\t\t\tshapes: shapesMovingTogether,\n\t\t\t\tpageBounds: commonPageBounds,\n\t\t\t})\n\n\t\t\tallBounds.push(commonPageBounds)\n\t\t}\n\n\t\tif (shapeClustersToStretch.length < 2) return this\n\n\t\tconst commonBounds = Box.Common(allBounds)\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tdim = 'height'\n\t\t}\n\n\t\tthis.run(() => {\n\t\t\tshapeClustersToStretch.forEach(({ shapes, pageBounds }) => {\n\t\t\t\tconst localOffset = new Vec()\n\t\t\t\tlocalOffset[val] = commonBounds[min] - pageBounds[min]\n\n\t\t\t\tconst scaleOrigin = pageBounds.center.clone()\n\t\t\t\tscaleOrigin[val] = commonBounds[min]\n\n\t\t\t\tconst scale = new Vec(1, 1)\n\t\t\t\tscale[val] = commonBounds[dim] / pageBounds[dim]\n\n\t\t\t\tfor (const shape of shapes) {\n\t\t\t\t\t// First translate\n\t\t\t\t\tconst shapeLocalOffset = localOffset.clone()\n\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\tif (parentTransform) localOffset.rot(-parentTransform.rotation())\n\t\t\t\t\tshapeLocalOffset.add(shape)\n\t\t\t\t\tconst changes = this.getChangesToTranslateShape(shape, shapeLocalOffset)\n\t\t\t\t\tthis.updateShape(changes)\n\n\t\t\t\t\t// Then resize\n\t\t\t\t\tthis.resizeShape(shape.id, scale, {\n\t\t\t\t\t\tinitialBounds: this.getShapeGeometry(shape).bounds,\n\t\t\t\t\t\tscaleOrigin,\n\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Resize a shape.\n\t *\n\t * @param shape - The shape (or the shape id of the shape) to resize.\n\t * @param scale - The scale factor to apply to the shape.\n\t * @param opts - Additional options.\n\t *\n\t * @public\n\t */\n\tresizeShape(shape: TLShapeId | TLShape, scale: VecLike, opts: TLResizeShapeOptions = {}): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (this.getIsReadonly()) return this\n\n\t\tif (!Number.isFinite(scale.x)) scale = new Vec(1, scale.y)\n\t\tif (!Number.isFinite(scale.y)) scale = new Vec(scale.x, 1)\n\n\t\tconst initialShape = opts.initialShape ?? this.getShape(id)\n\t\tif (!initialShape) return this\n\n\t\tconst scaleOrigin = opts.scaleOrigin ?? this.getShapePageBounds(id)?.center\n\t\tif (!scaleOrigin) return this\n\n\t\tconst pageTransform = opts.initialPageTransform\n\t\t\t? Mat.Cast(opts.initialPageTransform)\n\t\t\t: this.getShapePageTransform(id)\n\t\tif (!pageTransform) return this\n\n\t\tconst pageRotation = pageTransform.rotation()\n\n\t\tif (pageRotation == null) return this\n\n\t\tconst scaleAxisRotation = opts.scaleAxisRotation ?? pageRotation\n\n\t\tconst initialBounds = opts.initialBounds ?? this.getShapeGeometry(id).bounds\n\n\t\tif (!initialBounds) return this\n\n\t\tconst isAspectRatioLocked =\n\t\t\topts.isAspectRatioLocked ?? this.getShapeUtil(initialShape).isAspectRatioLocked(initialShape)\n\n\t\tif (!areAnglesCompatible(pageRotation, scaleAxisRotation)) {\n\t\t\t// shape is awkwardly rotated, keep the aspect ratio locked and adopt the scale factor\n\t\t\t// from whichever axis is being scaled the least, to avoid the shape getting bigger\n\t\t\t// than the bounds of the selection\n\t\t\t// const minScale = Math.min(Math.abs(scale.x), Math.abs(scale.y))\n\t\t\treturn this._resizeUnalignedShape(id, scale, {\n\t\t\t\t...opts,\n\t\t\t\tinitialBounds,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscaleAxisRotation,\n\t\t\t\tinitialPageTransform: pageTransform,\n\t\t\t\tisAspectRatioLocked,\n\t\t\t\tinitialShape,\n\t\t\t})\n\t\t}\n\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tif (isAspectRatioLocked) {\n\t\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\t\tscale = new Vec(scale.x, Math.sign(scale.y) * Math.abs(scale.x))\n\t\t\t} else {\n\t\t\t\tscale = new Vec(Math.sign(scale.x) * Math.abs(scale.y), scale.y)\n\t\t\t}\n\t\t}\n\n\t\tlet didResize = false\n\n\t\tif (util.onResize && util.canResize(initialShape)) {\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPagePoint = this._scalePagePoint(\n\t\t\t\tMat.applyToPoint(pageTransform, new Vec(0, 0)),\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst newLocalPoint = this.getPointInParentSpace(initialShape.id, newPagePoint)\n\n\t\t\t// resize the shape's local bounding box\n\t\t\tconst myScale = new Vec(scale.x, scale.y)\n\t\t\t// the shape is aligned with the rest of the shapes in the selection, but may be\n\t\t\t// 90deg offset from the main rotation of the selection, in which case\n\t\t\t// we need to flip the width and height scale factors\n\t\t\tconst areWidthAndHeightAlignedWithCorrectAxis = approximately(\n\t\t\t\t(pageRotation - scaleAxisRotation) % Math.PI,\n\t\t\t\t0\n\t\t\t)\n\t\t\tmyScale.x = areWidthAndHeightAlignedWithCorrectAxis ? scale.x : scale.y\n\t\t\tmyScale.y = areWidthAndHeightAlignedWithCorrectAxis ? scale.y : scale.x\n\n\t\t\t// adjust initial model for situations where the parent has moved during the resize\n\t\t\t// e.g. groups\n\t\t\tconst initialPagePoint = Mat.applyToPoint(pageTransform, new Vec())\n\n\t\t\t// need to adjust the shape's x and y points in case the parent has moved since start of resizing\n\t\t\tconst { x, y } = this.getPointInParentSpace(initialShape.id, initialPagePoint)\n\n\t\t\tlet workingShape = initialShape\n\t\t\tif (!opts.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tinitialShape,\n\t\t\t\t\tutil.onResizeStart?.(initialShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst resizedShape = util.onResize(\n\t\t\t\t{ ...initialShape, x, y },\n\t\t\t\t{\n\t\t\t\t\tnewPoint: newLocalPoint,\n\t\t\t\t\thandle: opts.dragHandle ?? 'bottom_right',\n\t\t\t\t\t// don't set isSingle to true for children\n\t\t\t\t\tmode: opts.mode ?? 'scale_shape',\n\t\t\t\t\tscaleX: myScale.x,\n\t\t\t\t\tscaleY: myScale.y,\n\t\t\t\t\tinitialBounds,\n\t\t\t\t\tinitialShape,\n\t\t\t\t}\n\t\t\t)\n\n\t\t\tif (resizedShape) {\n\t\t\t\tdidResize = true\n\t\t\t}\n\n\t\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\t\tid,\n\t\t\t\ttype: initialShape.type as any,\n\t\t\t\tx: newLocalPoint.x,\n\t\t\t\ty: newLocalPoint.y,\n\t\t\t\t...resizedShape,\n\t\t\t})\n\n\t\t\tif (!opts.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tworkingShape,\n\t\t\t\t\tutil.onResizeEnd?.(initialShape, workingShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tthis.updateShapes([workingShape])\n\t\t}\n\n\t\tif (!didResize) {\n\t\t\t// reposition shape (rather than resizing it) based on where its resized center would be\n\n\t\t\tconst initialPageCenter = Mat.applyToPoint(pageTransform, initialBounds.center)\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPageCenter = this._scalePagePoint(\n\t\t\t\tinitialPageCenter,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst initialPageCenterInParentSpace = this.getPointInParentSpace(\n\t\t\t\tinitialShape.id,\n\t\t\t\tinitialPageCenter\n\t\t\t)\n\t\t\tconst newPageCenterInParentSpace = this.getPointInParentSpace(initialShape.id, newPageCenter)\n\n\t\t\tconst delta = Vec.Sub(newPageCenterInParentSpace, initialPageCenterInParentSpace)\n\t\t\t// apply the changes to the model\n\t\t\tthis.updateShapes([\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\ttype: initialShape.type as any,\n\t\t\t\t\tx: initialShape.x + delta.x,\n\t\t\t\t\ty: initialShape.y + delta.y,\n\t\t\t\t},\n\t\t\t])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _scalePagePoint(\n\t\tpoint: VecLike,\n\t\tscaleOrigin: VecLike,\n\t\tscale: VecLike,\n\t\tscaleAxisRotation: number\n\t) {\n\t\tconst relativePoint = Vec.RotWith(point, scaleOrigin, -scaleAxisRotation).sub(scaleOrigin)\n\n\t\t// calculate the new point position relative to the scale origin\n\t\tconst newRelativePagePoint = Vec.MulV(relativePoint, scale)\n\n\t\t// and rotate it back to page coords to get the new page point of the resized shape\n\t\tconst destination = Vec.Add(newRelativePagePoint, scaleOrigin).rotWith(\n\t\t\tscaleOrigin,\n\t\t\tscaleAxisRotation\n\t\t)\n\n\t\treturn destination\n\t}\n\n\t/** @internal */\n\tprivate _resizeUnalignedShape(\n\t\tid: TLShapeId,\n\t\tscale: VecLike,\n\t\toptions: {\n\t\t\tinitialBounds: Box\n\t\t\tscaleOrigin: VecLike\n\t\t\tscaleAxisRotation: number\n\t\t\tinitialShape: TLShape\n\t\t\tisAspectRatioLocked: boolean\n\t\t\tinitialPageTransform: MatLike\n\t\t}\n\t) {\n\t\tconst { type } = options.initialShape\n\t\t// If a shape is not aligned with the scale axis we need to treat it differently to avoid skewing.\n\t\t// Instead of skewing we normalize the scale aspect ratio (i.e. keep the same scale magnitude in both axes)\n\t\t// and then after applying the scale to the shape we also rotate it if required and translate it so that it's center\n\t\t// point ends up in the right place.\n\n\t\tconst shapeScale = new Vec(scale.x, scale.y)\n\n\t\t// // make sure we are constraining aspect ratio, and using the smallest scale axis to avoid shapes getting bigger\n\t\t// // than the selection bounding box\n\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\tshapeScale.x = Math.sign(scale.x) * Math.abs(scale.y)\n\t\t} else {\n\t\t\tshapeScale.y = Math.sign(scale.y) * Math.abs(scale.x)\n\t\t}\n\n\t\t// first we can scale the shape about its center point\n\t\tthis.resizeShape(id, shapeScale, {\n\t\t\tinitialShape: options.initialShape,\n\t\t\tinitialBounds: options.initialBounds,\n\t\t\tisAspectRatioLocked: options.isAspectRatioLocked,\n\t\t})\n\n\t\t// then if the shape is flipped in one axis only, we need to apply an extra rotation\n\t\t// to make sure the shape is mirrored correctly\n\t\tif (Math.sign(scale.x) * Math.sign(scale.y) < 0) {\n\t\t\tlet { rotation } = Mat.Decompose(options.initialPageTransform)\n\t\t\trotation -= 2 * rotation\n\t\t\tthis.updateShapes([{ id, type, rotation }])\n\t\t}\n\n\t\t// Next we need to translate the shape so that it's center point ends up in the right place.\n\t\t// To do that we first need to calculate the center point of the shape in the current page space before the scale was applied.\n\t\tconst preScaleShapePageCenter = Mat.applyToPoint(\n\t\t\toptions.initialPageTransform,\n\t\t\toptions.initialBounds.center\n\t\t)\n\n\t\t// And now we scale the center point by the original scale factor\n\t\tconst postScaleShapePageCenter = this._scalePagePoint(\n\t\t\tpreScaleShapePageCenter,\n\t\t\toptions.scaleOrigin,\n\t\t\tscale,\n\t\t\toptions.scaleAxisRotation\n\t\t)\n\n\t\t// now calculate how far away the shape is from where it needs to be\n\t\tconst pageBounds = this.getShapePageBounds(id)!\n\t\tconst pageTransform = this.getShapePageTransform(id)!\n\t\tconst currentPageCenter = pageBounds.center\n\t\tconst shapePageTransformOrigin = pageTransform.point()\n\t\tif (!currentPageCenter || !shapePageTransformOrigin) return this\n\t\tconst pageDelta = Vec.Sub(postScaleShapePageCenter, currentPageCenter)\n\n\t\t// and finally figure out what the shape's new position should be\n\t\tconst postScaleShapePagePoint = Vec.Add(shapePageTransformOrigin, pageDelta)\n\t\tconst { x, y } = this.getPointInParentSpace(id, postScaleShapePagePoint)\n\n\t\tthis.updateShapes([{ id, type, x, y }])\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the initial meta value for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialMetaForShape = (shape) => {\n\t * if (shape.type === 'note') {\n\t * return { createdBy: myCurrentUser.id }\n\t * }\n\t * }\n\t * ```\n\t *\n\t * @param shape - The shape to get the initial meta for.\n\t *\n\t * @public\n\t */\n\tgetInitialMetaForShape(_shape: TLShape): JsonObject {\n\t\treturn {}\n\t}\n\n\t/**\n\t * Get whether the provided shape can be created.\n\t *\n\t * @param shape - The shape or shape IDs to check.\n\t *\n\t * @public\n\t */\n\tcanCreateShape<T extends TLUnknownShape>(\n\t\tshape: OptionalKeys<TLShapePartial<T>, 'id'> | T['id']\n\t): boolean {\n\t\treturn this.canCreateShapes([shape])\n\t}\n\n\t/**\n\t * Get whether the provided shapes can be created.\n\t *\n\t * @param shapes - The shapes or shape IDs to create.\n\t *\n\t * @public\n\t */\n\tcanCreateShapes<T extends TLUnknownShape>(\n\t\tshapes: (T['id'] | OptionalKeys<TLShapePartial<T>, 'id'>)[]\n\t): boolean {\n\t\treturn shapes.length + this.getCurrentPageShapeIds().size <= this.options.maxShapesPerPage\n\t}\n\n\t/**\n\t * Create a single shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShape(myShape)\n\t * editor.createShape({ id: 'box1', type: 'text', props: { richText: toRichText(\"ok\") } })\n\t * ```\n\t *\n\t * @param shape - The shape (or shape partial) to create.\n\t *\n\t * @public\n\t */\n\tcreateShape<T extends TLUnknownShape>(shape: OptionalKeys<TLShapePartial<T>, 'id'>): this {\n\t\tthis.createShapes([shape])\n\t\treturn this\n\t}\n\n\t/**\n\t * Create shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShapes([myShape])\n\t * editor.createShapes([{ id: 'box1', type: 'text', props: { richText: toRichText(\"ok\") } }])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape partials) to create.\n\t *\n\t * @public\n\t */\n\tcreateShapes<T extends TLUnknownShape>(shapes: OptionalKeys<TLShapePartial<T>, 'id'>[]): this {\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.createShapes: must provide an array of shapes or shape partials')\n\t\t}\n\t\tif (this.getIsReadonly()) return this\n\t\tif (shapes.length <= 0) return this\n\n\t\tconst currentPageShapeIds = this.getCurrentPageShapeIds()\n\n\t\tconst maxShapesReached =\n\t\t\tshapes.length + currentPageShapeIds.size > this.options.maxShapesPerPage\n\n\t\tif (maxShapesReached) {\n\t\t\t// can't create more shapes than fit on the page\n\t\t\talertMaxShapes(this)\n\t\t\t// todo: throw an error here? Otherwise we'll need to check every time whether the shapes were actually created\n\t\t\treturn this\n\t\t}\n\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\n\t\tthis.run(() => {\n\t\t\t// 1. Parents\n\n\t\t\t// Make sure that each partial will become the child of either the\n\t\t\t// page or another shape that exists (or that will exist) in this page.\n\n\t\t\t// find last parent id\n\t\t\tconst currentPageShapesSorted = this.getCurrentPageShapesSorted()\n\n\t\t\tconst partials = shapes.map((partial) => {\n\t\t\t\tif (!partial.id) {\n\t\t\t\t\tpartial = { id: createShapeId(), ...partial }\n\t\t\t\t}\n\n\t\t\t\t// If the partial does not provide the parentId OR if the provided\n\t\t\t\t// parentId is NOT in the store AND NOT among the other shapes being\n\t\t\t\t// created, then we need to find a parent for the shape. This can be\n\t\t\t\t// another shape that exists under that point and which can receive\n\t\t\t\t// children of the creating shape's type, or else the page itself.\n\t\t\t\tif (\n\t\t\t\t\t!partial.parentId ||\n\t\t\t\t\t!(this.store.has(partial.parentId) || shapes.some((p) => p.id === partial.parentId))\n\t\t\t\t) {\n\t\t\t\t\tlet parentId: TLParentId = this.getFocusedGroupId()\n\n\t\t\t\t\tconst isPositioned = partial.x !== undefined && partial.y !== undefined\n\n\t\t\t\t\t// If the shape has been explicitly positioned, we'll try to find a parent at\n\t\t\t\t\t// that position. If not, we'll assume the user isn't deliberately placing the\n\t\t\t\t\t// shape and the positioning will be handled later by another system.\n\t\t\t\t\tif (isPositioned) {\n\t\t\t\t\t\tfor (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {\n\t\t\t\t\t\t\tconst parent = currentPageShapesSorted[i]\n\t\t\t\t\t\t\tconst util = this.getShapeUtil(parent)\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tutil.canReceiveNewChildrenOfType(parent, partial.type) &&\n\t\t\t\t\t\t\t\t!this.isShapeHidden(parent) &&\n\t\t\t\t\t\t\t\tthis.isPointInShape(\n\t\t\t\t\t\t\t\t\tparent,\n\t\t\t\t\t\t\t\t\t// If no parent is provided, then we can treat the\n\t\t\t\t\t\t\t\t\t// shape's provided x/y as being in the page's space.\n\t\t\t\t\t\t\t\t\t{ x: partial.x ?? 0, y: partial.y ?? 0 },\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tmargin: 0,\n\t\t\t\t\t\t\t\t\t\thitInside: true,\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tparentId = parent.id\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst prevParentId = partial.parentId\n\n\t\t\t\t\t// a shape cannot be its own parent. This was a rare issue with frames/groups in the syncFuzz tests.\n\t\t\t\t\tif (parentId === partial.id) {\n\t\t\t\t\t\tparentId = focusedGroupId\n\t\t\t\t\t}\n\n\t\t\t\t\t// If the parentid has changed...\n\t\t\t\t\tif (parentId !== prevParentId) {\n\t\t\t\t\t\tpartial = { ...partial }\n\n\t\t\t\t\t\tpartial.parentId = parentId\n\n\t\t\t\t\t\t// If the parent is a shape (rather than a page) then insert the\n\t\t\t\t\t\t// shapes into the shape's children. Adjust the point and page rotation to be\n\t\t\t\t\t\t// preserved relative to the parent.\n\t\t\t\t\t\tif (isShapeId(parentId)) {\n\t\t\t\t\t\t\tconst point = this.getPointInShapeSpace(this.getShape(parentId)!, {\n\t\t\t\t\t\t\t\tx: partial.x ?? 0,\n\t\t\t\t\t\t\t\ty: partial.y ?? 0,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tpartial.x = point.x\n\t\t\t\t\t\t\tpartial.y = point.y\n\t\t\t\t\t\t\tpartial.rotation =\n\t\t\t\t\t\t\t\t-this.getShapePageTransform(parentId)!.rotation() + (partial.rotation ?? 0)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn partial\n\t\t\t})\n\n\t\t\t// 2. Indices\n\n\t\t\t// Get the highest index among the parents of each of the\n\t\t\t// the shapes being created; we'll increment from there.\n\n\t\t\tconst parentIndices = new Map<TLParentId, IndexKey>()\n\n\t\t\tconst shapeRecordsToCreate: TLShape[] = []\n\n\t\t\tconst { opacityForNextShape } = this.getInstanceState()\n\n\t\t\tfor (const partial of partials) {\n\t\t\t\tconst util = this.getShapeUtil(partial as TLShapePartial)\n\n\t\t\t\t// If an index is not explicitly provided, then add the\n\t\t\t\t// shapes to the top of their parents' children; using the\n\t\t\t\t// value in parentsMappedToIndex, get the index above, use it,\n\t\t\t\t// and set it back to parentsMappedToIndex for next time.\n\t\t\t\tlet index = partial.index\n\n\t\t\t\tif (!index) {\n\t\t\t\t\t// Hello bug-seeker: have you just created a frame and then a shape\n\t\t\t\t\t// and found that the shape is automatically the child of the frame?\n\t\t\t\t\t// this is the reason why! It would be harder to have each shape specify\n\t\t\t\t\t// the frame as the parent when creating a shape inside of a frame, so\n\t\t\t\t\t// we do it here.\n\t\t\t\t\tconst parentId = partial.parentId ?? focusedGroupId\n\n\t\t\t\t\tif (!parentIndices.has(parentId)) {\n\t\t\t\t\t\tparentIndices.set(parentId, this.getHighestIndexForParent(parentId))\n\t\t\t\t\t}\n\t\t\t\t\tindex = parentIndices.get(parentId)!\n\t\t\t\t\tparentIndices.set(parentId, getIndexAbove(index))\n\t\t\t\t}\n\n\t\t\t\t// The initial props starts as the shape utility's default props\n\t\t\t\tconst initialProps = util.getDefaultProps()\n\n\t\t\t\t// We then look up each key in the tab state's styles; and if it's there,\n\t\t\t\t// we use the value from the tab state's styles instead of the default.\n\t\t\t\tfor (const [style, propKey] of this.styleProps[partial.type]) {\n\t\t\t\t\t;(initialProps as any)[propKey] = this.getStyleForNextShape(style)\n\t\t\t\t}\n\n\t\t\t\t// When we create the shape, take in the partial (the props coming into the\n\t\t\t\t// function) and merge it with the default props.\n\t\t\t\tlet shapeRecordToCreate = (\n\t\t\t\t\tthis.store.schema.types.shape as RecordType<\n\t\t\t\t\t\tTLShape,\n\t\t\t\t\t\t'type' | 'props' | 'index' | 'parentId'\n\t\t\t\t\t>\n\t\t\t\t).create({\n\t\t\t\t\t...partial,\n\t\t\t\t\tindex,\n\t\t\t\t\topacity: partial.opacity ?? opacityForNextShape,\n\t\t\t\t\tparentId: partial.parentId ?? focusedGroupId,\n\t\t\t\t\tprops: 'props' in partial ? { ...initialProps, ...partial.props } : initialProps,\n\t\t\t\t})\n\n\t\t\t\tif (shapeRecordToCreate.index === undefined) {\n\t\t\t\t\tthrow Error('no index!')\n\t\t\t\t}\n\n\t\t\t\tconst next = this.getShapeUtil(shapeRecordToCreate).onBeforeCreate?.(shapeRecordToCreate)\n\n\t\t\t\tif (next) {\n\t\t\t\t\tshapeRecordToCreate = next\n\t\t\t\t}\n\n\t\t\t\tshapeRecordsToCreate.push(shapeRecordToCreate)\n\t\t\t}\n\n\t\t\t// Add meta properties, if any, to the shapes\n\t\t\tshapeRecordsToCreate.forEach((shape) => {\n\t\t\t\tshape.meta = {\n\t\t\t\t\t...this.getInitialMetaForShape(shape),\n\t\t\t\t\t...shape.meta,\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tthis.emit('created-shapes', shapeRecordsToCreate)\n\t\t\tthis.emit('edit')\n\t\t\tthis.store.put(shapeRecordsToCreate)\n\t\t})\n\n\t\treturn this\n\t}\n\n\tprivate animatingShapes = new Map<TLShapeId, string>()\n\n\t/**\n\t * Animate a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 })\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 }, { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t * @param opts - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShape(\n\t\tpartial: TLShapePartial | null | undefined,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\treturn this.animateShapes([partial], opts)\n\t}\n\n\t/**\n\t * Animate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }])\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }], { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t * @param opts - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShapes(\n\t\tpartials: (TLShapePartial | null | undefined)[],\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\tif (!opts.animation) return this\n\t\tconst { duration = 500, easing = EASINGS.linear } = opts.animation\n\n\t\tconst animationId = uniqueId()\n\n\t\tlet remaining = duration\n\t\tlet t: number\n\n\t\tinterface ShapeAnimation {\n\t\t\tstart: TLShape\n\t\t\tend: TLShape\n\t\t}\n\n\t\tconst animations: ShapeAnimation[] = []\n\n\t\tlet partial: TLShapePartial | null | undefined, result: ShapeAnimation\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tpartial = partials[i]\n\t\t\tif (!partial) continue\n\n\t\t\tconst shape = this.getShape(partial.id)!\n\t\t\tif (!shape) continue\n\n\t\t\tresult = {\n\t\t\t\tstart: structuredClone(shape),\n\t\t\t\tend: applyPartialToRecordWithProps(structuredClone(shape), partial),\n\t\t\t}\n\n\t\t\tanimations.push(result)\n\t\t\tthis.animatingShapes.set(shape.id, animationId)\n\t\t}\n\n\t\tconst handleTick = (elapsed: number) => {\n\t\t\tremaining -= elapsed\n\n\t\t\tif (remaining < 0) {\n\t\t\t\tconst { animatingShapes } = this\n\t\t\t\tconst partialsToUpdate = partials.filter(\n\t\t\t\t\t(p) => p && animatingShapes.get(p.id) === animationId\n\t\t\t\t)\n\t\t\t\tif (partialsToUpdate.length) {\n\t\t\t\t\t// the regular update shapes also removes the shape from\n\t\t\t\t\t// the animating shapes set\n\t\t\t\t\tthis.updateShapes(partialsToUpdate)\n\t\t\t\t}\n\n\t\t\t\tthis.off('tick', handleTick)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tt = easing(1 - remaining / duration)\n\n\t\t\tconst { animatingShapes } = this\n\n\t\t\tconst updates: TLShapePartial[] = []\n\n\t\t\tlet animationIdForShape: string | undefined\n\t\t\tfor (let i = 0, n = animations.length; i < n; i++) {\n\t\t\t\tconst { start, end } = animations[i]\n\t\t\t\t// Is the animation for this shape still active?\n\t\t\t\tanimationIdForShape = animatingShapes.get(start.id)\n\t\t\t\tif (animationIdForShape !== animationId) continue\n\n\t\t\t\tupdates.push({\n\t\t\t\t\t...end,\n\t\t\t\t\tx: start.x + (end.x - start.x) * t,\n\t\t\t\t\ty: start.y + (end.y - start.y) * t,\n\t\t\t\t\topacity: start.opacity + (end.opacity - start.opacity) * t,\n\t\t\t\t\trotation: start.rotation + (end.rotation - start.rotation) * t,\n\t\t\t\t\tprops: this.getShapeUtil(end).getInterpolatedProps?.(start, end, t) ?? end.props,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// The _updateShapes method does NOT remove the\n\t\t\t// shapes from the animated shapes set\n\t\t\tthis._updateShapes(updates)\n\t\t}\n\n\t\tthis.on('tick', handleTick)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a group containing the provided shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.groupShapes([myShape, myOtherShape])\n\t * editor.groupShapes([myShape, myOtherShape], { groupId: myGroupId, select: false })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to group. Defaults to the selected shapes.\n\t * @param opts - An options object.\n\t *\n\t * @public\n\t */\n\tgroupShapes(shapes: TLShape[], opts?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(ids: TLShapeId[], opts?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\topts = {} as Partial<{ groupId: TLShapeId; select: boolean }>\n\t): this {\n\t\tconst { groupId = createShapeId(), select = true } = opts\n\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.groupShapes: must provide an array of shapes or shape ids')\n\t\t}\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes.map((s) => (s as TLShape).id) as TLShapeId[])\n\n\t\tif (ids.length <= 1) return this\n\n\t\tconst shapesToGroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\t\tconst sortedShapeIds = shapesToGroup.sort(sortByIndex).map((s) => s.id)\n\t\tconst pageBounds = Box.Common(compact(shapesToGroup.map((id) => this.getShapePageBounds(id))))\n\n\t\tconst { x, y } = pageBounds.point\n\n\t\tconst parentId = this.findCommonAncestor(shapesToGroup) ?? this.getCurrentPageId()\n\n\t\t// Only group when the select tool is active\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\n\t\t// If not already in idle, cancel the current interaction (get back to idle)\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// Find all the shapes that have the same parentId, and use the highest index.\n\t\tconst shapesWithRootParent = shapesToGroup\n\t\t\t.filter((shape) => shape.parentId === parentId)\n\t\t\t.sort(sortByIndex)\n\n\t\tconst highestIndex = shapesWithRootParent[shapesWithRootParent.length - 1]?.index\n\n\t\tthis.run(() => {\n\t\t\tthis.createShapes<TLGroupShape>([\n\t\t\t\t{\n\t\t\t\t\tid: groupId,\n\t\t\t\t\ttype: 'group',\n\t\t\t\t\tparentId,\n\t\t\t\t\tindex: highestIndex,\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\topacity: 1,\n\t\t\t\t\tprops: {},\n\t\t\t\t},\n\t\t\t])\n\t\t\tthis.reparentShapes(sortedShapeIds, groupId)\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the grouped shapes' children are selected\n\t\t\t\tthis.select(groupId)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Ungroup some shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.ungroupShapes([myGroup, myOtherGroup])\n\t * editor.ungroupShapes([myGroup], { select: false })\n\t * ```\n\t *\n\t * @param shapes - The group shapes (or shape ids) to ungroup.\n\t * @param opts - An options object.\n\t *\n\t * @public\n\t */\n\tungroupShapes(ids: TLShapeId[], opts?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShape[], opts?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShapeId[] | TLShape[], opts = {} as Partial<{ select: boolean }>) {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst { select = true } = opts\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tconst shapesToUngroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\n\t\tif (shapesToUngroup.length === 0) return this\n\n\t\t// todo: the editor shouldn't know about the select tool, move to group / ungroup actions\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// The ids of the selected shapes after ungrouping;\n\t\t// these include all of the grouped shapes children,\n\t\t// plus any shapes that were selected apart from the groups.\n\t\tconst idsToSelect = new Set<TLShapeId>()\n\n\t\t// Get all groups in the selection\n\t\tconst groups: TLGroupShape[] = []\n\n\t\tshapesToUngroup.forEach((shape) => {\n\t\t\tif (this.isShapeOfType<TLGroupShape>(shape, 'group')) {\n\t\t\t\tgroups.push(shape)\n\t\t\t} else {\n\t\t\t\tidsToSelect.add(shape.id)\n\t\t\t}\n\t\t})\n\n\t\tif (groups.length === 0) return this\n\n\t\tthis.run(() => {\n\t\t\tlet group: TLGroupShape\n\n\t\t\tfor (let i = 0, n = groups.length; i < n; i++) {\n\t\t\t\tgroup = groups[i]\n\t\t\t\tconst childIds = this.getSortedChildIdsForParent(group.id)\n\n\t\t\t\tfor (let j = 0, n = childIds.length; j < n; j++) {\n\t\t\t\t\tidsToSelect.add(childIds[j])\n\t\t\t\t}\n\n\t\t\t\tthis.reparentShapes(childIds, group.parentId, group.index)\n\t\t\t}\n\n\t\t\tthis.deleteShapes(groups.map((group) => group.id))\n\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the ungrouped shapes' children are selected\n\t\t\t\tthis.select(...idsToSelect)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a shape using a partial of the shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShape({ id: 'box1', type: 'geo', props: { w: 100, h: 100 } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t *\n\t * @public\n\t */\n\tupdateShape<T extends TLUnknownShape>(partial: TLShapePartial<T> | null | undefined) {\n\t\tthis.updateShapes([partial])\n\t\treturn this\n\t}\n\n\t/**\n\t * Update shapes using partials of each shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShapes([{ id: 'box1', type: 'geo', props: { w: 100, h: 100 } }])\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t *\n\t * @public\n\t */\n\tupdateShapes<T extends TLUnknownShape>(partials: (TLShapePartial<T> | null | undefined)[]) {\n\t\tconst compactedPartials: TLShapePartial<T>[] = Array(partials.length)\n\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tconst partial = partials[i]\n\t\t\tif (!partial) continue\n\t\t\t// Get the current shape referenced by the partial\n\t\t\tconst shape = this.getShape(partial.id)\n\t\t\tif (!shape) continue\n\n\t\t\t// If we're \"forcing\" the update, then we'll update the shape\n\t\t\t// regardless of whether it / its ancestor is locked\n\t\t\tif (!this._shouldIgnoreShapeLock) {\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\t// If the shape itself is locked (even if one of its ancestors is\n\t\t\t\t\t// also locked) then only allow an update that unlocks the shape.\n\t\t\t\t\tif (!(Object.hasOwn(partial, 'isLocked') && !partial.isLocked)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else if (this.isShapeOrAncestorLocked(shape)) {\n\t\t\t\t\t// If the shape itself is unlocked, and any of the shape's\n\t\t\t\t\t// ancestors are locked then we'll skip the update\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove any animating shapes from the list of partials\n\t\t\tthis.animatingShapes.delete(partial.id)\n\n\t\t\tcompactedPartials.push(partial)\n\t\t}\n\n\t\tthis._updateShapes(compactedPartials)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateShapes(_partials: (TLShapePartial | null | undefined)[]) {\n\t\tif (this.getIsReadonly()) return\n\n\t\tthis.run(() => {\n\t\t\tconst updates = []\n\n\t\t\tlet shape: TLShape | undefined\n\t\t\tlet updated: TLShape\n\n\t\t\tfor (let i = 0, n = _partials.length; i < n; i++) {\n\t\t\t\tconst partial = _partials[i]\n\t\t\t\t// Skip nullish partials (sometimes created by map fns returning undefined)\n\t\t\t\tif (!partial) continue\n\n\t\t\t\t// Get the current shape referenced by the partial\n\t\t\t\t// If there is no current shape, we'll skip this update\n\t\t\t\tshape = this.getShape(partial.id)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\t// Get the updated version of the shape\n\t\t\t\t// If the update had no effect, we'll skip this update\n\t\t\t\tupdated = applyPartialToRecordWithProps(shape, partial)\n\t\t\t\tif (updated === shape) continue\n\n\t\t\t\t//if any shape has an onBeforeUpdate handler, call it and, if the handler returns a\n\t\t\t\t// new shape, replace the old shape with the new one. This is used for example when\n\t\t\t\t// repositioning a text shape based on its new text content.\n\t\t\t\tupdated = this.getShapeUtil(shape).onBeforeUpdate?.(shape, updated) ?? updated\n\n\t\t\t\tupdates.push(updated)\n\t\t\t}\n\n\t\t\tthis.emit('edited-shapes', updates)\n\t\t\tthis.emit('edit')\n\t\t\tthis.store.put(updates)\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _getUnlockedShapeIds(ids: TLShapeId[]): TLShapeId[] {\n\t\treturn ids.filter((id) => !this.getShape(id)?.isLocked)\n\t}\n\n\t/**\n\t * Delete shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShapes(['box1', 'box2'])\n\t * ```\n\t *\n\t * @param ids - The ids of the shapes to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShapes(ids: TLShapeId[]): this\n\tdeleteShapes(shapes: TLShape[]): this\n\tdeleteShapes(_ids: TLShapeId[] | TLShape[]): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tif (!Array.isArray(_ids)) {\n\t\t\tthrow Error('Editor.deleteShapes: must provide an array of shapes or shapeIds')\n\t\t}\n\n\t\tconst shapeIds =\n\t\t\ttypeof _ids[0] === 'string' ? (_ids as TLShapeId[]) : (_ids as TLShape[]).map((s) => s.id)\n\n\t\t// Normally we don't want to delete locked shapes, but if the force option is set, we'll delete them anyway\n\t\tconst shapeIdsToDelete = this._shouldIgnoreShapeLock\n\t\t\t? shapeIds\n\t\t\t: this._getUnlockedShapeIds(shapeIds)\n\n\t\tif (shapeIdsToDelete.length === 0) return this\n\n\t\t// We also need to delete these shapes' descendants\n\t\tconst allShapeIdsToDelete = new Set<TLShapeId>(shapeIdsToDelete)\n\n\t\tfor (const id of shapeIdsToDelete) {\n\t\t\tthis.visitDescendants(id, (childId) => {\n\t\t\t\tallShapeIdsToDelete.add(childId)\n\t\t\t})\n\t\t}\n\n\t\tthis.emit('deleted-shapes', [...allShapeIdsToDelete])\n\t\tthis.emit('edit')\n\t\treturn this.run(() => this.store.remove([...allShapeIdsToDelete]))\n\t}\n\n\t/**\n\t * Delete a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShape(shape.id)\n\t * ```\n\t *\n\t * @param id - The id of the shape to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShape(id: TLShapeId): this\n\tdeleteShape(shape: TLShape): this\n\tdeleteShape(_id: TLShapeId | TLShape) {\n\t\tthis.deleteShapes([typeof _id === 'string' ? _id : _id.id])\n\t\treturn this\n\t}\n\n\t/* --------------------- Styles --------------------- */\n\n\t/**\n\t * Get all the current styles among the users selected shapes\n\t *\n\t * @internal\n\t */\n\tprivate _extractSharedStyles(shape: TLShape, sharedStyleMap: SharedStyleMap) {\n\t\tif (this.isShapeOfType<TLGroupShape>(shape, 'group')) {\n\t\t\t// For groups, ignore the styles of the group shape and instead include the styles of the\n\t\t\t// group's children. These are the shapes that would have their styles changed if the\n\t\t\t// user called `setStyle` on the current selection.\n\t\t\tconst childIds = this._parentIdsToChildIds.get()[shape.id]\n\t\t\tif (!childIds) return\n\n\t\t\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\t\t\tthis._extractSharedStyles(this.getShape(childIds[i])!, sharedStyleMap)\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const [style, propKey] of this.styleProps[shape.type]) {\n\t\t\t\tsharedStyleMap.applyValue(style, getOwnProperty(shape.props, propKey))\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * A derived map containing all current styles among the user's selected shapes.\n\t *\n\t * @internal\n\t */\n\t@computed\n\tprivate _getSelectionSharedStyles(): ReadonlySharedStyleMap {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tconst sharedStyles = new SharedStyleMap()\n\t\tfor (const selectedShape of selectedShapes) {\n\t\t\tthis._extractSharedStyles(selectedShape, sharedStyles)\n\t\t}\n\n\t\treturn sharedStyles\n\t}\n\n\t/**\n\t * Get the style for the next shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getStyleForNextShape(DefaultColorStyle)\n\t * ```\n\t *\n\t * @param style - The style to get.\n\t *\n\t * @public */\n\tgetStyleForNextShape<T>(style: StyleProp<T>): T {\n\t\tconst value = this.getInstanceState().stylesForNextShape[style.id]\n\t\treturn value === undefined ? style.defaultValue : (value as T)\n\t}\n\n\tgetShapeStyleIfExists<T>(shape: TLShape, style: StyleProp<T>): T | undefined {\n\t\tconst styleKey = this.styleProps[shape.type].get(style)\n\t\tif (styleKey === undefined) return undefined\n\t\treturn getOwnProperty(shape.props, styleKey) as T | undefined\n\t}\n\n\t/**\n\t * A map of all the current styles either in the current selection, or that are relevant to the\n\t * current tool.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getSharedStyles().get(DefaultColorStyle)\n\t * if (color && color.type === 'shared') {\n\t * print('All selected shapes have the same color:', color.value)\n\t * }\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed<ReadonlySharedStyleMap>({ isEqual: (a, b) => a.equals(b) })\n\tgetSharedStyles(): ReadonlySharedStyleMap {\n\t\t// If we're in selecting and if we have a selection, return the shared styles from the\n\t\t// current selection\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\treturn this._getSelectionSharedStyles()\n\t\t}\n\n\t\t// If the current tool is associated with a shape, return the styles for that shape.\n\t\t// Otherwise, just return an empty map.\n\t\tconst currentTool = this.root.getCurrent()!\n\t\tconst styles = new SharedStyleMap()\n\n\t\tif (!currentTool) return styles\n\n\t\tif (currentTool.shapeType) {\n\t\t\tif (\n\t\t\t\tcurrentTool.shapeType === 'frame' &&\n\t\t\t\t!(this.getShapeUtil('frame')!.options as any).showColors\n\t\t\t) {\n\t\t\t\tfor (const style of this.styleProps[currentTool.shapeType].keys()) {\n\t\t\t\t\tif (style.id === 'tldraw:color') continue\n\t\t\t\t\tstyles.applyValue(style, this.getStyleForNextShape(style))\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (const style of this.styleProps[currentTool.shapeType].keys()) {\n\t\t\t\t\tstyles.applyValue(style, this.getStyleForNextShape(style))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn styles\n\t}\n\n\t/**\n\t * Get the currently selected shared opacity.\n\t * If any shapes are selected, this returns the shared opacity of the selected shapes.\n\t * Otherwise, this returns the chosen opacity for the next shape.\n\t *\n\t * @public\n\t */\n\t@computed getSharedOpacity(): SharedStyle<number> {\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\tconst shapesToCheck: TLShape[] = []\n\t\t\tconst addShape = (shapeId: TLShapeId) => {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) return\n\t\t\t\t// For groups, ignore the opacity of the group shape and instead include\n\t\t\t\t// the opacity of the group's children. These are the shapes that would have\n\t\t\t\t// their opacity changed if the user called `setOpacity` on the current selection.\n\t\t\t\tif (this.isShapeOfType<TLGroupShape>(shape, 'group')) {\n\t\t\t\t\tfor (const childId of this.getSortedChildIdsForParent(shape.id)) {\n\t\t\t\t\t\taddShape(childId)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToCheck.push(shape)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const shapeId of this.getSelectedShapeIds()) {\n\t\t\t\taddShape(shapeId)\n\t\t\t}\n\n\t\t\tlet opacity: number | null = null\n\t\t\tfor (const shape of shapesToCheck) {\n\t\t\t\tif (opacity === null) {\n\t\t\t\t\topacity = shape.opacity\n\t\t\t\t} else if (opacity !== shape.opacity) {\n\t\t\t\t\treturn { type: 'mixed' }\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (opacity !== null) return { type: 'shared', value: opacity }\n\t\t}\n\t\treturn { type: 'shared', value: this.getInstanceState().opacityForNextShape }\n\t}\n\n\t/**\n\t * Set the opacity for the next shapes. This will effect subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForNextShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t * @param historyOptions - The history options for the change.\n\t */\n\tsetOpacityForNextShapes(opacity: number, historyOptions?: TLHistoryBatchOptions): this {\n\t\tthis.updateInstanceState({ opacityForNextShape: opacity }, historyOptions)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current opacity. This will effect any selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForSelectedShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t */\n\tsetOpacityForSelectedShapes(opacity: number): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst shapesToUpdate: TLShape[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType<TLGroupShape>(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToUpdate.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const id of selectedShapes) {\n\t\t\t\taddShapeById(id)\n\t\t\t}\n\n\t\t\tthis.updateShapes(\n\t\t\t\tshapesToUpdate.map((shape) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\topacity,\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp} for the next shapes. This change will be applied to subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red')\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red', { ephemeral: true })\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t * @param historyOptions - The history options for the change.\n\t *\n\t * @public\n\t */\n\tsetStyleForNextShapes<T>(\n\t\tstyle: StyleProp<T>,\n\t\tvalue: T,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tconst stylesForNextShape = this.getInstanceState().stylesForNextShape\n\n\t\tthis.updateInstanceState(\n\t\t\t{ stylesForNextShape: { ...stylesForNextShape, [style.id]: value } },\n\t\t\thistoryOptions\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp}. This change will be applied to the currently selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForSelectedShapes(DefaultColorStyle, 'red')\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t *\n\t * @public\n\t */\n\tsetStyleForSelectedShapes<S extends StyleProp<any>>(style: S, value: StylePropValue<S>): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst updates: {\n\t\t\t\tutil: ShapeUtil\n\t\t\t\toriginalShape: TLShape\n\t\t\t\tupdatePartial: TLShapePartial\n\t\t\t}[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType<TLGroupShape>(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape.id)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\tconst stylePropKey = this.styleProps[shape.type].get(style)\n\t\t\t\t\tif (stylePropKey) {\n\t\t\t\t\t\tconst shapePartial: TLShapePartial = {\n\t\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\t\tprops: { [stylePropKey]: value },\n\t\t\t\t\t\t}\n\t\t\t\t\t\tupdates.push({\n\t\t\t\t\t\t\tutil,\n\t\t\t\t\t\t\toriginalShape: shape,\n\t\t\t\t\t\t\tupdatePartial: shapePartial,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const shape of selectedShapes) {\n\t\t\t\taddShapeById(shape)\n\t\t\t}\n\n\t\t\tthis.updateShapes(updates.map(({ updatePartial }) => updatePartial))\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/* --------------------- Content -------------------- */\n\n\t/** @internal */\n\texternalAssetContentHandlers: {\n\t\t[K in TLExternalAsset['type']]: {\n\t\t\t[Key in K]: null | ((info: TLExternalAsset & { type: Key }) => Promise<TLAsset | undefined>)\n\t\t}[K]\n\t} = {\n\t\tfile: null,\n\t\turl: null,\n\t}\n\n\t/** @internal */\n\tprivate readonly temporaryAssetPreview = new Map<TLAssetId, string>()\n\n\t/**\n\t * Register an external asset handler. This handler will be called when the editor needs to\n\t * create an asset for some external content, like an image/video file or a bookmark URL. For\n\t * example, the 'file' type handler will be called when a user drops an image onto the canvas.\n\t *\n\t * The handler should extract any relevant metadata for the asset, upload it to blob storage\n\t * using {@link Editor.uploadAsset} if needed, and return the asset with the metadata & uploaded\n\t * URL.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalAssetHandler('file', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalAssetHandler<T extends TLExternalAsset['type']>(\n\t\ttype: T,\n\t\thandler: null | ((info: TLExternalAsset & { type: T }) => Promise<TLAsset>)\n\t): this {\n\t\tthis.externalAssetContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Register a temporary preview of an asset. This is useful for showing a ghost image of\n\t * something that is being uploaded. Retrieve the placeholder with\n\t * {@link Editor.getTemporaryAssetPreview}. Placeholders last for 3 minutes by default, but this\n\t * can be configured using\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createTemporaryAssetPreview(assetId, file)\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t * @param file - The raw file.\n\t *\n\t * @public\n\t */\n\tcreateTemporaryAssetPreview(assetId: TLAssetId, file: File) {\n\t\tif (this.temporaryAssetPreview.has(assetId)) {\n\t\t\treturn this.temporaryAssetPreview.get(assetId)\n\t\t}\n\n\t\tconst objectUrl = URL.createObjectURL(file)\n\t\tthis.temporaryAssetPreview.set(assetId, objectUrl)\n\n\t\t// eslint-disable-next-line no-restricted-globals -- we always want to revoke the asset and object URL\n\t\tsetTimeout(() => {\n\t\t\tthis.temporaryAssetPreview.delete(assetId)\n\t\t\tURL.revokeObjectURL(objectUrl)\n\t\t}, this.options.temporaryAssetPreviewLifetimeMs)\n\n\t\treturn objectUrl\n\t}\n\n\t/**\n\t * Get temporary preview of an asset. This is useful for showing a ghost\n\t * image of something that is being uploaded.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getTemporaryAssetPreview('someId')\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t *\n\t * @public\n\t */\n\tgetTemporaryAssetPreview(assetId: TLAssetId) {\n\t\treturn this.temporaryAssetPreview.get(assetId)\n\t}\n\n\t/**\n\t * Get an asset for an external asset content type.\n\t *\n\t * @example\n\t * ```ts\n\t * const asset = await editor.getAssetForExternalContent({ type: 'file', file: myFile })\n\t * const asset = await editor.getAssetForExternalContent({ type: 'url', url: myUrl })\n\t * ```\n\t *\n\t * @param info - Info about the external content.\n\t * @returns The asset.\n\t */\n\tasync getAssetForExternalContent(info: TLExternalAsset): Promise<TLAsset | undefined> {\n\t\treturn await this.externalAssetContentHandlers[info.type]?.(info as any)\n\t}\n\n\thasExternalAssetHandler(type: TLExternalAsset['type']): boolean {\n\t\treturn !!this.externalAssetContentHandlers[type]\n\t}\n\n\t/** @internal */\n\texternalContentHandlers: {\n\t\t[K in TLExternalContent<any>['type']]: {\n\t\t\t[Key in K]: null | ((info: Extract<TLExternalContent<any>, { type: Key }>) => void)\n\t\t}[K]\n\t} = {\n\t\ttext: null,\n\t\tfiles: null,\n\t\t'file-replace': null,\n\t\tembed: null,\n\t\t'svg-text': null,\n\t\turl: null,\n\t\ttldraw: null,\n\t\texcalidraw: null,\n\t}\n\n\t/**\n\t * Register an external content handler. This handler will be called when the editor receives\n\t * external content of the provided type. For example, the 'image' type handler will be called\n\t * when a user drops an image onto the canvas.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler('text', myHandler)\n\t * ```\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler<'embed', MyEmbedType>('embed', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalContentHandler<T extends TLExternalContent<E>['type'], E>(\n\t\ttype: T,\n\t\thandler:\n\t\t\t| null\n\t\t\t| ((\n\t\t\t\t\tinfo: T extends TLExternalContent<E>['type']\n\t\t\t\t\t\t? Extract<TLExternalContent<E>, { type: T }>\n\t\t\t\t\t\t: TLExternalContent<E>\n\t\t\t ) => void)\n\t): this {\n\t\tthis.externalContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Handle external content, such as files, urls, embeds, or plain text which has been put into the app, for example by pasting external text or dropping external images onto canvas.\n\t *\n\t * @param info - Info about the external content.\n\t * @param opts - Options for handling external content, including force flag to bypass readonly checks.\n\t */\n\tasync putExternalContent<E>(\n\t\tinfo: TLExternalContent<E>,\n\t\topts = {} as { force?: boolean }\n\t): Promise<void> {\n\t\tif (!opts.force && this.getIsReadonly()) return\n\t\treturn this.externalContentHandlers[info.type]?.(info as any)\n\t}\n\n\t/**\n\t * Handle replacing external content.\n\t *\n\t * @param info - Info about the external content.\n\t * @param opts - Options for handling external content, including force flag to bypass readonly checks.\n\t */\n\tasync replaceExternalContent<E>(\n\t\tinfo: TLExternalContent<E>,\n\t\topts = {} as { force?: boolean }\n\t): Promise<void> {\n\t\tif (!opts.force && this.getIsReadonly()) return\n\t\treturn this.externalContentHandlers[info.type]?.(info as any)\n\t}\n\n\t/**\n\t * Get content that can be exported for the given shape ids.\n\t *\n\t * @param shapes - The shapes (or shape ids) to get content for.\n\t *\n\t * @returns The exported content.\n\t *\n\t * @public\n\t */\n\tgetContentFromCurrentPage(shapes: TLShapeId[] | TLShape[]): TLContent | undefined {\n\t\t// todo: make this work with any page, not just the current page\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (!ids) return\n\t\tif (ids.length === 0) return\n\n\t\tconst shapeIds = this.getShapeAndDescendantIds(ids)\n\n\t\treturn withIsolatedShapes(this, shapeIds, (bindingIdsToKeep) => {\n\t\t\tconst bindings: TLBinding[] = []\n\t\t\tfor (const id of bindingIdsToKeep) {\n\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\tif (!binding) continue\n\t\t\t\tbindings.push(binding)\n\t\t\t}\n\n\t\t\tconst rootShapeIds: TLShapeId[] = []\n\t\t\tconst shapes: TLShape[] = []\n\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\tconst isRootShape = !shapeIds.has(shape.parentId as TLShapeId)\n\t\t\t\tif (isRootShape) {\n\t\t\t\t\t// Need to get page point and rotation of the shape because shapes in\n\t\t\t\t\t// groups use local position/rotation\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape.id)!\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tshapes.push({\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tx: pagePoint.x,\n\t\t\t\t\t\ty: pagePoint.y,\n\t\t\t\t\t\trotation: pageTransform.rotation(),\n\t\t\t\t\t\tparentId: this.getCurrentPageId(),\n\t\t\t\t\t})\n\t\t\t\t\trootShapeIds.push(shape.id)\n\t\t\t\t} else {\n\t\t\t\t\tshapes.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst assets: TLAsset[] = []\n\t\t\tconst seenAssetIds = new Set<TLAssetId>()\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tif (!('assetId' in shape.props)) continue\n\n\t\t\t\tconst assetId = shape.props.assetId\n\t\t\t\tif (!assetId || seenAssetIds.has(assetId)) continue\n\n\t\t\t\tseenAssetIds.add(assetId)\n\t\t\t\tconst asset = this.getAsset(assetId)\n\t\t\t\tif (!asset) continue\n\t\t\t\tassets.push(asset)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tschema: this.store.schema.serialize(),\n\t\t\t\tshapes,\n\t\t\t\trootShapeIds,\n\t\t\t\tbindings,\n\t\t\t\tassets,\n\t\t\t}\n\t\t})\n\t}\n\n\tasync resolveAssetsInContent(content: TLContent | undefined): Promise<TLContent | undefined> {\n\t\tif (!content) return undefined\n\n\t\tconst assets: TLAsset[] = []\n\t\tawait Promise.allSettled(\n\t\t\tcontent.assets.map(async (asset) => {\n\t\t\t\tif (\n\t\t\t\t\t(asset.type === 'image' || asset.type === 'video') &&\n\t\t\t\t\t!asset.props.src?.startsWith('data:image') &&\n\t\t\t\t\t!asset.props.src?.startsWith('data:video') &&\n\t\t\t\t\t!asset.props.src?.startsWith('http')\n\t\t\t\t) {\n\t\t\t\t\tconst assetWithDataUrl = structuredClone(asset as TLImageAsset | TLVideoAsset)\n\t\t\t\t\tconst objectUrl = await this.store.props.assets.resolve(asset, {\n\t\t\t\t\t\tscreenScale: 1,\n\t\t\t\t\t\tsteppedScreenScale: 1,\n\t\t\t\t\t\tdpr: 1,\n\t\t\t\t\t\tnetworkEffectiveType: null,\n\t\t\t\t\t\tshouldResolveToOriginal: true,\n\t\t\t\t\t})\n\t\t\t\t\tassetWithDataUrl.props.src = await FileHelpers.blobToDataUrl(\n\t\t\t\t\t\tawait fetch(objectUrl!).then((r) => r.blob())\n\t\t\t\t\t)\n\t\t\t\t\tassets.push(assetWithDataUrl)\n\t\t\t\t} else {\n\t\t\t\t\tassets.push(asset)\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t\tcontent.assets = assets\n\n\t\treturn content\n\t}\n\n\t/**\n\t * Place content into the editor.\n\t *\n\t * @param content - The content.\n\t * @param opts - Options for placing the content.\n\t *\n\t * @public\n\t */\n\tputContentOntoCurrentPage(\n\t\tcontent: TLContent,\n\t\topts: {\n\t\t\tpoint?: VecLike\n\t\t\tselect?: boolean\n\t\t\tpreservePosition?: boolean\n\t\t\tpreserveIds?: boolean\n\t\t} = {}\n\t): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\t// todo: make this able to support putting content onto any page, not just the current page\n\n\t\tif (!content.schema) {\n\t\t\tthrow Error('Could not put content:\\ncontent is missing a schema.')\n\t\t}\n\n\t\tconst { select = false, preserveIds = false, preservePosition = false } = opts\n\t\tlet { point = undefined } = opts\n\n\t\t// decide on a parent for the put shapes; if the parent is among the put shapes(?) then use its parent\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\tconst { rootShapeIds } = content\n\n\t\t// We need to collect the migrated records\n\t\tconst assets: TLAsset[] = []\n\t\tconst shapes: TLShape[] = []\n\t\tconst bindings: TLBinding[] = []\n\n\t\t// Let's treat the content as a store, and then migrate that store.\n\t\tconst store: StoreSnapshot<TLRecord> = {\n\t\t\tstore: {\n\t\t\t\t...Object.fromEntries(content.assets.map((asset) => [asset.id, asset] as const)),\n\t\t\t\t...Object.fromEntries(content.shapes.map((shape) => [shape.id, shape] as const)),\n\t\t\t\t...Object.fromEntries(\n\t\t\t\t\tcontent.bindings?.map((bindings) => [bindings.id, bindings] as const) ?? []\n\t\t\t\t),\n\t\t\t},\n\t\t\tschema: content.schema,\n\t\t}\n\t\tconst result = this.store.schema.migrateStoreSnapshot(store)\n\t\tif (result.type === 'error') {\n\t\t\tthrow Error('Could not put content: could not migrate content')\n\t\t}\n\t\tfor (const record of Object.values(result.value)) {\n\t\t\tswitch (record.typeName) {\n\t\t\t\tcase 'asset': {\n\t\t\t\t\tassets.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'shape': {\n\t\t\t\t\tshapes.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'binding': {\n\t\t\t\t\tbindings.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Ok, we've got our migrated records, now we can continue!\n\t\tconst shapeIdMap = new Map<string, TLShapeId>(\n\t\t\tpreserveIds\n\t\t\t\t? shapes.map((shape) => [shape.id, shape.id])\n\t\t\t\t: shapes.map((shape) => [shape.id, createShapeId()])\n\t\t)\n\t\tconst bindingIdMap = new Map<string, TLBindingId>(\n\t\t\tpreserveIds\n\t\t\t\t? bindings.map((binding) => [binding.id, binding.id])\n\t\t\t\t: bindings.map((binding) => [binding.id, createBindingId()])\n\t\t)\n\n\t\t// By default, the paste parent will be the current page.\n\t\tlet pasteParentId = this.getCurrentPageId() as TLPageId | TLShapeId\n\t\tlet lowestDepth = Infinity\n\t\tlet lowestAncestors: TLShape[] = []\n\n\t\t// Among the selected shapes, find the shape with the fewest ancestors and use its first ancestor.\n\t\tfor (const shape of this.getSelectedShapes()) {\n\t\t\tif (lowestDepth === 0) break\n\n\t\t\tconst isFrame = this.isShapeOfType<TLFrameShape>(shape, 'frame')\n\t\t\tconst ancestors = this.getShapeAncestors(shape)\n\t\t\tif (isFrame) ancestors.push(shape)\n\n\t\t\tconst depth = isFrame ? ancestors.length + 1 : ancestors.length\n\n\t\t\tif (depth < lowestDepth) {\n\t\t\t\tlowestDepth = depth\n\t\t\t\tlowestAncestors = ancestors\n\t\t\t\tpasteParentId = isFrame ? shape.id : shape.parentId\n\t\t\t} else if (depth === lowestDepth) {\n\t\t\t\tif (lowestAncestors.length !== ancestors.length) {\n\t\t\t\t\tthrow Error(`Ancestors: ${lowestAncestors.length} !== ${ancestors.length}`)\n\t\t\t\t}\n\n\t\t\t\tif (lowestAncestors.length === 0) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tbreak\n\t\t\t\t} else {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tfor (let i = 0; i < lowestAncestors.length; i++) {\n\t\t\t\t\t\tif (ancestors[i] !== lowestAncestors[i]) break\n\t\t\t\t\t\tpasteParentId = ancestors[i].id\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet isDuplicating = false\n\n\t\tif (!isPageId(pasteParentId)) {\n\t\t\tconst parent = this.getShape(pasteParentId)\n\t\t\tif (parent) {\n\t\t\t\tif (!this.getViewportPageBounds().includes(this.getShapePageBounds(parent)!)) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t} else {\n\t\t\t\t\tif (rootShapeIds.length === 1) {\n\t\t\t\t\t\tconst rootShape = shapes.find((s) => s.id === rootShapeIds[0])!\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.isShapeOfType<TLFrameShape>(parent, 'frame') &&\n\t\t\t\t\t\t\tthis.isShapeOfType<TLFrameShape>(rootShape, 'frame') &&\n\t\t\t\t\t\t\trootShape.props.w === parent?.props.w &&\n\t\t\t\t\t\t\trootShape.props.h === parent?.props.h\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tisDuplicating = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpasteParentId = currentPageId\n\t\t\t}\n\t\t}\n\n\t\tif (!isDuplicating) {\n\t\t\tisDuplicating = shapeIdMap.has(pasteParentId)\n\t\t}\n\n\t\tif (isDuplicating) {\n\t\t\tpasteParentId = this.getShape(pasteParentId)!.parentId\n\t\t}\n\n\t\tlet index = this.getHighestIndexForParent(pasteParentId) // todo: requires that the putting page is the current page\n\n\t\tconst rootShapes: TLShape[] = []\n\n\t\tconst newShapes: TLShape[] = shapes.map((oldShape): TLShape => {\n\t\t\tconst newId = shapeIdMap.get(oldShape.id)!\n\n\t\t\t// Create the new shape (new except for the id)\n\t\t\tconst newShape = { ...oldShape, id: newId }\n\n\t\t\tif (rootShapeIds.includes(oldShape.id)) {\n\t\t\t\tnewShape.parentId = currentPageId\n\t\t\t\trootShapes.push(newShape)\n\t\t\t}\n\n\t\t\t// Assign the child to its new parent.\n\n\t\t\t// If the child's parent is among the putting shapes, then assign\n\t\t\t// it to the new parent's id.\n\t\t\tif (shapeIdMap.has(newShape.parentId)) {\n\t\t\t\tnewShape.parentId = shapeIdMap.get(oldShape.parentId)!\n\t\t\t} else {\n\t\t\t\trootShapeIds.push(newShape.id)\n\t\t\t\t// newShape.parentId = pasteParentId\n\t\t\t\tnewShape.index = index\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\n\t\t\treturn newShape\n\t\t})\n\n\t\tif (newShapes.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage) {\n\t\t\t// There's some complexity here involving children\n\t\t\t// that might be created without their parents, so\n\t\t\t// if we're going over the limit then just don't paste.\n\t\t\talertMaxShapes(this)\n\t\t\treturn this\n\t\t}\n\n\t\tconst newBindings = bindings.map(\n\t\t\t(oldBinding): TLBinding => ({\n\t\t\t\t...oldBinding,\n\t\t\t\tid: assertExists(bindingIdMap.get(oldBinding.id)),\n\t\t\t\tfromId: assertExists(shapeIdMap.get(oldBinding.fromId)),\n\t\t\t\ttoId: assertExists(shapeIdMap.get(oldBinding.toId)),\n\t\t\t})\n\t\t)\n\n\t\t// These are all the assets we need to create\n\t\tconst assetsToCreate: TLAsset[] = []\n\n\t\t// These assets have base64 data that may need to be hosted\n\t\tconst assetsToUpdate: (TLImageAsset | TLVideoAsset)[] = []\n\n\t\tfor (const asset of assets) {\n\t\t\tif (this.store.has(asset.id)) {\n\t\t\t\t// We already have this asset\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t(asset.type === 'image' && asset.props.src?.startsWith('data:image')) ||\n\t\t\t\t(asset.type === 'video' && asset.props.src?.startsWith('data:video'))\n\t\t\t) {\n\t\t\t\t// it's src is a base64 image or video; we need to create a new asset without the src,\n\t\t\t\t// then create a new asset from the original src. So we save a copy of the original asset,\n\t\t\t\t// then delete the src from the original asset.\n\t\t\t\tassetsToUpdate.push(structuredClone(asset as TLImageAsset | TLVideoAsset))\n\t\t\t\tasset.props.src = null\n\t\t\t}\n\n\t\t\t// Add the asset to the list of assets to create\n\t\t\tassetsToCreate.push(asset)\n\t\t}\n\n\t\t// Start loading the new assets, order does not matter\n\t\tPromise.allSettled(\n\t\t\t(assetsToUpdate as (TLImageAsset | TLVideoAsset)[]).map(async (asset) => {\n\t\t\t\t// Turn the data url into a file\n\t\t\t\tconst file = await dataUrlToFile(\n\t\t\t\t\tasset.props.src!,\n\t\t\t\t\tasset.props.name,\n\t\t\t\t\tasset.props.mimeType ?? 'image/png'\n\t\t\t\t)\n\n\t\t\t\t// Get a new asset for the file\n\t\t\t\tconst newAsset = await this.getAssetForExternalContent({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tfile,\n\t\t\t\t\tassetId: asset.id,\n\t\t\t\t})\n\n\t\t\t\tif (!newAsset) {\n\t\t\t\t\t// If we don't have a new asset, delete the old asset.\n\t\t\t\t\t// The shapes that reference this asset should break.\n\t\t\t\t\tthis.deleteAssets([asset.id])\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Save the new asset under the old asset's id\n\t\t\t\tthis.updateAssets([{ ...newAsset, id: asset.id }])\n\t\t\t})\n\t\t)\n\n\t\tthis.run(() => {\n\t\t\t// Create any assets that need to be created\n\t\t\tif (assetsToCreate.length > 0) {\n\t\t\t\tthis.createAssets(assetsToCreate)\n\t\t\t}\n\n\t\t\t// Create the shapes with root shapes as children of the page\n\t\t\tthis.createShapes(newShapes)\n\t\t\tthis.createBindings(newBindings)\n\n\t\t\tif (select) {\n\t\t\t\tthis.select(...rootShapes.map((s) => s.id))\n\t\t\t}\n\n\t\t\t// And then, if needed, reparent the root shapes to the paste parent\n\t\t\tif (pasteParentId !== currentPageId) {\n\t\t\t\tthis.reparentShapes(\n\t\t\t\t\trootShapes.map((s) => s.id),\n\t\t\t\t\tpasteParentId\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst newCreatedShapes = newShapes.map((s) => this.getShape(s.id)!)\n\t\t\tconst bounds = Box.Common(newCreatedShapes.map((s) => this.getShapePageBounds(s)!))\n\n\t\t\tif (point === undefined) {\n\t\t\t\tif (!isPageId(pasteParentId)) {\n\t\t\t\t\t// Put the shapes in the middle of the (on screen) parent\n\t\t\t\t\tconst shape = this.getShape(pasteParentId)!\n\t\t\t\t\tpoint = Mat.applyToPoint(\n\t\t\t\t\t\tthis.getShapePageTransform(shape),\n\t\t\t\t\t\tthis.getShapeGeometry(shape).bounds.center\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\t\tif (preservePosition || viewportPageBounds.includes(Box.From(bounds))) {\n\t\t\t\t\t\t// Otherwise, put shapes where they used to be\n\t\t\t\t\t\tpoint = bounds.center\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the old bounds are outside of the viewport...\n\t\t\t\t\t\t// put the shapes in the middle of the viewport\n\t\t\t\t\t\tpoint = viewportPageBounds.center\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rootShapes.length === 1) {\n\t\t\t\tconst onlyRoot = rootShapes[0] as TLFrameShape\n\t\t\t\t// If the old bounds are in the viewport...\n\t\t\t\t// todo: replace frame references with shapes that can accept children\n\t\t\t\tif (this.isShapeOfType<TLFrameShape>(onlyRoot, 'frame')) {\n\t\t\t\t\twhile (\n\t\t\t\t\t\tthis.getShapesAtPoint(point).some(\n\t\t\t\t\t\t\t(shape) =>\n\t\t\t\t\t\t\t\tthis.isShapeOfType<TLFrameShape>(shape, 'frame') &&\n\t\t\t\t\t\t\t\tshape.props.w === onlyRoot.props.w &&\n\t\t\t\t\t\t\t\tshape.props.h === onlyRoot.props.h\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tpoint.x += bounds.w + 16\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst pageCenter = Box.Common(\n\t\t\t\tcompact(rootShapes.map(({ id }) => this.getShapePageBounds(id)))\n\t\t\t).center\n\n\t\t\tconst offset = Vec.Sub(point, pageCenter)\n\n\t\t\tthis.updateShapes(\n\t\t\t\trootShapes.map(({ id }) => {\n\t\t\t\t\tconst s = this.getShape(id)!\n\t\t\t\t\tconst localRotation = this.getShapeParentTransform(id).decompose().rotation\n\t\t\t\t\tconst localDelta = Vec.Rot(offset, -localRotation)\n\n\t\t\t\t\treturn { id: s.id, type: s.type, x: s.x + localDelta.x, y: s.y + localDelta.y }\n\t\t\t\t})\n\t\t\t)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an exported SVG element of the given shapes.\n\t *\n\t * @param shapes - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgElement(shapes: TLShapeId[] | TLShape[], opts: TLSvgExportOptions = {}) {\n\t\tconst ids =\n\t\t\tshapes.length === 0\n\t\t\t\t? this.getCurrentPageShapeIdsSorted()\n\t\t\t\t: typeof shapes[0] === 'string'\n\t\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return undefined\n\n\t\treturn exportToSvg(this, ids, opts)\n\t}\n\n\t/**\n\t * Get an exported SVG string of the given shapes.\n\t *\n\t * @param shapes - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgString(shapes: TLShapeId[] | TLShape[], opts: TLSvgExportOptions = {}) {\n\t\tconst result = await this.getSvgElement(shapes, opts)\n\t\tif (!result) return undefined\n\n\t\tconst serializer = new XMLSerializer()\n\t\treturn {\n\t\t\tsvg: serializer.serializeToString(result.svg),\n\t\t\twidth: result.width,\n\t\t\theight: result.height,\n\t\t}\n\t}\n\n\t/**\n\t * Get an exported image of the given shapes.\n\t *\n\t * @param shapes - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns A blob of the image.\n\t * @public\n\t */\n\tasync toImage(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst withDefaults = {\n\t\t\tformat: 'png',\n\t\t\tscale: 1,\n\t\t\tpixelRatio: opts.format === 'svg' ? undefined : 2,\n\t\t\t...opts,\n\t\t} satisfies TLImageExportOptions\n\t\tconst result = await this.getSvgString(shapes, withDefaults)\n\t\tif (!result) throw new Error('Could not create SVG')\n\n\t\tswitch (withDefaults.format) {\n\t\t\tcase 'svg':\n\t\t\t\treturn {\n\t\t\t\t\tblob: new Blob([result.svg], { type: 'image/svg+xml' }),\n\t\t\t\t\twidth: result.width,\n\t\t\t\t\theight: result.height,\n\t\t\t\t}\n\t\t\tcase 'jpeg':\n\t\t\tcase 'png':\n\t\t\tcase 'webp': {\n\t\t\t\tconst blob = await getSvgAsImage(result.svg, {\n\t\t\t\t\ttype: withDefaults.format,\n\t\t\t\t\tquality: withDefaults.quality,\n\t\t\t\t\tpixelRatio: withDefaults.pixelRatio,\n\t\t\t\t\twidth: result.width,\n\t\t\t\t\theight: result.height,\n\t\t\t\t})\n\t\t\t\tif (!blob) {\n\t\t\t\t\tthrow new Error('Could not construct image.')\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tblob,\n\t\t\t\t\twidth: result.width,\n\t\t\t\t\theight: result.height,\n\t\t\t\t}\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\texhaustiveSwitchError(withDefaults.format)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get an exported image of the given shapes as a data URL.\n\t *\n\t * @param shapes - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns A data URL of the image.\n\t * @public\n\t */\n\tasync toImageDataUrl(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst { blob, width, height } = await this.toImage(shapes, opts)\n\t\treturn {\n\t\t\turl: await FileHelpers.blobToDataUrl(blob),\n\t\t\twidth,\n\t\t\theight,\n\t\t}\n\t}\n\n\t/* --------------------- Events --------------------- */\n\n\t/**\n\t * The app's current input state.\n\t *\n\t * @public\n\t */\n\tinputs = {\n\t\t/** The most recent pointer down's position in the current page space. */\n\t\toriginPagePoint: new Vec(),\n\t\t/** The most recent pointer down's position in screen space. */\n\t\toriginScreenPoint: new Vec(),\n\t\t/** The previous pointer position in the current page space. */\n\t\tpreviousPagePoint: new Vec(),\n\t\t/** The previous pointer position in screen space. */\n\t\tpreviousScreenPoint: new Vec(),\n\t\t/** The most recent pointer position in the current page space. */\n\t\tcurrentPagePoint: new Vec(),\n\t\t/** The most recent pointer position in screen space. */\n\t\tcurrentScreenPoint: new Vec(),\n\t\t/** A set containing the currently pressed keys. */\n\t\tkeys: new Set<string>(),\n\t\t/** A set containing the currently pressed buttons. */\n\t\tbuttons: new Set<number>(),\n\t\t/** Whether the input is from a pe. */\n\t\tisPen: false,\n\t\t/** Whether the shift key is currently pressed. */\n\t\tshiftKey: false,\n\t\t/** Whether the meta key is currently pressed. */\n\t\tmetaKey: false,\n\t\t/** Whether the control or command key is currently pressed. */\n\t\tctrlKey: false,\n\t\t/** Whether the alt or option key is currently pressed. */\n\t\taltKey: false,\n\t\t/** Whether the user is dragging. */\n\t\tisDragging: false,\n\t\t/** Whether the user is pointing. */\n\t\tisPointing: false,\n\t\t/** Whether the user is pinching. */\n\t\tisPinching: false,\n\t\t/** Whether the user is editing. */\n\t\tisEditing: false,\n\t\t/** Whether the user is panning. */\n\t\tisPanning: false,\n\t\t/** Whether the user is spacebar panning. */\n\t\tisSpacebarPanning: false,\n\t\t/** Velocity of mouse pointer, in pixels per millisecond */\n\t\tpointerVelocity: new Vec(),\n\t}\n\n\t/**\n\t * Update the input points from a pointer, pinch, or wheel event.\n\t *\n\t * @param info - The event info.\n\t */\n\tprivate _updateInputsFromEvent(\n\t\tinfo: TLPointerEventInfo | TLPinchEventInfo | TLWheelEventInfo\n\t): void {\n\t\tconst {\n\t\t\tpointerVelocity,\n\t\t\tpreviousScreenPoint,\n\t\t\tpreviousPagePoint,\n\t\t\tcurrentScreenPoint,\n\t\t\tcurrentPagePoint,\n\t\t\toriginScreenPoint,\n\t\t\toriginPagePoint,\n\t\t} = this.inputs\n\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\tconst sx = info.point.x - screenBounds.x\n\t\tconst sy = info.point.y - screenBounds.y\n\t\tconst sz = info.point.z ?? 0.5\n\n\t\tpreviousScreenPoint.setTo(currentScreenPoint)\n\t\tpreviousPagePoint.setTo(currentPagePoint)\n\n\t\t// The \"screen bounds\" is relative to the user's actual screen.\n\t\t// The \"screen point\" is relative to the \"screen bounds\";\n\t\t// it will be 0,0 when its actual screen position is equal\n\t\t// to screenBounds.point. This is confusing!\n\t\tcurrentScreenPoint.set(sx, sy)\n\t\tconst nx = sx / cz - cx\n\t\tconst ny = sy / cz - cy\n\t\tif (isFinite(nx) && isFinite(ny)) {\n\t\t\tcurrentPagePoint.set(nx, ny, sz)\n\t\t}\n\n\t\tthis.inputs.isPen = info.type === 'pointer' && info.isPen\n\n\t\t// Reset velocity on pointer down, or when a pinch starts or ends\n\t\tif (info.name === 'pointer_down' || this.inputs.isPinching) {\n\t\t\tpointerVelocity.set(0, 0)\n\t\t\toriginScreenPoint.setTo(currentScreenPoint)\n\t\t\toriginPagePoint.setTo(currentPagePoint)\n\t\t}\n\n\t\t// todo: We only have to do this if there are multiple users in the document\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([\n\t\t\t\t\t{\n\t\t\t\t\t\tid: TLPOINTER_ID,\n\t\t\t\t\t\ttypeName: 'pointer',\n\t\t\t\t\t\tx: currentPagePoint.x,\n\t\t\t\t\t\ty: currentPagePoint.y,\n\t\t\t\t\t\tlastActivityTimestamp:\n\t\t\t\t\t\t\t// If our pointer moved only because we're following some other user, then don't\n\t\t\t\t\t\t\t// update our last activity timestamp; otherwise, update it to the current timestamp.\n\t\t\t\t\t\t\tinfo.type === 'pointer' && info.pointerId === INTERNAL_POINTER_IDS.CAMERA_MOVE\n\t\t\t\t\t\t\t\t? (this.store.unsafeGetWithoutCapture(TLPOINTER_ID)?.lastActivityTimestamp ??\n\t\t\t\t\t\t\t\t\tthis._tickManager.now)\n\t\t\t\t\t\t\t\t: this._tickManager.now,\n\t\t\t\t\t\tmeta: {},\n\t\t\t\t\t},\n\t\t\t\t])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t}\n\n\t/**\n\t * Dispatch a cancel event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.cancel()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcancel(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'cancel' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch an interrupt event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.interrupt()\n\t * ```\n\t *\n\t * @public\n\t */\n\tinterrupt(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'interrupt' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch a complete event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.complete()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcomplete(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'complete' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch a pointer move event in the current position of the pointer. This is useful when\n\t * external circumstances have changed (e.g. the camera moved or a shape was moved) and you want\n\t * the current interaction to respond to that change.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updatePointer()\n\t * ```\n\t *\n\t * @param options - The options for updating the pointer.\n\t * @returns The editor instance.\n\t * @public\n\t */\n\tupdatePointer(options?: TLUpdatePointerOptions): this {\n\t\tconst event: TLPointerEventInfo = {\n\t\t\ttype: 'pointer',\n\t\t\ttarget: 'canvas',\n\t\t\tname: 'pointer_move',\n\t\t\tpoint:\n\t\t\t\toptions?.point ??\n\t\t\t\t// weird but true: what `inputs` calls screen-space is actually viewport space. so\n\t\t\t\t// we need to convert back into true screen space first. we should fix this...\n\t\t\t\tVec.Add(\n\t\t\t\t\tthis.inputs.currentScreenPoint,\n\t\t\t\t\tthis.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!.screenBounds\n\t\t\t\t),\n\t\t\tpointerId: options?.pointerId ?? 0,\n\t\t\tbutton: options?.button ?? 0,\n\t\t\tisPen: options?.isPen ?? this.inputs.isPen,\n\t\t\tshiftKey: options?.shiftKey ?? this.inputs.shiftKey,\n\t\t\taltKey: options?.altKey ?? this.inputs.altKey,\n\t\t\tctrlKey: options?.ctrlKey ?? this.inputs.ctrlKey,\n\t\t\tmetaKey: options?.metaKey ?? this.inputs.metaKey,\n\t\t\taccelKey: options?.accelKey ?? isAccelKey(this.inputs),\n\t\t}\n\n\t\tif (options?.immediate) {\n\t\t\tthis._flushEventForTick(event)\n\t\t} else {\n\t\t\tthis.dispatch(event)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Puts the editor into focused mode.\n\t *\n\t * This makes the editor eligible to receive keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus()\n\t * ```\n\t *\n\t * By default this also dispatches a 'focus' event to the container element. To prevent this, pass `focusContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus({ focusContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tfocus({ focusContainer = true } = {}): this {\n\t\tif (this.getIsFocused()) return this\n\t\tif (focusContainer) this.focusManager.focus()\n\t\tthis.updateInstanceState({ isFocused: true })\n\t\treturn this\n\t}\n\n\t/**\n\t * Switches off the editor's focused mode.\n\t *\n\t * This makes the editor ignore keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur()\n\t * ```\n\t * By default this also dispatches a 'blur' event to the container element. To prevent this, pass `blurContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur({ blurContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tblur({ blurContainer = true } = {}): this {\n\t\tif (!this.getIsFocused()) return this\n\t\tif (blurContainer) {\n\t\t\tthis.focusManager.blur()\n\t\t} else {\n\t\t\tthis.complete() // stop any interaction\n\t\t}\n\t\tthis.updateInstanceState({ isFocused: false })\n\t\treturn this\n\t}\n\n\t/**\n\t * @public\n\t * @returns true if the editor is focused\n\t */\n\t@computed getIsFocused() {\n\t\treturn this.getInstanceState().isFocused\n\t}\n\n\t/**\n\t * @public\n\t * @returns true if the editor is in readonly mode\n\t */\n\t@computed getIsReadonly() {\n\t\treturn this.getInstanceState().isReadonly\n\t}\n\n\t/**\n\t * @public\n\t * @returns a snapshot of the store's UI and document state\n\t */\n\tgetSnapshot() {\n\t\treturn getSnapshot(this.store)\n\t}\n\n\t/**\n\t * Loads a snapshot into the editor.\n\t * @param snapshot - The snapshot to load.\n\t * @param opts - The options for loading the snapshot.\n\t * @returns\n\t */\n\tloadSnapshot(\n\t\tsnapshot: Partial<TLEditorSnapshot> | TLStoreSnapshot,\n\t\topts?: TLLoadSnapshotOptions\n\t) {\n\t\tloadSnapshot(this.store, snapshot, opts)\n\t\treturn this\n\t}\n\n\tprivate _zoomToFitPageContentAt100Percent() {\n\t\tconst bounds = this.getCurrentPageBounds()\n\t\tif (bounds) {\n\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t}\n\t}\n\tprivate _navigateToDeepLink(deepLink: TLDeepLink) {\n\t\tthis.run(() => {\n\t\t\tswitch (deepLink.type) {\n\t\t\t\tcase 'page': {\n\t\t\t\t\tconst page = this.getPage(deepLink.pageId)\n\t\t\t\t\tif (page) {\n\t\t\t\t\t\tthis.setCurrentPage(page)\n\t\t\t\t\t}\n\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'shapes': {\n\t\t\t\t\tconst allShapes = compact(deepLink.shapeIds.map((id) => this.getShape(id)))\n\t\t\t\t\tconst byPage: { [pageId: string]: TLShape[] } = {}\n\t\t\t\t\tfor (const shape of allShapes) {\n\t\t\t\t\t\tconst pageId = this.getAncestorPageId(shape)\n\t\t\t\t\t\tif (!pageId) continue\n\t\t\t\t\t\tbyPage[pageId] ??= []\n\t\t\t\t\t\tbyPage[pageId].push(shape)\n\t\t\t\t\t}\n\t\t\t\t\tconst [pageId, shapes] = Object.entries(byPage).sort(\n\t\t\t\t\t\t([_, a], [__, b]) => b.length - a.length\n\t\t\t\t\t)[0] ?? ['', []]\n\n\t\t\t\t\tif (!pageId || !shapes.length) {\n\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.setCurrentPage(pageId as TLPageId)\n\t\t\t\t\t\tconst bounds = Box.Common(shapes.map((s) => this.getShapePageBounds(s)!))\n\t\t\t\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'viewport': {\n\t\t\t\t\tif (deepLink.pageId) {\n\t\t\t\t\t\tif (!this.getPage(deepLink.pageId)) {\n\t\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.setCurrentPage(deepLink.pageId)\n\t\t\t\t\t}\n\t\t\t\t\tthis.zoomToBounds(deepLink.bounds, { immediate: true, inset: 0 })\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(deepLink)\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Handles navigating to the content specified by the query param in the given URL.\n\t *\n\t * Use {@link Editor#createDeepLink} to create a URL with a deep link query param.\n\t *\n\t * If no URL is provided, it will look for the param in the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.navigateToDeepLink()\n\t * ```\n\t *\n\t * The default parameter name is 'd'. You can override this by providing the `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * // disable page parameter and change viewport parameter to 'c'\n\t * editor.navigateToDeepLink({\n\t * param: 'x',\n\t * url: 'https://my-app.com/my-document?x=200.12.454.23.xyz123',\n\t * })\n\t * ```\n\t *\n\t * @param opts - Options for loading the state from the URL.\n\t */\n\tnavigateToDeepLink(opts?: TLDeepLink | { url?: string | URL; param?: string }): Editor {\n\t\tif (opts && 'type' in opts) {\n\t\t\tthis._navigateToDeepLink(opts)\n\t\t\treturn this\n\t\t}\n\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\t\tconst deepLinkString = url.searchParams.get(opts?.param ?? 'd')\n\n\t\tif (!deepLinkString) {\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\treturn this\n\t\t}\n\n\t\ttry {\n\t\t\tthis._navigateToDeepLink(parseDeepLinkString(deepLinkString))\n\t\t} catch (e) {\n\t\t\tconsole.warn(e)\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Turns the given URL into a deep link by adding a query parameter.\n\t *\n\t * e.g. `https://my-app.com/my-document?d=100.100.200.200.xyz123`\n\t *\n\t * If no URL is provided, it will use the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the current page + viewport\n\t * navigator.clipboard.writeText(editor.createDeepLink())\n\t * ```\n\t *\n\t * You can link to a particular set of shapes by providing a `to` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the set of currently selected shapes\n\t * navigator.clipboard.writeText(editor.createDeepLink({\n\t * to: { type: 'selection', shapeIds: editor.getSelectedShapeIds() }\n\t * }))\n\t * ```\n\t *\n\t * The default query param is 'd'. You can override this by providing a `param` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // Use `x` as the param name instead\n\t * editor.createDeepLink({ param: 'x' })\n\t * ```\n\t *\n\t * @param opts - Options for adding the state to the URL.\n\t * @returns the updated URL\n\t */\n\tcreateDeepLink(opts?: { url?: string | URL; param?: string; to?: TLDeepLink }): URL {\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\n\t\turl.searchParams.set(\n\t\t\topts?.param ?? 'd',\n\t\t\tcreateDeepLinkString(\n\t\t\t\topts?.to ?? {\n\t\t\t\t\ttype: 'viewport',\n\t\t\t\t\tpageId: this.options.maxPages === 1 ? undefined : this.getCurrentPageId(),\n\t\t\t\t\tbounds: this.getViewportPageBounds(),\n\t\t\t\t}\n\t\t\t)\n\t\t)\n\n\t\treturn url\n\t}\n\n\t/**\n\t * Register a listener for changes to a deep link for the current document.\n\t *\n\t * You'll typically want to use this indirectly via the {@link TldrawEditorBaseProps.deepLinks} prop on the `<Tldraw />` component.\n\t *\n\t * By default this will update `window.location` in place, but you can provide a custom callback\n\t * to handle state changes on your own.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * onChange(url) {\n\t * window.history.replaceState({}, document.title, url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * You can also provide a custom URL to update, in which case you must also provide `onChange`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * getUrl: () => `https://my-app.com/my-document`,\n\t * onChange(url) {\n\t * setShareUrl(url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * By default this will update with a debounce interval of 500ms, but you can provide a custom interval.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ debounceMs: 1000 })\n\t * ```\n\t * The default parameter name is `d`. You can override this by providing a `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ param: 'x' })\n\t * ```\n\t * @param opts - Options for setting up the listener.\n\t * @returns a function that will stop the listener.\n\t */\n\tregisterDeepLinkListener(opts?: TLDeepLinkOptions): () => void {\n\t\tif (opts?.getUrl && !opts?.onChange) {\n\t\t\tthrow Error(\n\t\t\t\t'[tldraw:urlStateSync] If you specify getUrl, you must also specify the onChange callback.'\n\t\t\t)\n\t\t}\n\n\t\tconst url$ = computed('url with state', () => {\n\t\t\tconst url = opts?.getUrl?.(this) ?? window.location.href\n\t\t\tconst urlWithState = this.createDeepLink({\n\t\t\t\tparam: opts?.param,\n\t\t\t\turl,\n\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t})\n\t\t\treturn urlWithState.toString()\n\t\t})\n\n\t\tconst announceChange =\n\t\t\topts?.onChange ??\n\t\t\t(() => {\n\t\t\t\tconst url = this.createDeepLink({\n\t\t\t\t\tparam: opts?.param,\n\t\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t\t})\n\n\t\t\t\twindow.history.replaceState({}, document.title, url.toString())\n\t\t\t})\n\n\t\tconst scheduleEffect = debounce((execute: () => void) => execute(), opts?.debounceMs ?? 500)\n\n\t\tconst unlisten = react(\n\t\t\t'update url on state change',\n\t\t\t() => announceChange(new URL(url$.get()), this),\n\t\t\t{ scheduleEffect }\n\t\t)\n\n\t\treturn () => {\n\t\t\tunlisten()\n\t\t\tscheduleEffect.cancel()\n\t\t}\n\t}\n\n\t/**\n\t * A manager for recording multiple click events.\n\t *\n\t * @internal\n\t */\n\tprotected _clickManager = new ClickManager(this)\n\n\t/**\n\t * Prevent a double click event from firing the next time the user clicks\n\t *\n\t * @public\n\t */\n\tcancelDoubleClick() {\n\t\tthis._clickManager.cancelDoubleClickTimeout()\n\t}\n\n\t/**\n\t * The previous cursor. Used for restoring the cursor after pan events.\n\t *\n\t * @internal\n\t */\n\tprivate _prevCursor: TLCursorType = 'default'\n\n\t/** @internal */\n\tprivate _shiftKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setShiftKeyTimeout() {\n\t\tthis.inputs.shiftKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Shift',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'ShiftLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _altKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setAltKeyTimeout() {\n\t\tthis.inputs.altKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Alt',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'AltLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _ctrlKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setCtrlKeyTimeout() {\n\t\tthis.inputs.ctrlKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Ctrl',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'ControlLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _metaKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setMetaKeyTimeout() {\n\t\tthis.inputs.metaKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Meta',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'MetaLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _restoreToolId = 'select'\n\n\t/** @internal */\n\tprivate _pinchStart = 1\n\n\t/** @internal */\n\tprivate _didPinch = false\n\n\t/** @internal */\n\tprivate _selectedShapeIdsAtPointerDown: TLShapeId[] = []\n\n\t/** @internal */\n\tprivate _longPressTimeout = -1 as any\n\n\t/** @internal */\n\tcapturedPointerId: number | null = null\n\n\t/** @internal */\n\tprivate readonly performanceTracker: PerformanceTracker\n\n\t/** @internal */\n\tprivate performanceTrackerTimeout = -1 as any\n\n\t/** @internal */\n\tprivate handledEvents = new WeakSet<Event>()\n\n\t/**\n\t * In tldraw, events are sometimes handled by multiple components. For example, the shapes might\n\t * have events, but the canvas handles events too. The way that the canvas handles events can\n\t * interfere with the with the shapes event handlers - for example, it calls `.preventDefault()`\n\t * on `pointerDown`, which also prevents `click` events from firing on the shapes.\n\t *\n\t * You can use `.stopPropagation()` to prevent the event from propagating to the rest of the\n\t * DOM, but that can impact non-tldraw event handlers set up elsewhere. By using\n\t * `markEventAsHandled`, you'll stop other parts of tldraw from handling the event without\n\t * impacting other, non-tldraw event handlers. See also {@link Editor.wasEventAlreadyHandled}.\n\t *\n\t * @public\n\t */\n\tmarkEventAsHandled(e: Event | { nativeEvent: Event }) {\n\t\tconst nativeEvent = 'nativeEvent' in e ? e.nativeEvent : e\n\t\tthis.handledEvents.add(nativeEvent)\n\t}\n\n\t/**\n\t * Checks if an event has already been handled. See {@link Editor.markEventAsHandled}.\n\t *\n\t * @public\n\t */\n\twasEventAlreadyHandled(e: Event | { nativeEvent: Event }) {\n\t\tconst nativeEvent = 'nativeEvent' in e ? e.nativeEvent : e\n\t\treturn this.handledEvents.has(nativeEvent)\n\t}\n\n\t/**\n\t * Dispatch an event to the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.dispatch(myPointerEvent)\n\t * ```\n\t *\n\t * @param info - The event info.\n\t *\n\t * @public\n\t */\n\tdispatch(info: TLEventInfo) {\n\t\tthis._pendingEventsForNextTick.push(info)\n\t\tif (\n\t\t\t!(\n\t\t\t\t(info.type === 'pointer' && info.name === 'pointer_move') ||\n\t\t\t\tinfo.type === 'wheel' ||\n\t\t\t\tinfo.type === 'pinch'\n\t\t\t)\n\t\t) {\n\t\t\tthis._flushEventsForTick(0)\n\t\t}\n\t\treturn this\n\t}\n\n\tprivate _pendingEventsForNextTick: TLEventInfo[] = []\n\n\tprivate _flushEventsForTick(elapsed: number) {\n\t\tthis.run(() => {\n\t\t\tif (this._pendingEventsForNextTick.length > 0) {\n\t\t\t\tconst events = [...this._pendingEventsForNextTick]\n\t\t\t\tthis._pendingEventsForNextTick.length = 0\n\t\t\t\tfor (const info of events) {\n\t\t\t\t\tthis._flushEventForTick(info)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (elapsed > 0) {\n\t\t\t\tthis.root.handleEvent({ type: 'misc', name: 'tick', elapsed })\n\t\t\t}\n\t\t\tthis.scribbles.tick(elapsed)\n\t\t})\n\t}\n\n\t_flushEventForTick(info: TLEventInfo) {\n\t\t// prevent us from spamming similar event errors if we're crashed.\n\t\t// todo: replace with new readonly mode?\n\t\tif (this.getCrashingError()) return this\n\n\t\tthis.emit('before-event', info)\n\n\t\tconst { inputs } = this\n\t\tconst { type } = info\n\n\t\tif (info.type === 'misc') {\n\t\t\t// stop panning if the interaction is cancelled or completed\n\t\t\tif (info.name === 'cancel' || info.name === 'complete') {\n\t\t\t\tthis.inputs.isDragging = false\n\n\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.root.handleEvent(info)\n\t\t\treturn\n\t\t}\n\n\t\tif (info.shiftKey) {\n\t\t\tclearTimeout(this._shiftKeyTimeout)\n\t\t\tthis._shiftKeyTimeout = -1\n\t\t\tinputs.shiftKey = true\n\t\t} else if (!info.shiftKey && inputs.shiftKey && this._shiftKeyTimeout === -1) {\n\t\t\tthis._shiftKeyTimeout = this.timers.setTimeout(this._setShiftKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.altKey) {\n\t\t\tclearTimeout(this._altKeyTimeout)\n\t\t\tthis._altKeyTimeout = -1\n\t\t\tinputs.altKey = true\n\t\t} else if (!info.altKey && inputs.altKey && this._altKeyTimeout === -1) {\n\t\t\tthis._altKeyTimeout = this.timers.setTimeout(this._setAltKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.ctrlKey) {\n\t\t\tclearTimeout(this._ctrlKeyTimeout)\n\t\t\tthis._ctrlKeyTimeout = -1\n\t\t\tinputs.ctrlKey = true\n\t\t} else if (!info.ctrlKey && inputs.ctrlKey && this._ctrlKeyTimeout === -1) {\n\t\t\tthis._ctrlKeyTimeout = this.timers.setTimeout(this._setCtrlKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.metaKey) {\n\t\t\tclearTimeout(this._metaKeyTimeout)\n\t\t\tthis._metaKeyTimeout = -1\n\t\t\tinputs.metaKey = true\n\t\t} else if (!info.metaKey && inputs.metaKey && this._metaKeyTimeout === -1) {\n\t\t\tthis._metaKeyTimeout = this.timers.setTimeout(this._setMetaKeyTimeout, 150)\n\t\t}\n\n\t\tconst { originPagePoint, currentPagePoint } = inputs\n\n\t\tif (!inputs.isPointing) {\n\t\t\tinputs.isDragging = false\n\t\t}\n\n\t\tconst instanceState = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst pageState = this.store.get(this._getCurrentPageStateId())!\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()!\n\n\t\tswitch (type) {\n\t\t\tcase 'pinch': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pinch_start': {\n\t\t\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\t\t\tif (!inputs.isEditing) {\n\t\t\t\t\t\t\tthis._pinchStart = this.getCamera().z\n\t\t\t\t\t\t\tif (!this._selectedShapeIdsAtPointerDown.length) {\n\t\t\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds]\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis._didPinch = true\n\n\t\t\t\t\t\t\tinputs.isPinching = true\n\n\t\t\t\t\t\t\tthis.interrupt()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch': {\n\t\t\t\t\t\tif (!inputs.isPinching) return\n\n\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\tpoint: { z = 1 },\n\t\t\t\t\t\t\tdelta: { x: dx, y: dy },\n\t\t\t\t\t\t} = info\n\n\t\t\t\t\t\t// The center of the pinch in screen space\n\t\t\t\t\t\tconst { x, y } = Vec.SubXY(\n\t\t\t\t\t\t\tinfo.point,\n\t\t\t\t\t\t\tinstanceState.screenBounds.x,\n\t\t\t\t\t\t\tinstanceState.screenBounds.y\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\tconst { panSpeed } = cameraOptions\n\t\t\t\t\t\tthis._setCamera(\n\t\t\t\t\t\t\tnew Vec(\n\t\t\t\t\t\t\t\tcx + (dx * panSpeed) / cz - x / cz + x / z,\n\t\t\t\t\t\t\t\tcy + (dy * panSpeed) / cz - y / cz + y / z,\n\t\t\t\t\t\t\t\tz\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch_end': {\n\t\t\t\t\t\tif (!inputs.isPinching) return this\n\n\t\t\t\t\t\t// Stop pinching\n\t\t\t\t\t\tinputs.isPinching = false\n\n\t\t\t\t\t\t// Stash and clear the shapes that were selected when the pinch started\n\t\t\t\t\t\tconst { _selectedShapeIdsAtPointerDown: shapesToReselect } = this\n\t\t\t\t\t\tthis.setSelectedShapes(this._selectedShapeIdsAtPointerDown)\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = []\n\n\t\t\t\t\t\tif (this._didPinch) {\n\t\t\t\t\t\t\tthis._didPinch = false\n\t\t\t\t\t\t\tif (shapesToReselect.length > 0) {\n\t\t\t\t\t\t\t\tthis.once('tick', () => {\n\t\t\t\t\t\t\t\t\tif (!this._didPinch) {\n\t\t\t\t\t\t\t\t\t\t// Unless we've started pinching again...\n\t\t\t\t\t\t\t\t\t\t// Reselect the shapes that were selected when the pinch started\n\t\t\t\t\t\t\t\t\t\tthis.setSelectedShapes(shapesToReselect)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase 'wheel': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tconst { panSpeed, zoomSpeed } = cameraOptions\n\t\t\t\tlet wheelBehavior = cameraOptions.wheelBehavior\n\t\t\t\tconst inputMode = this.user.getUserPreferences().inputMode\n\n\t\t\t\t// If the user has set their input mode preference, then use that to determine the wheel behavior\n\t\t\t\tif (inputMode !== null) {\n\t\t\t\t\twheelBehavior = inputMode === 'trackpad' ? 'pan' : 'zoom'\n\t\t\t\t}\n\n\t\t\t\tif (wheelBehavior !== 'none') {\n\t\t\t\t\t// Stop any camera animation\n\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t// Stop following any following user\n\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\t\t\t\t\tconst { x: dx, y: dy, z: dz = 0 } = info.delta\n\n\t\t\t\t\tlet behavior = wheelBehavior\n\n\t\t\t\t\t// If the camera behavior is \"zoom\" and the ctrl key is pressed, then pan;\n\t\t\t\t\t// If the camera behavior is \"pan\" and the ctrl key is not pressed, then zoom\n\t\t\t\t\tif (info.ctrlKey) behavior = wheelBehavior === 'pan' ? 'zoom' : 'pan'\n\n\t\t\t\t\tswitch (behavior) {\n\t\t\t\t\t\tcase 'zoom': {\n\t\t\t\t\t\t\t// Zoom in on current screen point using the wheel delta\n\t\t\t\t\t\t\tconst { x, y } = this.inputs.currentScreenPoint\n\t\t\t\t\t\t\tlet delta = dz\n\n\t\t\t\t\t\t\t// If we're forcing zoom, then we need to do the wheel normalization math here\n\t\t\t\t\t\t\tif (wheelBehavior === 'zoom') {\n\t\t\t\t\t\t\t\tif (Math.abs(dy) > 10) {\n\t\t\t\t\t\t\t\t\tdelta = (10 * Math.sign(dy)) / 100\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tdelta = dy / 100\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst zoom = cz + (delta ?? 0) * zoomSpeed * cz\n\t\t\t\t\t\t\tthis._setCamera(new Vec(cx + x / zoom - x / cz, cy + y / zoom - y / cz, zoom), {\n\t\t\t\t\t\t\t\timmediate: true,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Zooming')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'pan': {\n\t\t\t\t\t\t\t// Pan the camera based on the wheel delta\n\t\t\t\t\t\t\tthis._setCamera(new Vec(cx + (dx * panSpeed) / cz, cy + (dy * panSpeed) / cz, cz), {\n\t\t\t\t\t\t\t\timmediate: true,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'pointer': {\n\t\t\t\t// Ignore pointer events while we're pinching\n\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\t\t\t\tconst { isPen } = info\n\t\t\t\tconst { isPenMode } = instanceState\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pointer_down': {\n\t\t\t\t\t\t// If we're in pen mode and the input is not a pen type, then stop here\n\t\t\t\t\t\tif (isPenMode && !isPen) return\n\n\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t// Start a long press timeout\n\t\t\t\t\t\t\tthis._longPressTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\t\t\t\tconst vsb = this.getViewportScreenBounds()\n\t\t\t\t\t\t\t\tthis.dispatch({\n\t\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\t\t// important! non-obvious!! the screenpoint was adjusted using the\n\t\t\t\t\t\t\t\t\t// viewport bounds, and will be again when this event is handled...\n\t\t\t\t\t\t\t\t\t// so we need to counter-adjust from the stored value so that the\n\t\t\t\t\t\t\t\t\t// new value is set correctly.\n\t\t\t\t\t\t\t\t\tpoint: this.inputs.originScreenPoint.clone().addXY(vsb.x, vsb.y),\n\t\t\t\t\t\t\t\t\tname: 'long_press',\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}, this.options.longPressDurationMs)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Save the selected ids at pointer down\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds()\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's a left-mouse-click, we store the pointer id for later user\n\t\t\t\t\t\tif (info.button === LEFT_MOUSE_BUTTON) this.capturedPointerId = info.pointerId\n\n\t\t\t\t\t\t// Add the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.add(info.button)\n\n\t\t\t\t\t\t// Start pointing and stop dragging\n\t\t\t\t\t\tinputs.isPointing = true\n\t\t\t\t\t\tinputs.isDragging = false\n\n\t\t\t\t\t\t// If pen mode is off but we're not already in pen mode, turn that on\n\t\t\t\t\t\tif (!isPenMode && isPen) this.updateInstanceState({ isPenMode: true })\n\n\t\t\t\t\t\t// On devices with erasers (like the Surface Pen or Wacom Pen), button 5 is the eraser\n\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\tthis._restoreToolId = this.getCurrentToolId()\n\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\tthis.setCurrentTool('eraser')\n\t\t\t\t\t\t} else if (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\t\t\t\t// Middle mouse pan activates panning unless we're already panning (with spacebar)\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = this.getInstanceState().cursor.type\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// We might be panning because we did a middle mouse click, or because we're holding spacebar and started a regular click\n\t\t\t\t\t\t// Also stop here, we don't want the state chart to receive the event\n\t\t\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\t\tthis.setCursor({ type: 'grabbing', rotation: 0 })\n\t\t\t\t\t\t\treturn this\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_move': {\n\t\t\t\t\t\t// If the user is in pen mode, but the pointer is not a pen, stop here.\n\t\t\t\t\t\tif (!isPen && isPenMode) return\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\t// If we've started panning, then clear any long press timeout\n\t\t\t\t\t\tif (this.inputs.isPanning && this.inputs.isPointing) {\n\t\t\t\t\t\t\t// Handle spacebar / middle mouse button panning\n\t\t\t\t\t\t\tconst { currentScreenPoint, previousScreenPoint } = this.inputs\n\t\t\t\t\t\t\tconst offset = Vec.Sub(currentScreenPoint, previousScreenPoint)\n\t\t\t\t\t\t\tthis.setCamera(new Vec(cx + offset.x / cz, cy + offset.y / cz, cz), {\n\t\t\t\t\t\t\t\timmediate: true,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinputs.isPointing &&\n\t\t\t\t\t\t\t!inputs.isDragging &&\n\t\t\t\t\t\t\tVec.Dist2(originPagePoint, currentPagePoint) * this.getZoomLevel() >\n\t\t\t\t\t\t\t\t(instanceState.isCoarsePointer\n\t\t\t\t\t\t\t\t\t? this.options.coarseDragDistanceSquared\n\t\t\t\t\t\t\t\t\t: this.options.dragDistanceSquared) /\n\t\t\t\t\t\t\t\t\tcz\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// Start dragging\n\t\t\t\t\t\t\tinputs.isDragging = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_up': {\n\t\t\t\t\t\t// Stop dragging / pointing\n\t\t\t\t\t\tinputs.isDragging = false\n\t\t\t\t\t\tinputs.isPointing = false\n\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\n\t\t\t\t\t\t// Remove the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.delete(info.button)\n\n\t\t\t\t\t\t// If we're in pen mode and we're not using a pen, stop here\n\t\t\t\t\t\tif (instanceState.isPenMode && !isPen) return\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's the same pointer that we stored earlier...\n\t\t\t\t\t\t// ... then it's probably still a left-mouse-click!\n\t\t\t\t\t\tif (this.capturedPointerId === info.pointerId) {\n\t\t\t\t\t\t\tthis.capturedPointerId = null\n\t\t\t\t\t\t\tinfo.button = 0\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (inputs.isPanning) {\n\t\t\t\t\t\t\tif (!inputs.keys.has('Space')) {\n\t\t\t\t\t\t\t\tinputs.isPanning = false\n\t\t\t\t\t\t\t\tinputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst slideDirection = this.inputs.pointerVelocity\n\t\t\t\t\t\t\tconst slideSpeed = Math.min(2, slideDirection.len())\n\n\t\t\t\t\t\t\tswitch (info.button) {\n\t\t\t\t\t\t\t\tcase LEFT_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase MIDDLE_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tif (this.inputs.keys.has(' ')) {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (slideSpeed > 0) {\n\t\t\t\t\t\t\t\tthis.slideCamera({ speed: slideSpeed, direction: slideDirection })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\t\t// If we were erasing with a stylus button, restore the tool we were using before we started erasing\n\t\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\t\tthis.setCurrentTool(this._restoreToolId)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'keyboard': {\n\t\t\t\t// please, please\n\t\t\t\tif (info.key === 'ShiftRight') info.key = 'ShiftLeft'\n\t\t\t\tif (info.key === 'AltRight') info.key = 'AltLeft'\n\t\t\t\tif (info.code === 'ControlRight') info.code = 'ControlLeft'\n\t\t\t\tif (info.code === 'MetaRight') info.code = 'MetaLeft'\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'key_down': {\n\t\t\t\t\t\t// Add the key from the keys set\n\t\t\t\t\t\tinputs.keys.add(info.code)\n\n\t\t\t\t\t\t// If the space key is pressed (but meta / control isn't!) activate panning\n\t\t\t\t\t\tif (info.code === 'Space' && !info.ctrlKey) {\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = instanceState.cursor.type\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t\tthis.setCursor({ type: this.inputs.isPointing ? 'grabbing' : 'grab', rotation: 0 })\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (this.inputs.isSpacebarPanning) {\n\t\t\t\t\t\t\tlet offset: Vec | undefined\n\t\t\t\t\t\t\tswitch (info.code) {\n\t\t\t\t\t\t\t\tcase 'ArrowUp': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, -1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowRight': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowDown': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, 1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowLeft': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(-1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (offset) {\n\t\t\t\t\t\t\t\tconst bounds = this.getViewportPageBounds()\n\t\t\t\t\t\t\t\tconst next = bounds.clone().translate(offset.mulV({ x: bounds.w, y: bounds.h }))\n\t\t\t\t\t\t\t\tthis._animateToViewport(next, { animation: { duration: 320 } })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_up': {\n\t\t\t\t\t\t// Remove the key from the keys set\n\t\t\t\t\t\tinputs.keys.delete(info.code)\n\n\t\t\t\t\t\t// If we've lifted the space key,\n\t\t\t\t\t\tif (info.code === 'Space') {\n\t\t\t\t\t\t\tif (this.inputs.buttons.has(MIDDLE_MOUSE_BUTTON)) {\n\t\t\t\t\t\t\t\t// If we're still middle dragging, continue panning\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// otherwise, stop panning\n\t\t\t\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_repeat': {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Correct the info name for right / middle clicks\n\t\tif (info.type === 'pointer') {\n\t\t\tif (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'middle_click'\n\t\t\t} else if (info.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'right_click'\n\t\t\t}\n\n\t\t\t// If a left click pointer event, send the event to the click manager.\n\t\t\tconst { isPenMode } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\t\tif (info.isPen === isPenMode) {\n\t\t\t\t// The click manager may return a new event, i.e. a double click event\n\t\t\t\t// depending on the event coming in and its own state. If the event has\n\t\t\t\t// changed then hand both events to the statechart\n\t\t\t\tconst clickInfo = this._clickManager.handlePointerEvent(info)\n\t\t\t\tif (info.name !== clickInfo.name) {\n\t\t\t\t\tthis.root.handleEvent(info)\n\t\t\t\t\tthis.emit('event', info)\n\t\t\t\t\tthis.root.handleEvent(clickInfo)\n\t\t\t\t\tthis.emit('event', clickInfo)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Send the event to the statechart. It will be handled by all\n\t\t// active states, starting at the root.\n\t\tthis.root.handleEvent(info)\n\t\tthis.emit('event', info)\n\n\t\t// close open menus at the very end on pointer down! after everything else! \u03C3\u03C5\u03BD\u03C4\u03B5\u03BB\u03B5\u03AF\u03B1\u03C2 \u03C4\u03BF\u1FE6 \u03BA\u03CE\u03B4\u03B9\u03BA\u03B1!!\n\t\tif (info.type === 'pointer' && info.name === 'pointer_down') {\n\t\t\tthis.menus.clearOpenMenus()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate maybeTrackPerformance(name: string) {\n\t\tif (debugFlags.measurePerformance.get()) {\n\t\t\tif (this.performanceTracker.isStarted()) {\n\t\t\t\tclearTimeout(this.performanceTrackerTimeout)\n\t\t\t} else {\n\t\t\t\tthis.performanceTracker.start(name)\n\t\t\t}\n\t\t\tthis.performanceTrackerTimeout = this.timers.setTimeout(() => {\n\t\t\t\tthis.performanceTracker.stop()\n\t\t\t}, 50)\n\t\t}\n\t}\n}\n\nfunction alertMaxShapes(editor: Editor, pageId = editor.getCurrentPageId()) {\n\tconst name = editor.getPage(pageId)!.name\n\teditor.emit('max-shapes', { name, pageId, count: editor.options.maxShapesPerPage })\n}\n\nfunction applyPartialToRecordWithProps<\n\tT extends UnknownRecord & { type: string; props: object; meta: object },\n>(prev: T, partial?: Partial<T> & { props?: Partial<T['props']> }): T {\n\tif (!partial) return prev\n\tlet next = null as null | T\n\tconst entries = Object.entries(partial)\n\tfor (let i = 0, n = entries.length; i < n; i++) {\n\t\tconst [k, v] = entries[i]\n\t\tif (v === undefined) continue\n\n\t\t// Is the key a special key? We don't update those\n\t\tif (k === 'id' || k === 'type' || k === 'typeName') continue\n\n\t\t// Is the value the same as it was before?\n\t\tif (v === (prev as any)[k]) continue\n\n\t\t// There's a new value, so create the new shape if we haven't already (should we be cloning this?)\n\t\tif (!next) next = { ...prev }\n\n\t\t// for props / meta properties, we support updates with partials of this object\n\t\tif (k === 'props' || k === 'meta') {\n\t\t\tnext[k] = { ...prev[k] } as JsonObject\n\t\t\tfor (const [nextKey, nextValue] of Object.entries(v as object)) {\n\t\t\t\t;(next[k] as JsonObject)[nextKey] = nextValue\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// base property\n\t\t;(next as any)[k] = v\n\t}\n\tif (!next) return prev\n\treturn next\n}\n\nfunction pushShapeWithDescendants(editor: Editor, id: TLShapeId, result: TLShape[]): void {\n\tconst shape = editor.getShape(id)\n\tif (!shape) return\n\tresult.push(shape)\n\tconst childIds = editor.getSortedChildIdsForParent(id)\n\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\tpushShapeWithDescendants(editor, childIds[i], result)\n\t}\n}\n\n/**\n * Run `callback` in a world where all bindings from the shapes in `shapeIds` to shapes not in\n * `shapeIds` are removed. This is useful when you want to duplicate/copy shapes without worrying\n * about bindings that might be pointing to shapes that are not being duplicated.\n *\n * The callback is given the set of bindings that should be maintained.\n */\nfunction withIsolatedShapes<T>(\n\teditor: Editor,\n\tshapeIds: Set<TLShapeId>,\n\tcallback: (bindingsWithBoth: Set<TLBindingId>) => T\n): T {\n\tlet result!: Result<T, unknown>\n\n\teditor.run(\n\t\t() => {\n\t\t\tconst changes = editor.store.extractingChanges(() => {\n\t\t\t\tconst bindingsWithBoth = new Set<TLBindingId>()\n\t\t\t\tconst bindingsToRemove = new Set<TLBindingId>()\n\n\t\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\t\tconst shape = editor.getShape(shapeId)\n\t\t\t\t\tif (!shape) continue\n\n\t\t\t\t\tfor (const binding of editor.getBindingsInvolvingShape(shapeId)) {\n\t\t\t\t\t\tconst hasFrom = shapeIds.has(binding.fromId)\n\t\t\t\t\t\tconst hasTo = shapeIds.has(binding.toId)\n\t\t\t\t\t\tif (hasFrom && hasTo) {\n\t\t\t\t\t\t\tbindingsWithBoth.add(binding.id)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!hasFrom || !hasTo) {\n\t\t\t\t\t\t\tbindingsToRemove.add(binding.id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\teditor.deleteBindings([...bindingsToRemove], { isolateShapes: true })\n\n\t\t\t\ttry {\n\t\t\t\t\tresult = Result.ok(callback(bindingsWithBoth))\n\t\t\t\t} catch (error) {\n\t\t\t\t\tresult = Result.err(error)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\teditor.store.applyDiff(reverseRecordsDiff(changes), { runCallbacks: false })\n\t\t},\n\t\t{ history: 'ignore' }\n\t)\n\n\tif (result.ok) {\n\t\treturn result.value\n\t} else {\n\t\tthrow result.error\n\t}\n}\n\nfunction getCameraFitXFitY(editor: Editor, cameraOptions: TLCameraOptions) {\n\tif (!cameraOptions.constraints) throw Error('Should have constraints here')\n\tconst {\n\t\tpadding: { x: px, y: py },\n\t} = cameraOptions.constraints\n\tconst vsb = editor.getViewportScreenBounds()\n\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\tconst zx = (vsb.w - px * 2) / bounds.w\n\tconst zy = (vsb.h - py * 2) / bounds.h\n\treturn { zx, zy }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tAtom,\n\tEMPTY_ARRAY,\n\tatom,\n\tcomputed,\n\treact,\n\ttransact,\n\tunsafe__withoutCapture,\n} from '@tldraw/state'\nimport {\n\tComputedCache,\n\tRecordType,\n\tStoreSideEffects,\n\tStoreSnapshot,\n\tUnknownRecord,\n\treverseRecordsDiff,\n} from '@tldraw/store'\nimport {\n\tCameraRecordType,\n\tInstancePageStateRecordType,\n\tPageRecordType,\n\tStyleProp,\n\tStylePropValue,\n\tTLArrowShape,\n\tTLAsset,\n\tTLAssetId,\n\tTLAssetPartial,\n\tTLBinding,\n\tTLBindingCreate,\n\tTLBindingId,\n\tTLBindingUpdate,\n\tTLCamera,\n\tTLCursor,\n\tTLCursorType,\n\tTLDOCUMENT_ID,\n\tTLDocument,\n\tTLFrameShape,\n\tTLGeoShape,\n\tTLGroupShape,\n\tTLHandle,\n\tTLINSTANCE_ID,\n\tTLImageAsset,\n\tTLInstance,\n\tTLInstancePageState,\n\tTLInstancePresence,\n\tTLNoteShape,\n\tTLPOINTER_ID,\n\tTLPage,\n\tTLPageId,\n\tTLParentId,\n\tTLRecord,\n\tTLShape,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLStore,\n\tTLStoreSnapshot,\n\tTLUnknownBinding,\n\tTLUnknownShape,\n\tTLVideoAsset,\n\tcreateBindingId,\n\tcreateShapeId,\n\tgetShapePropKeysByStyle,\n\tisPageId,\n\tisShapeId,\n} from '@tldraw/tlschema'\nimport {\n\tFileHelpers,\n\tIndexKey,\n\tJsonObject,\n\tPerformanceTracker,\n\tResult,\n\tZERO_INDEX_KEY,\n\tannotateError,\n\tassert,\n\tassertExists,\n\tbind,\n\tcompact,\n\tdebounce,\n\tdedupe,\n\texhaustiveSwitchError,\n\tfetch,\n\tgetIndexAbove,\n\tgetIndexBetween,\n\tgetIndices,\n\tgetIndicesAbove,\n\tgetIndicesBetween,\n\tgetOwnProperty,\n\thasOwnProperty,\n\tlast,\n\tlerp,\n\tmaxBy,\n\tminBy,\n\tsortById,\n\tsortByIndex,\n\tstructuredClone,\n\tuniqueId,\n} from '@tldraw/utils'\nimport EventEmitter from 'eventemitter3'\nimport {\n\tTLEditorSnapshot,\n\tTLLoadSnapshotOptions,\n\tgetSnapshot,\n\tloadSnapshot,\n} from '../config/TLEditorSnapshot'\nimport { TLUser, createTLUser } from '../config/createTLUser'\nimport { TLAnyBindingUtilConstructor, checkBindings } from '../config/defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from '../config/defaultShapes'\nimport {\n\tDEFAULT_ANIMATION_OPTIONS,\n\tDEFAULT_CAMERA_OPTIONS,\n\tINTERNAL_POINTER_IDS,\n\tLEFT_MOUSE_BUTTON,\n\tMIDDLE_MOUSE_BUTTON,\n\tRIGHT_MOUSE_BUTTON,\n\tSTYLUS_ERASER_BUTTON,\n\tZOOM_TO_FIT_PADDING,\n} from '../constants'\nimport { exportToSvg } from '../exports/exportToSvg'\nimport { getSvgAsImage } from '../exports/getSvgAsImage'\nimport { tlmenus } from '../globals/menus'\nimport { tltime } from '../globals/time'\nimport { TldrawOptions, defaultTldrawOptions } from '../options'\nimport { Box, BoxLike } from '../primitives/Box'\nimport { Mat, MatLike } from '../primitives/Mat'\nimport { Vec, VecLike } from '../primitives/Vec'\nimport { EASINGS } from '../primitives/easings'\nimport { Geometry2d } from '../primitives/geometry/Geometry2d'\nimport { Group2d } from '../primitives/geometry/Group2d'\nimport { intersectPolygonPolygon } from '../primitives/intersect'\nimport { PI, approximately, areAnglesCompatible, clamp, pointInPolygon } from '../primitives/utils'\nimport { ReadonlySharedStyleMap, SharedStyle, SharedStyleMap } from '../utils/SharedStylesMap'\nimport { areShapesContentEqual } from '../utils/areShapesContentEqual'\nimport { dataUrlToFile } from '../utils/assets'\nimport { debugFlags } from '../utils/debug-flags'\nimport {\n\tTLDeepLink,\n\tTLDeepLinkOptions,\n\tcreateDeepLinkString,\n\tparseDeepLinkString,\n} from '../utils/deepLinks'\nimport { getIncrementedName } from '../utils/getIncrementedName'\nimport { isAccelKey } from '../utils/keyboard'\nimport { getReorderingShapesChanges } from '../utils/reorderShapes'\nimport { TLTextOptions, TiptapEditor } from '../utils/richText'\nimport { applyRotationToSnapshotShapes, getRotationSnapshot } from '../utils/rotation'\nimport { BindingOnDeleteOptions, BindingUtil } from './bindings/BindingUtil'\nimport { bindingsIndex } from './derivations/bindingsIndex'\nimport { notVisibleShapes } from './derivations/notVisibleShapes'\nimport { parentsToChildren } from './derivations/parentsToChildren'\nimport { deriveShapeIdsInCurrentPage } from './derivations/shapeIdsInCurrentPage'\nimport { ClickManager } from './managers/ClickManager/ClickManager'\nimport { EdgeScrollManager } from './managers/EdgeScrollManager/EdgeScrollManager'\nimport { FocusManager } from './managers/FocusManager/FocusManager'\nimport { FontManager } from './managers/FontManager/FontManager'\nimport { HistoryManager } from './managers/HistoryManager/HistoryManager'\nimport { ScribbleManager } from './managers/ScribbleManager/ScribbleManager'\nimport { SnapManager } from './managers/SnapManager/SnapManager'\nimport { TextManager } from './managers/TextManager/TextManager'\nimport { TickManager } from './managers/TickManager/TickManager'\nimport { UserPreferencesManager } from './managers/UserPreferencesManager/UserPreferencesManager'\nimport { ShapeUtil, TLGeometryOpts, TLResizeMode } from './shapes/ShapeUtil'\nimport { RootState } from './tools/RootState'\nimport { StateNode, TLStateNodeConstructor } from './tools/StateNode'\nimport { TLContent } from './types/clipboard-types'\nimport { TLEventMap } from './types/emit-types'\nimport {\n\tTLEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLWheelEventInfo,\n} from './types/event-types'\nimport { TLExternalAsset, TLExternalContent } from './types/external-content'\nimport { TLHistoryBatchOptions } from './types/history-types'\nimport {\n\tOptionalKeys,\n\tRequiredKeys,\n\tTLCameraMoveOptions,\n\tTLCameraOptions,\n\tTLGetShapeAtPointOptions,\n\tTLImageExportOptions,\n\tTLSvgExportOptions,\n\tTLUpdatePointerOptions,\n} from './types/misc-types'\nimport { TLAdjacentDirection, TLResizeHandle } from './types/selection-types'\n\n/** @public */\nexport type TLResizeShapeOptions = Partial<{\n\tinitialBounds: Box\n\tscaleOrigin: VecLike\n\tscaleAxisRotation: number\n\tinitialShape: TLShape\n\tinitialPageTransform: MatLike\n\tdragHandle: TLResizeHandle\n\tisAspectRatioLocked: boolean\n\tmode: TLResizeMode\n\tskipStartAndEndCallbacks: boolean\n}>\n\n/** @public */\nexport interface TLEditorOptions {\n\t/**\n\t * The Store instance to use for keeping the app's data. This may be prepopulated, e.g. by loading\n\t * from a server or database.\n\t */\n\tstore: TLStore\n\t/**\n\t * An array of shapes to use in the editor. These will be used to create and manage shapes in the editor.\n\t */\n\tshapeUtils: readonly TLAnyShapeUtilConstructor[]\n\t/**\n\t * An array of bindings to use in the editor. These will be used to create and manage bindings in the editor.\n\t */\n\tbindingUtils: readonly TLAnyBindingUtilConstructor[]\n\t/**\n\t * An array of tools to use in the editor. These will be used to handle events and manage user interactions in the editor.\n\t */\n\ttools: readonly TLStateNodeConstructor[]\n\t/**\n\t * Should return a containing html element which has all the styles applied to the editor. If not\n\t * given, the body element will be used.\n\t */\n\tgetContainer(): HTMLElement\n\t/**\n\t * A user defined externally to replace the default user.\n\t */\n\tuser?: TLUser\n\t/**\n\t * The editor's initial active tool (or other state node id).\n\t */\n\tinitialState?: string\n\t/**\n\t * Whether to automatically focus the editor when it mounts.\n\t */\n\tautoFocus?: boolean\n\t/**\n\t * Whether to infer dark mode from the user's system preferences. Defaults to false.\n\t */\n\tinferDarkMode?: boolean\n\t/**\n\t * Options for the editor's camera.\n\t */\n\tcameraOptions?: Partial<TLCameraOptions>\n\ttextOptions?: TLTextOptions\n\toptions?: Partial<TldrawOptions>\n\tlicenseKey?: string\n\tfontAssetUrls?: { [key: string]: string | undefined }\n\t/**\n\t * Provides a way to hide shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * getShapeVisibility={(shape, editor) => shape.meta.hidden ? 'hidden' : 'inherit'}\n\t * ```\n\t *\n\t * - `'inherit' | undefined` - (default) The shape will be visible unless its parent is hidden.\n\t * - `'hidden'` - The shape will be hidden.\n\t * - `'visible'` - The shape will be visible.\n\t *\n\t * @param shape - The shape to check.\n\t * @param editor - The editor instance.\n\t */\n\tgetShapeVisibility?(\n\t\tshape: TLShape,\n\t\teditor: Editor\n\t): 'visible' | 'hidden' | 'inherit' | null | undefined\n}\n\n/**\n * Options for {@link Editor.(run:1)}.\n * @public\n */\nexport interface TLEditorRunOptions extends TLHistoryBatchOptions {\n\tignoreShapeLock?: boolean\n}\n\n/** @public */\nexport interface TLRenderingShape {\n\tid: TLShapeId\n\tshape: TLShape\n\tutil: ShapeUtil\n\tindex: number\n\tbackgroundIndex: number\n\topacity: number\n}\n\n/** @public */\nexport class Editor extends EventEmitter<TLEventMap> {\n\treadonly id = uniqueId()\n\tconstructor({\n\t\tstore,\n\t\tuser,\n\t\tshapeUtils,\n\t\tbindingUtils,\n\t\ttools,\n\t\tgetContainer,\n\t\tcameraOptions,\n\t\ttextOptions,\n\t\tinitialState,\n\t\tautoFocus,\n\t\tinferDarkMode,\n\t\toptions,\n\t\tgetShapeVisibility,\n\t\tfontAssetUrls,\n\t}: TLEditorOptions) {\n\t\tsuper()\n\n\t\tthis._getShapeVisibility = getShapeVisibility\n\n\t\tthis.options = { ...defaultTldrawOptions, ...options }\n\n\t\tthis.store = store\n\t\tthis.history = new HistoryManager<TLRecord>({\n\t\t\tstore,\n\t\t\tannotateError: (error: any) => {\n\t\t\t\tthis.annotateError(error, { origin: 'history.batch', willCrashApp: true })\n\t\t\t\tthis.crash(error)\n\t\t\t},\n\t\t})\n\n\t\tthis.snaps = new SnapManager(this)\n\n\t\tthis.disposables.add(this.timers.dispose)\n\n\t\tthis._cameraOptions.set({ ...DEFAULT_CAMERA_OPTIONS, ...cameraOptions })\n\n\t\tthis._textOptions = atom('text options', textOptions ?? null)\n\n\t\tthis.user = new UserPreferencesManager(user ?? createTLUser(), inferDarkMode ?? false)\n\t\tthis.disposables.add(() => this.user.dispose())\n\n\t\tthis.getContainer = getContainer\n\n\t\tthis.textMeasure = new TextManager(this)\n\t\tthis.disposables.add(() => this.textMeasure.dispose())\n\n\t\tthis.fonts = new FontManager(this, fontAssetUrls)\n\n\t\tthis._tickManager = new TickManager(this)\n\n\t\tclass NewRoot extends RootState {\n\t\t\tstatic override initial = initialState ?? ''\n\t\t}\n\n\t\tthis.root = new NewRoot(this)\n\t\tthis.root.children = {}\n\n\t\tthis.markEventAsHandled = this.markEventAsHandled.bind(this)\n\n\t\tconst allShapeUtils = checkShapesAndAddCore(shapeUtils)\n\n\t\tconst _shapeUtils = {} as Record<string, ShapeUtil<any>>\n\t\tconst _styleProps = {} as Record<string, Map<StyleProp<unknown>, string>>\n\t\tconst allStylesById = new Map<string, StyleProp<unknown>>()\n\n\t\tfor (const Util of allShapeUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_shapeUtils[Util.type] = util\n\n\t\t\tconst propKeysByStyle = getShapePropKeysByStyle(Util.props ?? {})\n\t\t\t_styleProps[Util.type] = propKeysByStyle\n\n\t\t\tfor (const style of propKeysByStyle.keys()) {\n\t\t\t\tif (!allStylesById.has(style.id)) {\n\t\t\t\t\tallStylesById.set(style.id, style)\n\t\t\t\t} else if (allStylesById.get(style.id) !== style) {\n\t\t\t\t\tthrow Error(\n\t\t\t\t\t\t`Multiple style props with id \"${style.id}\" in use. Style prop IDs must be unique.`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.shapeUtils = _shapeUtils\n\t\tthis.styleProps = _styleProps\n\n\t\tconst allBindingUtils = checkBindings(bindingUtils)\n\t\tconst _bindingUtils = {} as Record<string, BindingUtil<any>>\n\t\tfor (const Util of allBindingUtils) {\n\t\t\tconst util = new Util(this)\n\t\t\t_bindingUtils[Util.type] = util\n\t\t}\n\t\tthis.bindingUtils = _bindingUtils\n\n\t\t// Tools.\n\t\t// Accept tools from constructor parameters which may not conflict with the root note's default or\n\t\t// \"baked in\" tools, select and zoom.\n\t\tfor (const Tool of [...tools]) {\n\t\t\tif (hasOwnProperty(this.root.children!, Tool.id)) {\n\t\t\t\tthrow Error(`Can't override tool with id \"${Tool.id}\"`)\n\t\t\t}\n\t\t\tthis.root.children![Tool.id] = new Tool(this, this.root)\n\t\t}\n\n\t\tthis.scribbles = new ScribbleManager(this)\n\n\t\t// Cleanup\n\n\t\tconst cleanupInstancePageState = (\n\t\t\tprevPageState: TLInstancePageState,\n\t\t\tshapesNoLongerInPage: Set<TLShapeId>\n\t\t) => {\n\t\t\tlet nextPageState = null as null | TLInstancePageState\n\n\t\t\tconst selectedShapeIds = prevPageState.selectedShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (selectedShapeIds.length !== prevPageState.selectedShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.selectedShapeIds = selectedShapeIds\n\t\t\t}\n\n\t\t\tconst erasingShapeIds = prevPageState.erasingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (erasingShapeIds.length !== prevPageState.erasingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.erasingShapeIds = erasingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.hoveredShapeId && shapesNoLongerInPage.has(prevPageState.hoveredShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hoveredShapeId = null\n\t\t\t}\n\n\t\t\tif (prevPageState.editingShapeId && shapesNoLongerInPage.has(prevPageState.editingShapeId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.editingShapeId = null\n\t\t\t}\n\n\t\t\tconst hintingShapeIds = prevPageState.hintingShapeIds.filter(\n\t\t\t\t(id) => !shapesNoLongerInPage.has(id)\n\t\t\t)\n\t\t\tif (hintingShapeIds.length !== prevPageState.hintingShapeIds.length) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.hintingShapeIds = hintingShapeIds\n\t\t\t}\n\n\t\t\tif (prevPageState.focusedGroupId && shapesNoLongerInPage.has(prevPageState.focusedGroupId)) {\n\t\t\t\tif (!nextPageState) nextPageState = { ...prevPageState }\n\t\t\t\tnextPageState.focusedGroupId = null\n\t\t\t}\n\t\t\treturn nextPageState\n\t\t}\n\n\t\tthis.sideEffects = this.store.sideEffects\n\n\t\tlet deletedBindings = new Map<TLBindingId, BindingOnDeleteOptions<any>>()\n\t\tconst deletedShapeIds = new Set<TLShapeId>()\n\t\tconst invalidParents = new Set<TLShapeId>()\n\t\tlet invalidBindingTypes = new Set<string>()\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.registerOperationCompleteHandler(() => {\n\t\t\t\t// this needs to be cleared here because further effects may delete more shapes\n\t\t\t\t// and we want the next invocation of this handler to handle those separately\n\t\t\t\tdeletedShapeIds.clear()\n\n\t\t\t\tfor (const parentId of invalidParents) {\n\t\t\t\t\tinvalidParents.delete(parentId)\n\t\t\t\t\tconst parent = this.getShape(parentId)\n\t\t\t\t\tif (!parent) continue\n\n\t\t\t\t\tconst util = this.getShapeUtil(parent)\n\t\t\t\t\tconst changes = util.onChildrenChange?.(parent)\n\n\t\t\t\t\tif (changes?.length) {\n\t\t\t\t\t\tthis.updateShapes(changes)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (invalidBindingTypes.size) {\n\t\t\t\t\tconst t = invalidBindingTypes\n\t\t\t\t\tinvalidBindingTypes = new Set()\n\t\t\t\t\tfor (const type of t) {\n\t\t\t\t\t\tconst util = this.getBindingUtil(type)\n\t\t\t\t\t\tutil.onOperationComplete?.()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (deletedBindings.size) {\n\t\t\t\t\tconst t = deletedBindings\n\t\t\t\t\tdeletedBindings = new Map()\n\t\t\t\t\tfor (const opts of t.values()) {\n\t\t\t\t\t\tthis.getBindingUtil(opts.binding).onAfterDelete?.(opts)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.emit('update')\n\t\t\t})\n\t\t)\n\n\t\tthis.disposables.add(\n\t\t\tthis.sideEffects.register({\n\t\t\t\tshape: {\n\t\t\t\t\tafterChange: (shapeBefore, shapeAfter) => {\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shapeAfter)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tif (binding.fromId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t\treason: 'self',\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (binding.toId === shapeAfter.id) {\n\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\tshapeBefore,\n\t\t\t\t\t\t\t\t\tshapeAfter,\n\t\t\t\t\t\t\t\t\treason: 'self',\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if the shape's parent changed and it has a binding, update the binding\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId) {\n\t\t\t\t\t\t\tconst notifyBindingAncestryChange = (id: TLShapeId) => {\n\t\t\t\t\t\t\t\tconst descendantShape = this.getShape(id)\n\t\t\t\t\t\t\t\tif (!descendantShape) return\n\n\t\t\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(descendantShape)) {\n\t\t\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\n\t\t\t\t\t\t\t\t\tif (binding.fromId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeFromShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\treason: 'ancestry',\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (binding.toId === descendantShape.id) {\n\t\t\t\t\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterChangeToShape?.({\n\t\t\t\t\t\t\t\t\t\t\tbinding,\n\t\t\t\t\t\t\t\t\t\t\tshapeBefore: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\tshapeAfter: descendantShape,\n\t\t\t\t\t\t\t\t\t\t\treason: 'ancestry',\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnotifyBindingAncestryChange(shapeAfter.id)\n\t\t\t\t\t\t\tthis.visitDescendants(shapeAfter.id, notifyBindingAncestryChange)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// if this shape moved to a new page, clean up any previous page's instance state\n\t\t\t\t\t\tif (shapeBefore.parentId !== shapeAfter.parentId && isPageId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tconst allMovingIds = new Set([shapeBefore.id])\n\t\t\t\t\t\t\tthis.visitDescendants(shapeBefore.id, (id) => {\n\t\t\t\t\t\t\t\tallMovingIds.add(id)\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tfor (const instancePageState of this.getPageStates()) {\n\t\t\t\t\t\t\t\tif (instancePageState.pageId === shapeAfter.parentId) continue\n\t\t\t\t\t\t\t\tconst nextPageState = cleanupInstancePageState(instancePageState, allMovingIds)\n\n\t\t\t\t\t\t\t\tif (nextPageState) {\n\t\t\t\t\t\t\t\t\tthis.store.put([nextPageState])\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeBefore.parentId && isShapeId(shapeBefore.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeBefore.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (shapeAfter.parentId !== shapeBefore.parentId && isShapeId(shapeAfter.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shapeAfter.parentId)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (shape) => {\n\t\t\t\t\t\t// if we triggered this delete with a recursive call, don't do anything\n\t\t\t\t\t\tif (deletedShapeIds.has(shape.id)) return\n\t\t\t\t\t\t// if the deleted shape has a parent shape make sure we call it's onChildrenChange callback\n\t\t\t\t\t\tif (shape.parentId && isShapeId(shape.parentId)) {\n\t\t\t\t\t\t\tinvalidParents.add(shape.parentId)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedShapeIds.add(shape.id)\n\n\t\t\t\t\t\tconst deleteBindingIds: TLBindingId[] = []\n\t\t\t\t\t\tfor (const binding of this.getBindingsInvolvingShape(shape)) {\n\t\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\t\tdeleteBindingIds.push(binding.id)\n\t\t\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\t\t\tif (binding.fromId === shape.id) {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteFromShape?.({ binding, shape })\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: shape })\n\t\t\t\t\t\t\t\tutil.onBeforeDeleteToShape?.({ binding, shape })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (deleteBindingIds.length) {\n\t\t\t\t\t\t\tthis.deleteBindings(deleteBindingIds)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst deletedIds = new Set([shape.id])\n\t\t\t\t\t\tconst updates = compact(\n\t\t\t\t\t\t\tthis.getPageStates().map((pageState) => {\n\t\t\t\t\t\t\t\treturn cleanupInstancePageState(pageState, deletedIds)\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tif (updates.length) {\n\t\t\t\t\t\t\tthis.store.put(updates)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tbinding: {\n\t\t\t\t\tbeforeCreate: (binding) => {\n\t\t\t\t\t\tconst next = this.getBindingUtil(binding).onBeforeCreate?.({ binding })\n\t\t\t\t\t\tif (next) return next\n\t\t\t\t\t\treturn binding\n\t\t\t\t\t},\n\t\t\t\t\tafterCreate: (binding) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterCreate?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tconst updated = this.getBindingUtil(bindingAfter).onBeforeChange?.({\n\t\t\t\t\t\t\tbindingBefore,\n\t\t\t\t\t\t\tbindingAfter,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tif (updated) return updated\n\t\t\t\t\t\treturn bindingAfter\n\t\t\t\t\t},\n\t\t\t\t\tafterChange: (bindingBefore, bindingAfter) => {\n\t\t\t\t\t\tinvalidBindingTypes.add(bindingAfter.type)\n\t\t\t\t\t\tthis.getBindingUtil(bindingAfter).onAfterChange?.({ bindingBefore, bindingAfter })\n\t\t\t\t\t},\n\t\t\t\t\tbeforeDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onBeforeDelete?.({ binding })\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (binding) => {\n\t\t\t\t\t\tthis.getBindingUtil(binding).onAfterDelete?.({ binding })\n\t\t\t\t\t\tinvalidBindingTypes.add(binding.type)\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tpage: {\n\t\t\t\t\tafterCreate: (record) => {\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst _pageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tif (!this.store.has(cameraId)) {\n\t\t\t\t\t\t\tthis.store.put([CameraRecordType.create({ id: cameraId })])\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!this.store.has(_pageStateId)) {\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\tInstancePageStateRecordType.create({ id: _pageStateId, pageId: record.id }),\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tafterDelete: (record, source) => {\n\t\t\t\t\t\t// page was deleted, need to check whether it's the current page and select another one if so\n\t\t\t\t\t\tif (this.getInstanceState()?.currentPageId === record.id) {\n\t\t\t\t\t\t\tconst backupPageId = this.getPages().find((p) => p.id !== record.id)?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: backupPageId }])\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// delete the camera and state for the page if necessary\n\t\t\t\t\t\tconst cameraId = CameraRecordType.createId(record.id)\n\t\t\t\t\t\tconst instance_PageStateId = InstancePageStateRecordType.createId(record.id)\n\t\t\t\t\t\tthis.store.remove([cameraId, instance_PageStateId])\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance: {\n\t\t\t\t\tafterChange: (prev, next, source) => {\n\t\t\t\t\t\t// instance should never be updated to a page that no longer exists (this can\n\t\t\t\t\t\t// happen when undoing a change that involves switching to a page that has since\n\t\t\t\t\t\t// been deleted by another user)\n\t\t\t\t\t\tif (!this.store.has(next.currentPageId)) {\n\t\t\t\t\t\t\tconst backupPageId = this.store.has(prev.currentPageId)\n\t\t\t\t\t\t\t\t? prev.currentPageId\n\t\t\t\t\t\t\t\t: this.getPages()[0]?.id\n\t\t\t\t\t\t\tif (backupPageId) {\n\t\t\t\t\t\t\t\tthis.store.update(next.id, (instance) => ({\n\t\t\t\t\t\t\t\t\t...instance,\n\t\t\t\t\t\t\t\t\tcurrentPageId: backupPageId,\n\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t} else if (source === 'user') {\n\t\t\t\t\t\t\t\t// fall back to ensureStoreIsUsable:\n\t\t\t\t\t\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinstance_page_state: {\n\t\t\t\t\tafterChange: (prev, next) => {\n\t\t\t\t\t\tif (prev?.selectedShapeIds !== next?.selectedShapeIds) {\n\t\t\t\t\t\t\t// ensure that descendants and ancestors are not selected at the same time\n\t\t\t\t\t\t\tconst filtered = next.selectedShapeIds.filter((id) => {\n\t\t\t\t\t\t\t\tlet parentId = this.getShape(id)?.parentId\n\t\t\t\t\t\t\t\twhile (isShapeId(parentId)) {\n\t\t\t\t\t\t\t\t\tif (next.selectedShapeIds.includes(parentId)) {\n\t\t\t\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tparentId = this.getShape(parentId)?.parentId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn true\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tlet nextFocusedGroupId: null | TLShapeId = null\n\n\t\t\t\t\t\t\tif (filtered.length > 0) {\n\t\t\t\t\t\t\t\tconst commonGroupAncestor = this.findCommonAncestor(\n\t\t\t\t\t\t\t\t\tcompact(filtered.map((id) => this.getShape(id))),\n\t\t\t\t\t\t\t\t\t(shape) => this.isShapeOfType<TLGroupShape>(shape, 'group')\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t\tif (commonGroupAncestor) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = commonGroupAncestor\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (next?.focusedGroupId) {\n\t\t\t\t\t\t\t\t\tnextFocusedGroupId = next.focusedGroupId\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tfiltered.length !== next.selectedShapeIds.length ||\n\t\t\t\t\t\t\t\tnextFocusedGroupId !== next.focusedGroupId\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t...next,\n\t\t\t\t\t\t\t\t\t\tselectedShapeIds: filtered,\n\t\t\t\t\t\t\t\t\t\tfocusedGroupId: nextFocusedGroupId ?? null,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t)\n\n\t\tthis._currentPageShapeIds = deriveShapeIdsInCurrentPage(this.store, () =>\n\t\t\tthis.getCurrentPageId()\n\t\t)\n\t\tthis._parentIdsToChildIds = parentsToChildren(this.store)\n\n\t\tthis.disposables.add(\n\t\t\tthis.store.listen((changes) => {\n\t\t\t\tthis.emit('change', changes)\n\t\t\t})\n\t\t)\n\t\tthis.disposables.add(this.history.dispose)\n\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.ensureStoreIsUsable()\n\n\t\t\t\t// clear ephemeral state\n\t\t\t\tthis._updateCurrentPageState({\n\t\t\t\t\teditingShapeId: null,\n\t\t\t\t\thoveredShapeId: null,\n\t\t\t\t\terasingShapeIds: [],\n\t\t\t\t})\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\tif (initialState && this.root.children[initialState] === undefined) {\n\t\t\tthrow Error(`No state found for initialState \"${initialState}\".`)\n\t\t}\n\n\t\tthis.root.enter(undefined, 'initial')\n\n\t\tthis.edgeScrollManager = new EdgeScrollManager(this)\n\t\tthis.focusManager = new FocusManager(this, autoFocus)\n\t\tthis.disposables.add(this.focusManager.dispose.bind(this.focusManager))\n\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tthis.on('tick', this._flushEventsForTick)\n\n\t\tthis.timers.requestAnimationFrame(() => {\n\t\t\tthis._tickManager.start()\n\t\t})\n\n\t\tthis.performanceTracker = new PerformanceTracker()\n\n\t\tif (this.store.props.collaboration?.mode) {\n\t\t\tconst mode = this.store.props.collaboration.mode\n\t\t\tthis.disposables.add(\n\t\t\t\treact('update collaboration mode', () => {\n\t\t\t\t\tthis.store.put([{ ...this.getInstanceState(), isReadonly: mode.get() === 'readonly' }])\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\t}\n\n\tprivate readonly _getShapeVisibility?: TLEditorOptions['getShapeVisibility']\n\t@computed\n\tprivate getIsShapeHiddenCache() {\n\t\tif (!this._getShapeVisibility) return null\n\t\treturn this.store.createComputedCache<boolean, TLShape>('isShapeHidden', (shape: TLShape) => {\n\t\t\tconst visibility = this._getShapeVisibility!(shape, this)\n\t\t\tconst isParentHidden = PageRecordType.isId(shape.parentId)\n\t\t\t\t? false\n\t\t\t\t: this.isShapeHidden(shape.parentId)\n\n\t\t\tif (isParentHidden) return visibility !== 'visible'\n\t\t\treturn visibility === 'hidden'\n\t\t})\n\t}\n\tisShapeHidden(shapeOrId: TLShape | TLShapeId): boolean {\n\t\tif (!this._getShapeVisibility) return false\n\t\treturn !!this.getIsShapeHiddenCache!()!.get(\n\t\t\ttypeof shapeOrId === 'string' ? shapeOrId : shapeOrId.id\n\t\t)\n\t}\n\n\treadonly options: TldrawOptions\n\n\treadonly contextId = uniqueId()\n\n\t/**\n\t * The editor's store\n\t *\n\t * @public\n\t */\n\treadonly store: TLStore\n\n\t/**\n\t * The root state of the statechart.\n\t *\n\t * @public\n\t */\n\treadonly root: StateNode\n\n\t/**\n\t * Set a tool. Useful if you need to add a tool to the state chart on demand,\n\t * after the editor has already been initialized.\n\t *\n\t * @param Tool - The tool to set.\n\t *\n\t * @public\n\t */\n\tsetTool(Tool: TLStateNodeConstructor) {\n\t\tif (hasOwnProperty(this.root.children!, Tool.id)) {\n\t\t\tthrow Error(`Can't override tool with id \"${Tool.id}\"`)\n\t\t}\n\t\tthis.root.children![Tool.id] = new Tool(this, this.root)\n\t}\n\n\t/**\n\t * Remove a tool. Useful if you need to remove a tool from the state chart on demand,\n\t * after the editor has already been initialized.\n\t *\n\t * @param Tool - The tool to delete.\n\t *\n\t * @public\n\t */\n\tremoveTool(Tool: TLStateNodeConstructor) {\n\t\tif (hasOwnProperty(this.root.children!, Tool.id)) {\n\t\t\tdelete this.root.children![Tool.id]\n\t\t}\n\t}\n\n\t/**\n\t * A set of functions to call when the app is disposed.\n\t *\n\t * @public\n\t */\n\treadonly disposables = new Set<() => void>()\n\n\t/**\n\t * Whether the editor is disposed.\n\t *\n\t * @public\n\t */\n\tisDisposed = false\n\n\t/** @internal */\n\tprivate readonly _tickManager\n\n\t/**\n\t * A manager for the app's snapping feature.\n\t *\n\t * @public\n\t */\n\treadonly snaps: SnapManager\n\n\t/**\n\t * A manager for the any asynchronous events and making sure they're\n\t * cleaned up upon disposal.\n\t *\n\t * @public\n\t */\n\treadonly timers = tltime.forContext(this.contextId)\n\n\t/**\n\t * A manager for the user and their preferences.\n\t *\n\t * @public\n\t */\n\treadonly user: UserPreferencesManager\n\n\t/**\n\t * A helper for measuring text.\n\t *\n\t * @public\n\t */\n\treadonly textMeasure: TextManager\n\n\t/**\n\t * A utility for managing the set of fonts that should be rendered in the document.\n\t *\n\t * @public\n\t */\n\treadonly fonts: FontManager\n\n\t/**\n\t * A manager for the editor's scribbles.\n\t *\n\t * @public\n\t */\n\treadonly scribbles: ScribbleManager\n\n\t/**\n\t * A manager for side effects and correct state enforcement. See {@link @tldraw/store#StoreSideEffects} for details.\n\t *\n\t * @public\n\t */\n\treadonly sideEffects: StoreSideEffects<TLRecord>\n\n\t/**\n\t * A manager for moving the camera when the mouse is at the edge of the screen.\n\t *\n\t * @public\n\t */\n\tedgeScrollManager: EdgeScrollManager\n\n\t/**\n\t * A manager for ensuring correct focus. See FocusManager for details.\n\t *\n\t * @internal\n\t */\n\tprivate focusManager: FocusManager\n\n\t/**\n\t * The current HTML element containing the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * const container = editor.getContainer()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetContainer: () => HTMLElement\n\n\t/**\n\t * Dispose the editor.\n\t *\n\t * @public\n\t */\n\tdispose() {\n\t\tthis.disposables.forEach((dispose) => dispose())\n\t\tthis.disposables.clear()\n\t\tthis.store.dispose()\n\t\tthis.isDisposed = true\n\t}\n\n\t/* ------------------- Shape Utils ------------------ */\n\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tshapeUtils: { readonly [K in string]?: ShapeUtil<TLUnknownShape> }\n\n\tstyleProps: { [key: string]: Map<StyleProp<any>, string> }\n\n\t/**\n\t * Get a shape util from a shape itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getShapeUtil(myArrowShape)\n\t * const util = editor.getShapeUtil('arrow')\n\t * const util = editor.getShapeUtil<TLArrowShape>(myArrowShape)\n\t * const util = editor.getShapeUtil(TLArrowShape)('arrow')\n\t * ```\n\t *\n\t * @param shape - A shape, shape partial, or shape type.\n\t *\n\t * @public\n\t */\n\tgetShapeUtil<S extends TLUnknownShape>(shape: S | TLShapePartial<S>): ShapeUtil<S>\n\tgetShapeUtil<S extends TLUnknownShape>(type: S['type']): ShapeUtil<S>\n\tgetShapeUtil<T extends ShapeUtil>(type: T extends ShapeUtil<infer R> ? R['type'] : string): T\n\tgetShapeUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst shapeUtil = getOwnProperty(this.shapeUtils, type)\n\t\tassert(shapeUtil, `No shape util found for type \"${type}\"`)\n\t\treturn shapeUtil\n\t}\n\n\t/**\n\t * Returns true if the editor has a shape util for the given shape / shape type.\n\t *\n\t * @param shape - A shape, shape partial, or shape type.\n\t */\n\thasShapeUtil<S extends TLUnknownShape>(shape: S | TLShapePartial<S>): boolean\n\thasShapeUtil<S extends TLUnknownShape>(type: S['type']): boolean\n\thasShapeUtil<T extends ShapeUtil>(\n\t\ttype: T extends ShapeUtil<infer R> ? R['type'] : string\n\t): boolean\n\thasShapeUtil(arg: string | { type: string }): boolean {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\treturn hasOwnProperty(this.shapeUtils, type)\n\t}\n\n\t/* ------------------- Binding Utils ------------------ */\n\t/**\n\t * A map of shape utility classes (TLShapeUtils) by shape type.\n\t *\n\t * @public\n\t */\n\tbindingUtils: { readonly [K in string]?: BindingUtil<TLUnknownBinding> }\n\n\t/**\n\t * Get a binding util from a binding itself.\n\t *\n\t * @example\n\t * ```ts\n\t * const util = editor.getBindingUtil(myArrowBinding)\n\t * const util = editor.getBindingUtil('arrow')\n\t * const util = editor.getBindingUtil<TLArrowBinding>(myArrowBinding)\n\t * const util = editor.getBindingUtil(TLArrowBinding)('arrow')\n\t * ```\n\t *\n\t * @param binding - A binding, binding partial, or binding type.\n\t *\n\t * @public\n\t */\n\tgetBindingUtil<S extends TLUnknownBinding>(binding: S | { type: S['type'] }): BindingUtil<S>\n\tgetBindingUtil<S extends TLUnknownBinding>(type: S['type']): BindingUtil<S>\n\tgetBindingUtil<T extends BindingUtil>(\n\t\ttype: T extends BindingUtil<infer R> ? R['type'] : string\n\t): T\n\tgetBindingUtil(arg: string | { type: string }) {\n\t\tconst type = typeof arg === 'string' ? arg : arg.type\n\t\tconst bindingUtil = getOwnProperty(this.bindingUtils, type)\n\t\tassert(bindingUtil, `No binding util found for type \"${type}\"`)\n\t\treturn bindingUtil\n\t}\n\n\t/* --------------------- History -------------------- */\n\n\t/**\n\t * A manager for the app's history.\n\t *\n\t * @readonly\n\t */\n\tprotected readonly history: HistoryManager<TLRecord>\n\n\t/**\n\t * Undo to the last mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.undo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tundo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.undo()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can undo.\n\t *\n\t * @public\n\t */\n\t@computed getCanUndo(): boolean {\n\t\treturn this.history.getNumUndos() > 0\n\t}\n\n\t/**\n\t * Redo to the next mark.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.redo()\n\t * ```\n\t *\n\t * @public\n\t */\n\tredo(): this {\n\t\tthis._flushEventsForTick(0)\n\t\tthis.complete()\n\t\tthis.history.redo()\n\t\treturn this\n\t}\n\n\tclearHistory() {\n\t\tthis.history.clear()\n\t\treturn this\n\t}\n\n\t/**\n\t * Whether the app can redo.\n\t *\n\t * @public\n\t */\n\t@computed getCanRedo(): boolean {\n\t\treturn this.history.getNumRedos() > 0\n\t}\n\n\t/**\n\t * Create a new \"mark\", or stopping point, in the undo redo history. Creating a mark will clear\n\t * any redos. You typically want to do this just before a user interaction begins or is handled.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.markHistoryStoppingPoint()\n\t * editor.flipShapes(editor.getSelectedShapes())\n\t * ```\n\t * @example\n\t * ```ts\n\t * const beginRotateMark = editor.markHistoryStoppingPoint()\n\t * // if the use cancels the rotation, you can bail back to this mark\n\t * editor.bailToMark(beginRotateMark)\n\t * ```\n\t *\n\t * @public\n\t * @param name - The name of the mark, useful for debugging the undo/redo stacks\n\t * @returns a unique id for the mark that can be used with `squashToMark` or `bailToMark`.\n\t */\n\tmarkHistoryStoppingPoint(name?: string): string {\n\t\tconst id = `[${name ?? 'stop'}]_${uniqueId()}`\n\t\tthis.history._mark(id)\n\t\treturn id\n\t}\n\n\t/**\n\t * @internal this is only used to implement some backwards-compatibility logic. Should be fine to delete after 6 months or whatever.\n\t */\n\tgetMarkIdMatching(idSubstring: string) {\n\t\treturn this.history.getMarkIdMatching(idSubstring)\n\t}\n\n\t/**\n\t * Coalesces all changes since the given mark into a single change, removing any intermediate marks.\n\t *\n\t * This is useful if you need to 'compress' the recent history to simplify the undo/redo experience of a complex interaction.\n\t *\n\t * @example\n\t * ```ts\n\t * const bumpShapesMark = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.squashToMark(bumpShapesMark)\n\t * ```\n\t *\n\t * @param markId - The mark id to squash to.\n\t */\n\tsquashToMark(markId: string): this {\n\t\tthis.history.squashToMark(markId)\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the closest mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bail()\n\t * ```\n\t *\n\t * @public\n\t */\n\tbail() {\n\t\tthis.history.bail()\n\t\treturn this\n\t}\n\n\t/**\n\t * Undo to the given mark, discarding the changes so they cannot be redone.\n\t *\n\t * @example\n\t * ```ts\n\t * const beginDrag = editor.markHistoryStoppingPoint()\n\t * // ... some changes\n\t * editor.bailToMark(beginDrag)\n\t * ```\n\t *\n\t * @public\n\t */\n\tbailToMark(id: string): this {\n\t\tthis.history.bailToMark(id)\n\t\treturn this\n\t}\n\n\tprivate _shouldIgnoreShapeLock = false\n\n\t/**\n\t * Run a function in a transaction with optional options for context.\n\t * You can use the options to change the way that history is treated\n\t * or allow changes to locked shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * // updating with\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * }, { history: \"ignore\" })\n\t *\n\t * // forcing changes / deletions for locked shapes\n\t * editor.toggleLock([myShape])\n\t * editor.run(() => {\n\t * \teditor.updateShape({ ...myShape, x: 100 })\n\t * \teditor.deleteShape(myShape)\n\t * }, { ignoreShapeLock: true }, )\n\t * ```\n\t *\n\t * @param fn - The callback function to run.\n\t * @param opts - The options for the batch.\n\t *\n\t *\n\t * @public\n\t */\n\trun(fn: () => void, opts?: TLEditorRunOptions): this {\n\t\tconst previousIgnoreShapeLock = this._shouldIgnoreShapeLock\n\t\tthis._shouldIgnoreShapeLock = opts?.ignoreShapeLock ?? previousIgnoreShapeLock\n\t\ttry {\n\t\t\tthis.history.batch(fn, opts)\n\t\t} finally {\n\t\t\tthis._shouldIgnoreShapeLock = previousIgnoreShapeLock\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/* --------------------- Errors --------------------- */\n\n\t/** @internal */\n\tannotateError(\n\t\terror: unknown,\n\t\t{\n\t\t\torigin,\n\t\t\twillCrashApp,\n\t\t\ttags,\n\t\t\textras,\n\t\t}: {\n\t\t\torigin: string\n\t\t\twillCrashApp: boolean\n\t\t\ttags?: Record<string, string | boolean | number>\n\t\t\textras?: Record<string, unknown>\n\t\t}\n\t): this {\n\t\tconst defaultAnnotations = this.createErrorAnnotations(origin, willCrashApp)\n\t\tannotateError(error, {\n\t\t\ttags: { ...defaultAnnotations.tags, ...tags },\n\t\t\textras: { ...defaultAnnotations.extras, ...extras },\n\t\t})\n\t\tif (willCrashApp) {\n\t\t\tthis.store.markAsPossiblyCorrupted()\n\t\t}\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tcreateErrorAnnotations(origin: string, willCrashApp: boolean | 'unknown') {\n\t\ttry {\n\t\t\tconst editingShapeId = this.getEditingShapeId()\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {\n\t\t\t\t\tactiveStateNode: this.root.getPath(),\n\t\t\t\t\tselectedShapes: this.getSelectedShapes().map((s) => {\n\t\t\t\t\t\tconst { props, ...rest } = s\n\t\t\t\t\t\tconst { text: _text, richText: _richText, ...restProps } = props as any\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...rest,\n\t\t\t\t\t\t\tprops: restProps,\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tselectionCount: this.getSelectedShapes().length,\n\t\t\t\t\teditingShape: editingShapeId ? this.getShape(editingShapeId) : undefined,\n\t\t\t\t\tinputs: this.inputs,\n\t\t\t\t\tpageState: this.getCurrentPageState(),\n\t\t\t\t\tinstanceState: this.getInstanceState(),\n\t\t\t\t\tcollaboratorCount: this.getCollaboratorsOnCurrentPage().length,\n\t\t\t\t},\n\t\t\t}\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\ttags: {\n\t\t\t\t\torigin: origin,\n\t\t\t\t\twillCrashApp,\n\t\t\t\t},\n\t\t\t\textras: {},\n\t\t\t}\n\t\t}\n\t}\n\n\t/** @internal */\n\tprivate _crashingError: unknown | null = null\n\n\t/**\n\t * We can't use an `atom` here because there's a chance that when `crashAndReportError` is called,\n\t * we're in a transaction that's about to be rolled back due to the same error we're currently\n\t * reporting.\n\t *\n\t * Instead, to listen to changes to this value, you need to listen to app's `crash` event.\n\t *\n\t * @internal\n\t */\n\tgetCrashingError() {\n\t\treturn this._crashingError\n\t}\n\n\t/** @internal */\n\tcrash(error: unknown): this {\n\t\tthis._crashingError = error\n\t\tthis.store.markAsPossiblyCorrupted()\n\t\tthis.emit('crash', { error })\n\t\treturn this\n\t}\n\n\t/* ------------------- Statechart ------------------- */\n\n\t/**\n\t * The editor's current path of active states.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPath() // \"select.idle\"\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPath() {\n\t\treturn this.root.getPath().split('root.')[1]\n\t}\n\n\t/**\n\t * Get whether a certain tool (or other state node) is currently active.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isIn('select')\n\t * editor.isIn('select.brushing')\n\t * ```\n\t *\n\t * @param path - The path of active states, separated by periods.\n\t *\n\t * @public\n\t */\n\tisIn(path: string): boolean {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return true\n\t\t\tconst current = state.getCurrent()\n\t\t\tif (current?.id === id) {\n\t\t\t\tif (ids.length === 0) return true\n\t\t\t\tstate = current\n\t\t\t\tcontinue\n\t\t\t} else return false\n\t\t}\n\t\treturn false\n\t}\n\n\t/**\n\t * Get whether the state node is in any of the given active paths.\n\t *\n\t * @example\n\t * ```ts\n\t * state.isInAny('select', 'erase')\n\t * state.isInAny('select.brushing', 'erase.idle')\n\t * ```\n\t *\n\t * @public\n\t */\n\tisInAny(...paths: string[]): boolean {\n\t\treturn paths.some((path) => this.isIn(path))\n\t}\n\n\t/**\n\t * Set the selected tool.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentTool('hand')\n\t * editor.setCurrentTool('hand', { date: Date.now() })\n\t * ```\n\t *\n\t * @param id - The id of the tool to select.\n\t * @param info - Arbitrary data to pass along into the transition.\n\t *\n\t * @public\n\t */\n\tsetCurrentTool(id: string, info = {}): this {\n\t\tthis.root.transition(id, info)\n\t\treturn this\n\t}\n\n\t/**\n\t * The current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentTool(): StateNode {\n\t\treturn this.root.getCurrent()!\n\t}\n\n\t/**\n\t * The id of the current selected tool.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentToolId(): string {\n\t\tconst currentTool = this.getCurrentTool()\n\t\tif (!currentTool) return ''\n\t\treturn currentTool.getCurrentToolIdMask() ?? currentTool.id\n\t}\n\n\t/**\n\t * Get a descendant by its path.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getStateDescendant('select')\n\t * editor.getStateDescendant('select.brushing')\n\t * ```\n\t *\n\t * @param path - The descendant's path of state ids, separated by periods.\n\t *\n\t * @public\n\t */\n\tgetStateDescendant<T extends StateNode>(path: string): T | undefined {\n\t\tconst ids = path.split('.').reverse()\n\t\tlet state = this.root as StateNode\n\t\twhile (ids.length > 0) {\n\t\t\tconst id = ids.pop()\n\t\t\tif (!id) return state as T\n\t\t\tconst childState = state.children?.[id]\n\t\t\tif (!childState) return undefined\n\t\t\tstate = childState\n\t\t}\n\t\treturn state as T\n\t}\n\n\t/* ---------------- Document Settings --------------- */\n\n\t/**\n\t * The global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\t@computed getDocumentSettings() {\n\t\treturn this.store.get(TLDOCUMENT_ID)!\n\t}\n\n\t/**\n\t * Update the global document settings that apply to all users.\n\t *\n\t * @public\n\t **/\n\tupdateDocumentSettings(settings: Partial<TLDocument>): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getDocumentSettings(), ...settings }])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/* ----------------- Instance State ----------------- */\n\n\t/**\n\t * The current instance's state.\n\t *\n\t * @public\n\t */\n\t@computed getInstanceState(): TLInstance {\n\t\treturn this.store.get(TLINSTANCE_ID)!\n\t}\n\n\t/**\n\t * Update the instance's state.\n\t *\n\t * @param partial - A partial object to update the instance state with.\n\t * @param historyOptions - History batch options.\n\t *\n\t * @public\n\t */\n\tupdateInstanceState(\n\t\tpartial: Partial<Omit<TLInstance, 'currentPageId'>>,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tthis._updateInstanceState(partial, { history: 'ignore', ...historyOptions })\n\n\t\tif (partial.isChangingStyle !== undefined) {\n\t\t\tclearTimeout(this._isChangingStyleTimeout)\n\t\t\tif (partial.isChangingStyle === true) {\n\t\t\t\t// If we've set to true, set a new reset timeout to change the value back to false after 1 seconds\n\t\t\t\tthis._isChangingStyleTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\tthis._updateInstanceState({ isChangingStyle: false }, { history: 'ignore' })\n\t\t\t\t}, 1000)\n\t\t\t}\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateInstanceState(\n\t\tpartial: Partial<Omit<TLInstance, 'currentPageId'>>,\n\t\topts?: TLHistoryBatchOptions\n\t) {\n\t\tthis.run(() => {\n\t\t\tthis.store.put([\n\t\t\t\t{\n\t\t\t\t\t...this.getInstanceState(),\n\t\t\t\t\t...partial,\n\t\t\t\t},\n\t\t\t])\n\t\t}, opts)\n\t}\n\n\t/** @internal */\n\tprivate _isChangingStyleTimeout = -1 as any\n\n\t// Menus\n\n\tmenus = tlmenus.forContext(this.contextId)\n\n\t/* --------------------- Cursor --------------------- */\n\n\t/**\n\t * Set the cursor.\n\t *\n\t * @param cursor - The cursor to set.\n\t * @public\n\t */\n\tsetCursor(cursor: Partial<TLCursor>) {\n\t\tthis.updateInstanceState({ cursor: { ...this.getInstanceState().cursor, ...cursor } })\n\t\treturn this\n\t}\n\n\t/* ------------------- Page State ------------------- */\n\n\t/**\n\t * Page states.\n\t *\n\t * @public\n\t */\n\t@computed getPageStates(): TLInstancePageState[] {\n\t\treturn this._getPageStatesQuery().get()\n\t}\n\n\t/** @internal */\n\t@computed private _getPageStatesQuery() {\n\t\treturn this.store.query.records('instance_page_state')\n\t}\n\n\t/**\n\t * The current page state.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageState(): TLInstancePageState {\n\t\treturn this.store.get(this._getCurrentPageStateId())!\n\t}\n\n\t/** @internal */\n\t@computed private _getCurrentPageStateId() {\n\t\treturn InstancePageStateRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * Update this instance's page state.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateCurrentPageState({ id: 'page1', editingShapeId: 'shape:123' })\n\t * ```\n\t *\n\t * @param partial - The partial of the page state object containing the changes.\n\t *\n\t * @public\n\t */\n\tupdateCurrentPageState(\n\t\tpartial: Partial<\n\t\t\tOmit<TLInstancePageState, 'selectedShapeIds' | 'editingShapeId' | 'pageId' | 'focusedGroupId'>\n\t\t>\n\t): this {\n\t\tthis._updateCurrentPageState(partial)\n\t\treturn this\n\t}\n\t_updateCurrentPageState(partial: Partial<Omit<TLInstancePageState, 'selectedShapeIds'>>) {\n\t\tthis.store.update(partial.id ?? this.getCurrentPageState().id, (state) => ({\n\t\t\t...state,\n\t\t\t...partial,\n\t\t}))\n\t}\n\n\t/**\n\t * The current selected ids.\n\t *\n\t * @public\n\t */\n\t@computed getSelectedShapeIds() {\n\t\treturn this.getCurrentPageState().selectedShapeIds\n\t}\n\n\t/**\n\t * An array containing all of the currently selected shapes.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getSelectedShapes(): TLShape[] {\n\t\treturn compact(this.getSelectedShapeIds().map((id) => this.store.get(id)))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setSelectedShapes(['id1'])\n\t * editor.setSelectedShapes(['id1', 'id2'])\n\t * ```\n\t *\n\t * @param shapes - The shape (or shape ids) to select.\n\t *\n\t * @public\n\t */\n\tsetSelectedShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tconst ids = shapes.map((shape) => (typeof shape === 'string' ? shape : shape.id))\n\t\t\t\tconst { selectedShapeIds: prevSelectedShapeIds } = this.getCurrentPageState()\n\t\t\t\tconst prevSet = new Set(prevSelectedShapeIds)\n\n\t\t\t\tif (ids.length === prevSet.size && ids.every((id) => prevSet.has(id))) return null\n\n\t\t\t\tthis.store.put([{ ...this.getCurrentPageState(), selectedShapeIds: ids }])\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Determine whether or not any of a shape's ancestors are selected.\n\t *\n\t * @param shape - The shape (or shape id) of the shape to check.\n\t *\n\t * @public\n\t */\n\tisAncestorSelected(shape: TLShape | TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : (shape?.id ?? null)\n\t\tconst _shape = this.getShape(id)\n\t\tif (!_shape) return false\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn !!this.findShapeAncestor(_shape, (parent) => selectedShapeIds.includes(parent.id))\n\t}\n\n\t/**\n\t * Select one or more shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.select('id1')\n\t * editor.select('id1', 'id2')\n\t * ```\n\t *\n\t * @param shapes - The shape (or the shape ids) to select.\n\t *\n\t * @public\n\t */\n\tselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tthis.setSelectedShapes(ids)\n\t\treturn this\n\t}\n\n\t/**\n\t * Remove a shape from the existing set of selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deselect(shape.id)\n\t * ```\n\t *\n\t * @public\n\t */\n\tdeselect(...shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tif (selectedShapeIds.length > 0 && ids.length > 0) {\n\t\t\tthis.setSelectedShapes(selectedShapeIds.filter((id) => !ids.includes(id)))\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Select all shapes. If the user has selected shapes that share a parent,\n\t * select all shapes within that parent. If the user has not selected any shapes,\n\t * or if the shapes shapes are only on select all shapes on the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectAll()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectAll(): this {\n\t\tlet parentToSelectWithinId: TLParentId | null = null\n\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\n\t\t// If we have selected shapes, try to find a parent to select within\n\t\tif (selectedShapeIds.length > 0) {\n\t\t\tfor (const id of selectedShapeIds) {\n\t\t\t\tconst shape = this.getShape(id)\n\t\t\t\tif (!shape) continue\n\t\t\t\tif (parentToSelectWithinId === null) {\n\t\t\t\t\t// If we haven't found a parent yet, set this parent as the parent to select within\n\t\t\t\t\tparentToSelectWithinId = shape.parentId\n\t\t\t\t} else if (parentToSelectWithinId !== shape.parentId) {\n\t\t\t\t\t// If we've found two different parents, we can't select all, do nothing\n\t\t\t\t\treturn this\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we haven't found a parent from our selected shapes, select the current page\n\t\tif (!parentToSelectWithinId) {\n\t\t\tparentToSelectWithinId = this.getCurrentPageId()\n\t\t}\n\n\t\t// Select all the unlocked shapes within the parent\n\t\tconst ids = this.getSortedChildIdsForParent(parentToSelectWithinId)\n\t\tif (ids.length <= 0) return this\n\t\tthis.setSelectedShapes(this._getUnlockedShapeIds(ids))\n\t\treturn this\n\t}\n\n\t/**\n\t * Select the next shape in the reading order or in cardinal order.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectAdjacentShape('next')\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectAdjacentShape(direction: TLAdjacentDirection) {\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tconst firstParentId = selectedShapeIds[0] ? this.getShape(selectedShapeIds[0])?.parentId : null\n\t\tconst isSelectedWithinContainer =\n\t\t\tfirstParentId &&\n\t\t\tselectedShapeIds.every((shapeId) => this.getShape(shapeId)?.parentId === firstParentId) &&\n\t\t\t!isPageId(firstParentId)\n\t\tconst filteredShapes = isSelectedWithinContainer\n\t\t\t? this.getCurrentPageShapes().filter((shape) => shape.parentId === firstParentId)\n\t\t\t: this.getCurrentPageShapes().filter((shape) => isPageId(shape.parentId))\n\t\tconst readingOrderShapes = isSelectedWithinContainer\n\t\t\t? this._getShapesInReadingOrder(filteredShapes)\n\t\t\t: this.getCurrentPageShapesInReadingOrder()\n\t\tconst currentShapeId: TLShapeId | undefined =\n\t\t\tselectedShapeIds.length === 1\n\t\t\t\t? selectedShapeIds[0]\n\t\t\t\t: readingOrderShapes.find((shape) => selectedShapeIds.includes(shape.id))?.id\n\n\t\tlet adjacentShapeId: TLShapeId\n\t\tif (direction === 'next' || direction === 'prev') {\n\t\t\tconst shapeIds = readingOrderShapes.map((shape) => shape.id)\n\n\t\t\tconst currentIndex = currentShapeId ? shapeIds.indexOf(currentShapeId) : -1\n\t\t\tconst adjacentIndex =\n\t\t\t\t(currentIndex + (direction === 'next' ? 1 : -1) + shapeIds.length) % shapeIds.length\n\t\t\tadjacentShapeId = shapeIds[adjacentIndex]\n\t\t} else {\n\t\t\tif (!currentShapeId) return\n\t\t\tadjacentShapeId = this.getNearestAdjacentShape(filteredShapes, currentShapeId, direction)\n\t\t}\n\n\t\tconst shape = this.getShape(adjacentShapeId)\n\t\tif (!shape) return\n\n\t\tthis._selectShapesAndZoom([shape.id])\n\t}\n\n\t/**\n\t * Generates a reading order for shapes based on rows grouping.\n\t * Tries to keep a natural reading order (left-to-right, top-to-bottom).\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapesInReadingOrder(): TLShape[] {\n\t\tconst shapes = this.getCurrentPageShapes().filter((shape) => isPageId(shape.parentId))\n\t\treturn this._getShapesInReadingOrder(shapes)\n\t}\n\n\tprivate _getShapesInReadingOrder(shapes: TLShape[]): TLShape[] {\n\t\tconst SHALLOW_ANGLE = 20\n\t\tconst ROW_THRESHOLD = 100\n\n\t\tconst tabbableShapes = shapes.filter((shape) => this.getShapeUtil(shape).canTabTo(shape))\n\n\t\tif (tabbableShapes.length <= 1) return tabbableShapes\n\n\t\tconst shapesWithCenters = tabbableShapes.map((shape) => ({\n\t\t\tshape,\n\t\t\tcenter: this.getShapePageBounds(shape)!.center,\n\t\t}))\n\t\tshapesWithCenters.sort((a, b) => a.center.y - b.center.y)\n\n\t\tconst rows: Array<typeof shapesWithCenters> = []\n\n\t\t// First, group shapes into rows based on y-coordinates.\n\t\tfor (const shapeWithCenter of shapesWithCenters) {\n\t\t\tlet rowIndex = -1\n\t\t\tfor (let i = rows.length - 1; i >= 0; i--) {\n\t\t\t\tconst row = rows[i]\n\t\t\t\tconst lastShapeInRow = row[row.length - 1]\n\n\t\t\t\t// If the shape is close enough vertically to the last shape in this row.\n\t\t\t\tif (Math.abs(shapeWithCenter.center.y - lastShapeInRow.center.y) < ROW_THRESHOLD) {\n\t\t\t\t\trowIndex = i\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If no suitable row found, create a new row.\n\t\t\tif (rowIndex === -1) {\n\t\t\t\trows.push([shapeWithCenter])\n\t\t\t} else {\n\t\t\t\trows[rowIndex].push(shapeWithCenter)\n\t\t\t}\n\t\t}\n\n\t\t// Then, sort each row by x-coordinate (left-to-right).\n\t\tfor (const row of rows) {\n\t\t\trow.sort((a, b) => a.center.x - b.center.x)\n\t\t}\n\n\t\t// Finally, apply angle/distance weight adjustments within rows for closely positioned shapes.\n\t\tfor (const row of rows) {\n\t\t\tif (row.length <= 2) continue\n\n\t\t\tfor (let i = 0; i < row.length - 2; i++) {\n\t\t\t\tconst currentShape = row[i]\n\t\t\t\tconst nextShape = row[i + 1]\n\t\t\t\tconst nextNextShape = row[i + 2]\n\n\t\t\t\t// Only consider adjustment if the next two shapes are relatively close to each other.\n\t\t\t\tconst dist1 = Vec.Dist2(currentShape.center, nextShape.center)\n\t\t\t\tconst dist2 = Vec.Dist2(currentShape.center, nextNextShape.center)\n\n\t\t\t\t// Check if the 2nd shape is actually closer to the current shape.\n\t\t\t\tif (dist2 < dist1 * 0.9) {\n\t\t\t\t\t// Check if it's a shallow enough angle.\n\t\t\t\t\tconst angle = Math.abs(\n\t\t\t\t\t\tVec.Angle(currentShape.center, nextNextShape.center) * (180 / Math.PI)\n\t\t\t\t\t)\n\t\t\t\t\tif (angle <= SHALLOW_ANGLE) {\n\t\t\t\t\t\t// Swap swap.\n\t\t\t\t\t\t;[row[i + 1], row[i + 2]] = [row[i + 2], row[i + 1]]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn rows.flat().map((item) => item.shape)\n\t}\n\n\t/**\n\t * Find the nearest adjacent shape in a specific direction.\n\t *\n\t * @public\n\t */\n\tgetNearestAdjacentShape(\n\t\tshapes: TLShape[],\n\t\tcurrentShapeId: TLShapeId,\n\t\tdirection: 'left' | 'right' | 'up' | 'down'\n\t): TLShapeId {\n\t\tconst directionToAngle = { right: 0, left: 180, down: 90, up: 270 }\n\t\tconst currentShape = this.getShape(currentShapeId)\n\t\tif (!currentShape) return currentShapeId\n\n\t\tconst tabbableShapes = shapes.filter(\n\t\t\t(shape) => this.getShapeUtil(shape).canTabTo(shape) && shape.id !== currentShapeId\n\t\t)\n\t\tif (!tabbableShapes.length) return currentShapeId\n\n\t\tconst currentCenter = this.getShapePageBounds(currentShape)!.center\n\t\tconst shapesWithCenters = tabbableShapes.map((shape) => ({\n\t\t\tshape,\n\t\t\tcenter: this.getShapePageBounds(shape)!.center,\n\t\t}))\n\n\t\t// Filter shapes that are in the same direction.\n\t\tconst shapesInDirection = shapesWithCenters.filter(({ center }) => {\n\t\t\tconst isRight = center.x > currentCenter.x\n\t\t\tconst isDown = center.y > currentCenter.y\n\t\t\tconst xDist = center.x - currentCenter.x\n\t\t\tconst yDist = center.y - currentCenter.y\n\t\t\tconst isInXDirection = Math.abs(yDist) < Math.abs(xDist) * 2\n\t\t\tconst isInYDirection = Math.abs(xDist) < Math.abs(yDist) * 2\n\t\t\tif (direction === 'left' || direction === 'right') {\n\t\t\t\treturn isInXDirection && (direction === 'right' ? isRight : !isRight)\n\t\t\t}\n\t\t\tif (direction === 'up' || direction === 'down') {\n\t\t\t\treturn isInYDirection && (direction === 'down' ? isDown : !isDown)\n\t\t\t}\n\t\t})\n\n\t\tif (shapesInDirection.length === 0) return currentShapeId\n\n\t\t// Ok, now score that subset of shapes.\n\t\tconst lowestScoringShape = minBy(shapesInDirection, ({ center }) => {\n\t\t\t// Distance is the primary weighting factor.\n\t\t\tconst distance = Vec.Dist2(currentCenter, center)\n\n\t\t\t// Distance along the primary axis.\n\t\t\tconst dirProp = ['left', 'right'].includes(direction) ? 'x' : 'y'\n\t\t\tconst directionalDistance = Math.abs(center[dirProp] - currentCenter[dirProp])\n\n\t\t\t// Distance off the perpendicular to the primary axis.\n\t\t\tconst offProp = ['left', 'right'].includes(direction) ? 'y' : 'x'\n\t\t\tconst offAxisDeviation = Math.abs(center[offProp] - currentCenter[offProp])\n\n\t\t\t// Angle in degrees\n\t\t\tconst angle = Math.abs(Vec.Angle(currentCenter, center) * (180 / Math.PI))\n\t\t\tconst angleDeviation = Math.abs(angle - directionToAngle[direction])\n\n\t\t\t// Calculate final score (lower is better).\n\t\t\t// Weight factors to prioritize:\n\t\t\t// 1. Shapes directly in line with the current shape\n\t\t\t// 2. Shapes closer to the current shape\n\t\t\t// 3. Shapes with less angular deviation from the primary direction\n\t\t\treturn (\n\t\t\t\tdistance * 1.0 + // Base distance\n\t\t\t\toffAxisDeviation * 2.0 + // Heavy penalty for off-axis deviation\n\t\t\t\t(distance - directionalDistance) * 1.5 + // Penalty for diagonal distance\n\t\t\t\tangleDeviation * 0.5\n\t\t\t) // Slight penalty for angular deviation\n\t\t})\n\n\t\treturn lowestScoringShape!.shape.id\n\t}\n\n\tselectParentShape() {\n\t\tconst selectedShape = this.getOnlySelectedShape()\n\t\tif (!selectedShape) return\n\t\tconst parentShape = this.getShape(selectedShape.parentId)\n\t\tif (!parentShape) return\n\t\tthis._selectShapesAndZoom([parentShape.id])\n\t}\n\n\tselectFirstChildShape() {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\t\tif (!selectedShapes.length) return\n\t\tconst selectedShape = selectedShapes[0]\n\t\tconst children = this.getSortedChildIdsForParent(selectedShape.id)\n\t\t\t.map((id) => this.getShape(id))\n\t\t\t.filter((i) => i) as TLShape[]\n\t\tconst sortedChildren = this._getShapesInReadingOrder(children)\n\t\tif (sortedChildren.length === 0) return\n\t\tthis._selectShapesAndZoom([sortedChildren[0].id])\n\t}\n\n\tprivate _selectShapesAndZoom(ids: TLShapeId[]) {\n\t\tthis.setSelectedShapes(ids)\n\t\tthis.zoomToSelectionIfOffscreen(256, {\n\t\t\tanimation: {\n\t\t\t\tduration: this.options.animationMediumMs,\n\t\t\t},\n\t\t\tinset: 0,\n\t\t})\n\t}\n\n\t/**\n\t * Clear the selection.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.selectNone()\n\t * ```\n\t *\n\t * @public\n\t */\n\tselectNone(): this {\n\t\tif (this.getSelectedShapeIds().length > 0) {\n\t\t\tthis.setSelectedShapes([])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The id of the app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape's id.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShapeId(): TLShapeId | null {\n\t\treturn this.getOnlySelectedShape()?.id ?? null\n\t}\n\n\t/**\n\t * The app's only selected shape.\n\t *\n\t * @returns Null if there is no shape or more than one selected shape, otherwise the selected shape.\n\t *\n\t * @public\n\t * @readonly\n\t */\n\t@computed getOnlySelectedShape(): TLShape | null {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\t\treturn selectedShapes.length === 1 ? selectedShapes[0] : null\n\t}\n\n\t/**\n\t * Get the page bounds of all the provided shapes.\n\t *\n\t * @public\n\t */\n\tgetShapesPageBounds(shapeIds: TLShapeId[]): Box | null {\n\t\tconst bounds = compact(shapeIds.map((id) => this.getShapePageBounds(id)))\n\t\tif (bounds.length === 0) return null\n\t\treturn Box.Common(bounds)\n\t}\n\n\t/**\n\t * The current page bounds of all the selected shapes. If the\n\t * selection is rotated, then these bounds are the axis-aligned\n\t * box that the rotated bounds would fit inside of.\n\t *\n\t * @readonly\n\t *\n\t * @public\n\t */\n\t@computed getSelectionPageBounds(): Box | null {\n\t\treturn this.getShapesPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\tgetSelectionScreenBounds(): Box | undefined {\n\t\tconst bounds = this.getSelectionPageBounds()\n\t\tif (!bounds) return undefined\n\t\tconst { x, y } = this.pageToScreen(bounds.point)\n\t\tconst zoom = this.getZoomLevel()\n\t\treturn new Box(x, y, bounds.width * zoom, bounds.height * zoom)\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesSharedRotation(shapeIds: TLShapeId[]) {\n\t\tlet foundFirst = false // annoying but we can't use an i===0 check because we need to skip over undefineds\n\t\tlet rotation = 0\n\t\tfor (let i = 0, n = shapeIds.length; i < n; i++) {\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[i])\n\t\t\tif (!pageTransform) continue\n\t\t\tif (foundFirst) {\n\t\t\t\tif (pageTransform.rotation() !== rotation) {\n\t\t\t\t\t// There are at least 2 different rotations, so the common rotation is zero\n\t\t\t\t\treturn 0\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// First rotation found\n\t\t\t\tfoundFirst = true\n\t\t\t\trotation = pageTransform.rotation()\n\t\t\t}\n\t\t}\n\n\t\treturn rotation\n\t}\n\n\t/**\n\t * The rotation of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotation(): number {\n\t\treturn this.getShapesSharedRotation(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tgetShapesRotatedPageBounds(shapeIds: TLShapeId[]): Box | undefined {\n\t\tif (shapeIds.length === 0) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tconst selectionRotation = this.getShapesSharedRotation(shapeIds)\n\t\tif (selectionRotation === 0) {\n\t\t\treturn this.getShapesPageBounds(shapeIds) ?? undefined\n\t\t}\n\n\t\tif (shapeIds.length === 1) {\n\t\t\tconst bounds = this.getShapeGeometry(shapeIds[0]).bounds.clone()\n\t\t\tconst pageTransform = this.getShapePageTransform(shapeIds[0])!\n\t\t\tbounds.point = pageTransform.applyToPoint(bounds.point)\n\t\t\treturn bounds\n\t\t}\n\n\t\t// need to 'un-rotate' all the outlines of the existing nodes so we can fit them inside a box\n\t\tconst boxFromRotatedVertices = Box.FromPoints(\n\t\t\tshapeIds\n\t\t\t\t.flatMap((id) => {\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(id)\n\t\t\t\t\tif (!pageTransform) return []\n\t\t\t\t\treturn pageTransform.applyToPoints(this.getShapeGeometry(id).bounds.corners)\n\t\t\t\t})\n\t\t\t\t.map((p) => p.rot(-selectionRotation))\n\t\t)\n\t\t// now position box so that it's top-left corner is in the right place\n\t\tboxFromRotatedVertices.point = boxFromRotatedVertices.point.rot(selectionRotation)\n\t\treturn boxFromRotatedVertices\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedPageBounds(): Box | undefined {\n\t\treturn this.getShapesRotatedPageBounds(this.getSelectedShapeIds())\n\t}\n\n\t/**\n\t * The bounds of the selection bounding box in the current page space.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getSelectionRotatedScreenBounds(): Box | undefined {\n\t\tconst bounds = this.getSelectionRotatedPageBounds()\n\t\tif (!bounds) return undefined\n\t\tconst { x, y } = this.pageToScreen(bounds.point)\n\t\tconst zoom = this.getZoomLevel()\n\t\treturn new Box(x, y, bounds.width * zoom, bounds.height * zoom)\n\t}\n\n\t// Focus Group\n\n\t/**\n\t * The current focused group id.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroupId(): TLShapeId | TLPageId {\n\t\treturn this.getCurrentPageState().focusedGroupId ?? this.getCurrentPageId()\n\t}\n\n\t/**\n\t * The current focused group.\n\t *\n\t * @public\n\t */\n\t@computed getFocusedGroup(): TLShape | undefined {\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\t\treturn focusedGroupId ? this.getShape(focusedGroupId) : undefined\n\t}\n\n\t/**\n\t * Set the current focused group shape.\n\t *\n\t * @param shape - The group shape id (or group shape's id) to set as the focused group shape.\n\t *\n\t * @public\n\t */\n\tsetFocusedGroup(shape: TLShapeId | TLGroupShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : (shape?.id ?? null)\n\n\t\tif (id !== null) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) {\n\t\t\t\tthrow Error(`Editor.setFocusedGroup: Shape with id ${id} does not exist`)\n\t\t\t}\n\n\t\t\tif (!this.isShapeOfType<TLGroupShape>(shape, 'group')) {\n\t\t\t\tthrow Error(\n\t\t\t\t\t`Editor.setFocusedGroup: Cannot set focused group to shape of type ${shape.type}`\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tif (id === this.getFocusedGroupId()) return this\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.update(this.getCurrentPageState().id, (s) => ({ ...s, focusedGroupId: id }))\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Exit the current focused group, moving up to the next parent group if there is one.\n\t *\n\t * @public\n\t */\n\tpopFocusedGroupId(): this {\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\tif (focusedGroup) {\n\t\t\t// If we have a focused layer, look for an ancestor of the focused shape that is a group\n\t\t\tconst match = this.findShapeAncestor(focusedGroup, (shape) =>\n\t\t\t\tthis.isShapeOfType<TLGroupShape>(shape, 'group')\n\t\t\t)\n\t\t\t// If we have an ancestor that can become a focused layer, set it as the focused layer\n\t\t\tthis.setFocusedGroup(match?.id ?? null)\n\t\t\tthis.select(focusedGroup.id)\n\t\t} else {\n\t\t\t// If there's no parent focused group, then clear the focus layer and clear selection\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The current editing shape's id.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().editingShapeId\n\t}\n\n\t/**\n\t * The current editing shape.\n\t *\n\t * @public\n\t */\n\t@computed getEditingShape(): TLShape | undefined {\n\t\tconst editingShapeId = this.getEditingShapeId()\n\t\treturn editingShapeId ? this.getShape(editingShapeId) : undefined\n\t}\n\n\t/**\n\t * Set the current editing shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setEditingShape(myShape)\n\t * editor.setEditingShape(myShape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to set as editing.\n\t *\n\t * @public\n\t */\n\tsetEditingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : (shape?.id ?? null)\n\t\tthis.setRichTextEditor(null)\n\t\tconst prevEditingShapeId = this.getEditingShapeId()\n\t\tif (id !== prevEditingShapeId) {\n\t\t\tif (id) {\n\t\t\t\tconst shape = this.getShape(id)\n\t\t\t\tif (shape && this.getShapeUtil(shape).canEdit(shape)) {\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: id })\n\t\t\t\t\t\t\tif (prevEditingShapeId) {\n\t\t\t\t\t\t\t\tconst prevEditingShape = this.getShape(prevEditingShapeId)\n\t\t\t\t\t\t\t\tif (prevEditingShape) {\n\t\t\t\t\t\t\t\t\tthis.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.getShapeUtil(shape).onEditStart?.(shape)\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t\treturn this\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Either we just set the editing id to null, or the shape was missing or not editable\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: null })\n\t\t\t\t\tthis._currentRichTextEditor.set(null)\n\t\t\t\t\tif (prevEditingShapeId) {\n\t\t\t\t\t\tconst prevEditingShape = this.getShape(prevEditingShapeId)\n\t\t\t\t\t\tif (prevEditingShape) {\n\t\t\t\t\t\t\tthis.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\t// Rich text editor\n\n\tprivate _currentRichTextEditor = atom('rich text editor', null as TiptapEditor | null)\n\n\t/**\n\t * The current editing shape's text editor.\n\t *\n\t * @public\n\t */\n\t@computed getRichTextEditor(): TiptapEditor | null {\n\t\treturn this._currentRichTextEditor.get()\n\t}\n\n\t/**\n\t * Set the current editing shape's rich text editor.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setRichTextEditor(richTextEditorView)\n\t * ```\n\t *\n\t * @param textEditor - The text editor to set as the current editing shape's text editor.\n\t *\n\t * @public\n\t */\n\tsetRichTextEditor(textEditor: TiptapEditor | null) {\n\t\tthis._currentRichTextEditor.set(textEditor)\n\t\treturn this\n\t}\n\n\t// Hovered\n\n\t/**\n\t * The current hovered shape id.\n\t *\n\t * @readonly\n\t * @public\n\t */\n\t@computed getHoveredShapeId(): TLShapeId | null {\n\t\treturn this.getCurrentPageState().hoveredShapeId\n\t}\n\n\t/**\n\t * The current hovered shape.\n\t *\n\t * @public\n\t */\n\t@computed getHoveredShape(): TLShape | undefined {\n\t\tconst hoveredShapeId = this.getHoveredShapeId()\n\t\treturn hoveredShapeId ? this.getShape(hoveredShapeId) : undefined\n\t}\n\t/**\n\t * Set the editor's current hovered shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHoveredShape(myShape)\n\t * editor.setHoveredShape(myShape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to set as hovered.\n\t *\n\t * @public\n\t */\n\tsetHoveredShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : (shape?.id ?? null)\n\t\tif (id === this.getHoveredShapeId()) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.updateCurrentPageState({ hoveredShapeId: id })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Hinting\n\n\t/**\n\t * The editor's current hinting shape ids.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShapeIds() {\n\t\treturn this.getCurrentPageState().hintingShapeIds\n\t}\n\n\t/**\n\t * The editor's current hinting shapes.\n\t *\n\t * @public\n\t */\n\t@computed getHintingShape() {\n\t\tconst hintingShapeIds = this.getHintingShapeIds()\n\t\treturn compact(hintingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current hinting shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setHintingShapes([myShape])\n\t * editor.setHintingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetHintingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\t// always ephemeral\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis._updateCurrentPageState({ hintingShapeIds: dedupe(ids) })\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t// Erasing\n\n\t/**\n\t * The editor's current erasing ids.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapeIds() {\n\t\treturn this.getCurrentPageState().erasingShapeIds\n\t}\n\n\t/**\n\t * The editor's current erasing shapes.\n\t *\n\t * @public\n\t */\n\t@computed getErasingShapes() {\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\treturn compact(erasingShapeIds.map((id) => this.getShape(id)))\n\t}\n\n\t/**\n\t * Set the editor's current erasing shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setErasingShapes([myShape])\n\t * editor.setErasingShapes([myShape.id])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to set as hinting.\n\t *\n\t * @public\n\t */\n\tsetErasingShapes(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((shape) => shape.id)\n\t\tids.sort() // sort the incoming ids\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tif (ids.length === erasingShapeIds.length) {\n\t\t\t\t\t// if the new ids are the same length as the current ids, they might be the same.\n\t\t\t\t\t// presuming the current ids are also sorted, check each item to see if it's the same;\n\t\t\t\t\t// if we find any unequal, then we know the new ids are different.\n\t\t\t\t\tfor (let i = 0; i < ids.length; i++) {\n\t\t\t\t\t\tif (ids[i] !== erasingShapeIds[i]) {\n\t\t\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// if the ids are a different length, then we know they're different.\n\t\t\t\t\tthis._updateCurrentPageState({ erasingShapeIds: ids })\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t// Cropping\n\n\t/**\n\t * The current cropping shape's id.\n\t *\n\t * @public\n\t */\n\tgetCroppingShapeId() {\n\t\treturn this.getCurrentPageState().croppingShapeId\n\t}\n\n\t/**\n\t * Set the current cropping shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCroppingShape(myShape)\n\t * editor.setCroppingShape(myShape.id)\n\t * ```\n\t *\n\t *\n\t * @param shape - The shape (or shape id) to set as cropping.\n\t *\n\t * @public\n\t */\n\tsetCroppingShape(shape: TLShapeId | TLShape | null): this {\n\t\tconst id = typeof shape === 'string' ? shape : (shape?.id ?? null)\n\t\tif (id !== this.getCroppingShapeId()) {\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tif (!id) {\n\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: null })\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst shape = this.getShape(id)!\n\t\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\t\tif (shape && util.canCrop(shape)) {\n\t\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: id })\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\t\t}\n\t\treturn this\n\t}\n\n\tprivate _textOptions: Atom<TLTextOptions | null>\n\n\t/**\n\t * Get the current text options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getTextOptions()\n\t * ```\n\t *\n\t * @public */\n\tgetTextOptions() {\n\t\treturn assertExists(this._textOptions.get(), 'Cannot use text without setting textOptions')\n\t}\n\n\t/* --------------------- Camera --------------------- */\n\n\t/** @internal */\n\t@computed\n\tprivate _unsafe_getCameraId() {\n\t\treturn CameraRecordType.createId(this.getCurrentPageId())\n\t}\n\n\t/**\n\t * The current camera.\n\t *\n\t * @public\n\t */\n\t@computed getCamera(): TLCamera {\n\t\tconst baseCamera = this.store.get(this._unsafe_getCameraId())!\n\t\tif (this._isLockedOnFollowingUser.get()) {\n\t\t\tconst followingCamera = this.getCameraForFollowing()\n\t\t\tif (followingCamera) {\n\t\t\t\treturn { ...baseCamera, ...followingCamera }\n\t\t\t}\n\t\t}\n\t\treturn baseCamera\n\t}\n\n\tprivate _getFollowingPresence(targetUserId: string | null) {\n\t\tconst visited = [this.user.getId()]\n\t\tconst collaborators = this.getCollaborators()\n\t\tlet leaderPresence = null as null | TLInstancePresence\n\t\twhile (targetUserId && !visited.includes(targetUserId)) {\n\t\t\tleaderPresence = collaborators.find((c) => c.userId === targetUserId) ?? null\n\t\t\ttargetUserId = leaderPresence?.followingUserId ?? null\n\t\t\tif (leaderPresence) {\n\t\t\t\tvisited.push(leaderPresence.userId)\n\t\t\t}\n\t\t}\n\t\treturn leaderPresence\n\t}\n\n\t@computed\n\tprivate getViewportPageBoundsForFollowing(): null | Box {\n\t\tconst leaderPresence = this._getFollowingPresence(this.getInstanceState().followingUserId)\n\n\t\tif (!leaderPresence?.camera || !leaderPresence?.screenBounds) return null\n\n\t\t// Fit their viewport inside of our screen bounds\n\t\t// 1. calculate their viewport in page space\n\t\tconst { w: lw, h: lh } = leaderPresence.screenBounds\n\t\tconst { x: lx, y: ly, z: lz } = leaderPresence.camera\n\t\tconst theirViewport = new Box(-lx, -ly, lw / lz, lh / lz)\n\n\t\t// resize our screenBounds to contain their viewport\n\t\tconst ourViewport = this.getViewportScreenBounds().clone()\n\t\tconst ourAspectRatio = ourViewport.width / ourViewport.height\n\n\t\tourViewport.width = theirViewport.width\n\t\tourViewport.height = ourViewport.width / ourAspectRatio\n\t\tif (ourViewport.height < theirViewport.height) {\n\t\t\tourViewport.height = theirViewport.height\n\t\t\tourViewport.width = ourViewport.height * ourAspectRatio\n\t\t}\n\n\t\tourViewport.center = theirViewport.center\n\t\treturn ourViewport\n\t}\n\n\t@computed\n\tprivate getCameraForFollowing(): null | { x: number; y: number; z: number } {\n\t\tconst viewport = this.getViewportPageBoundsForFollowing()\n\t\tif (!viewport) return null\n\n\t\treturn {\n\t\t\tx: -viewport.x,\n\t\t\ty: -viewport.y,\n\t\t\tz: this.getViewportScreenBounds().w / viewport.width,\n\t\t}\n\t}\n\n\t/**\n\t * The current camera zoom level.\n\t *\n\t * @public\n\t */\n\t@computed getZoomLevel() {\n\t\treturn this.getCamera().z\n\t}\n\n\t/**\n\t * Get the camera's initial or reset zoom level.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetInitialZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.initialZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.initialZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.initialZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the camera's base level for calculating actual zoom levels based on the zoom steps.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getBaseZoom()\n\t * ```\n\t *\n\t * @public */\n\tgetBaseZoom() {\n\t\tconst cameraOptions = this.getCameraOptions()\n\t\t// If no camera constraints are provided, the default zoom is 100%\n\t\tif (!cameraOptions.constraints) return 1\n\n\t\t// When defaultZoom is default, the default zoom is 100%\n\t\tif (cameraOptions.constraints.baseZoom === 'default') return 1\n\n\t\tconst { zx, zy } = getCameraFitXFitY(this, cameraOptions)\n\n\t\tswitch (cameraOptions.constraints.baseZoom) {\n\t\t\tcase 'fit-min': {\n\t\t\t\treturn Math.max(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-max': {\n\t\t\t\treturn Math.min(zx, zy)\n\t\t\t}\n\t\t\tcase 'fit-x': {\n\t\t\t\treturn zx\n\t\t\t}\n\t\t\tcase 'fit-y': {\n\t\t\t\treturn zy\n\t\t\t}\n\t\t\tcase 'fit-min-100': {\n\t\t\t\treturn Math.min(1, Math.max(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-max-100': {\n\t\t\t\treturn Math.min(1, Math.min(zx, zy))\n\t\t\t}\n\t\t\tcase 'fit-x-100': {\n\t\t\t\treturn Math.min(1, zx)\n\t\t\t}\n\t\t\tcase 'fit-y-100': {\n\t\t\t\treturn Math.min(1, zy)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(cameraOptions.constraints.baseZoom)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate _cameraOptions = atom('camera options', DEFAULT_CAMERA_OPTIONS)\n\n\t/**\n\t * Get the current camera options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraOptions()\n\t * ```\n\t *\n\t * @public */\n\tgetCameraOptions() {\n\t\treturn this._cameraOptions.get()\n\t}\n\n\t/**\n\t * Set the camera options. Changing the options won't immediately change the camera itself, so you may want to call `setCamera` after changing the options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCameraOptions(myCameraOptions)\n\t * editor.setCamera(editor.getCamera())\n\t * ```\n\t *\n\t * @param opts - The camera options to set.\n\t *\n\t * @public */\n\tsetCameraOptions(opts: Partial<TLCameraOptions>) {\n\t\tconst next = structuredClone({\n\t\t\t...this._cameraOptions.__unsafe__getWithoutCapture(),\n\t\t\t...opts,\n\t\t})\n\t\tif (next.zoomSteps?.length < 1) next.zoomSteps = [1]\n\t\tthis._cameraOptions.set(next)\n\t\tthis.setCamera(this.getCamera())\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate getConstrainedCamera(\n\t\tpoint: VecLike,\n\t\topts?: TLCameraMoveOptions\n\t): {\n\t\tx: number\n\t\ty: number\n\t\tz: number\n\t} {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tlet { x, y, z = currentCamera.z } = point\n\n\t\t// If force is true, then we'll set the camera to the point regardless of\n\t\t// the camera options, so that we can handle gestures that permit elasticity\n\t\t// or decay, or animations that occur while the camera is locked.\n\t\tif (!opts?.force) {\n\t\t\t// Apply any adjustments based on the camera options\n\n\t\t\tconst cameraOptions = this.getCameraOptions()\n\n\t\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\t\tconst vsb = this.getViewportScreenBounds()\n\n\t\t\t// If bounds are provided, then we'll keep those bounds on screen\n\t\t\tif (cameraOptions.constraints) {\n\t\t\t\tconst { constraints } = cameraOptions\n\n\t\t\t\t// Clamp padding to half the viewport size on either dimension\n\t\t\t\tconst py = Math.min(constraints.padding.y, vsb.w / 2)\n\t\t\t\tconst px = Math.min(constraints.padding.x, vsb.h / 2)\n\n\t\t\t\t// Expand the bounds by the padding\n\t\t\t\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\n\t\t\t\t// For each axis, the \"natural zoom\" is the zoom at\n\t\t\t\t// which the expanded bounds (with padding) would fit\n\t\t\t\t// the current viewport screen bounds. Paddings are\n\t\t\t\t// equal to screen pixels at 100%\n\t\t\t\t// The min and max zooms are factors of the smaller natural zoom axis\n\n\t\t\t\tconst zx = (vsb.w - px * 2) / bounds.w\n\t\t\t\tconst zy = (vsb.h - py * 2) / bounds.h\n\n\t\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\t\tconst maxZ = zoomMax * baseZoom\n\t\t\t\tconst minZ = zoomMin * baseZoom\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\tz = this.getInitialZoom()\n\t\t\t\t}\n\n\t\t\t\tif (z < minZ || z > maxZ) {\n\t\t\t\t\t// We're trying to zoom out past the minimum zoom level,\n\t\t\t\t\t// or in past the maximum zoom level, so stop the camera\n\t\t\t\t\t// but keep the current center\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tconst cxA = -cx + vsb.w / cz / 2\n\t\t\t\t\tconst cyA = -cy + vsb.h / cz / 2\n\t\t\t\t\tz = clamp(z, minZ, maxZ)\n\t\t\t\t\tconst cxB = -cx + vsb.w / z / 2\n\t\t\t\t\tconst cyB = -cy + vsb.h / z / 2\n\t\t\t\t\tx = cx + cxB - cxA\n\t\t\t\t\ty = cy + cyB - cyA\n\t\t\t\t}\n\n\t\t\t\t// Calculate available space\n\t\t\t\tconst minX = px / z - bounds.x\n\t\t\t\tconst minY = py / z - bounds.y\n\t\t\t\tconst freeW = (vsb.w - px * 2) / z - bounds.w\n\t\t\t\tconst freeH = (vsb.h - py * 2) / z - bounds.h\n\t\t\t\tconst originX = minX + freeW * constraints.origin.x\n\t\t\t\tconst originY = minY + freeH * constraints.origin.y\n\n\t\t\t\tconst behaviorX =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.x\n\t\t\t\tconst behaviorY =\n\t\t\t\t\ttypeof constraints.behavior === 'string' ? constraints.behavior : constraints.behavior.y\n\n\t\t\t\t// x axis\n\n\t\t\t\tif (opts?.reset) {\n\t\t\t\t\t// Reset the camera according to the origin\n\t\t\t\t\tx = originX\n\t\t\t\t\ty = originY\n\t\t\t\t} else {\n\t\t\t\t\t// Apply constraints to the camera\n\t\t\t\t\tswitch (behaviorX) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\t// Center according to the origin\n\t\t\t\t\t\t\tx = originX\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\t// When below fit zoom, center the camera\n\t\t\t\t\t\t\tif (z < zx) x = originX\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\t// When below fit zoom, constrain the camera so that the bounds stay completely within the viewport\n\t\t\t\t\t\t\tif (z < zx) x = clamp(x, minX, (vsb.w - px) / z - bounds.w)\n\t\t\t\t\t\t\t// When above fit zoom, keep the bounds within padding distance of the viewport edge\n\t\t\t\t\t\t\telse x = clamp(x, minX + freeW, minX)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\t// Constrain the camera so that the bounds never leaves the viewport\n\t\t\t\t\t\t\tx = clamp(x, px / z - bounds.w, (vsb.w - px) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorX)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// y axis\n\n\t\t\t\t\tswitch (behaviorY) {\n\t\t\t\t\t\tcase 'fixed': {\n\t\t\t\t\t\t\ty = originY\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'contain': {\n\t\t\t\t\t\t\tif (z < zy) y = originY\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'inside': {\n\t\t\t\t\t\t\tif (z < zy) y = clamp(y, minY, (vsb.h - py) / z - bounds.h)\n\t\t\t\t\t\t\telse y = clamp(y, minY + freeH, minY)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'outside': {\n\t\t\t\t\t\t\ty = clamp(y, py / z - bounds.h, (vsb.h - py) / z)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'free': {\n\t\t\t\t\t\t\t// noop, use whatever x is provided\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tthrow exhaustiveSwitchError(behaviorY)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// constrain the zoom, preserving the center\n\t\t\t\tif (z > zoomMax || z < zoomMin) {\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\t\t\t\tz = clamp(z, zoomMin, zoomMax)\n\t\t\t\t\tx = cx + (-cx + vsb.w / z / 2) - (-cx + vsb.w / cz / 2)\n\t\t\t\t\ty = cy + (-cy + vsb.h / z / 2) - (-cy + vsb.h / cz / 2)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { x, y, z }\n\t}\n\n\t/** @internal */\n\tprivate _setCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst currentCamera = this.getCamera()\n\n\t\tconst { x, y, z } = this.getConstrainedCamera(point, opts)\n\n\t\tif (currentCamera.x === x && currentCamera.y === y && currentCamera.z === z) {\n\t\t\treturn this\n\t\t}\n\n\t\ttransact(() => {\n\t\t\tconst camera = { ...currentCamera, x, y, z }\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\tthis.store.put([camera]) // include id and meta here\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\n\t\t\t// Dispatch a new pointer move because the pointer's page will have changed\n\t\t\t// (its screen position will compute to a new page position given the new camera position)\n\t\t\tconst { currentScreenPoint, currentPagePoint } = this.inputs\n\n\t\t\t// compare the next page point (derived from the current camera) to the current page point\n\t\t\tif (\n\t\t\t\tcurrentScreenPoint.x / z - x !== currentPagePoint.x ||\n\t\t\t\tcurrentScreenPoint.y / z - y !== currentPagePoint.y\n\t\t\t) {\n\t\t\t\t// If it's changed, dispatch a pointer event\n\t\t\t\tthis.updatePointer({\n\t\t\t\t\timmediate: opts?.immediate,\n\t\t\t\t\tpointerId: INTERNAL_POINTER_IDS.CAMERA_MOVE,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tthis._tickCameraState()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current camera.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCamera({ x: 0, y: 0})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5})\n\t * editor.setCamera({ x: 0, y: 0, z: 1.5}, { animation: { duration: 1000, easing: (t) => t * t } })\n\t * ```\n\t *\n\t * @param point - The new camera position.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tsetCamera(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\t// Stop any camera animations\n\t\tthis.stopCameraAnimation()\n\n\t\t// Stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tconst _point = Vec.Cast(point)\n\n\t\tif (!Number.isFinite(_point.x)) _point.x = 0\n\t\tif (!Number.isFinite(_point.y)) _point.y = 0\n\t\tif (_point.z === undefined || !Number.isFinite(_point.z)) point.z = this.getZoomLevel()\n\n\t\tconst camera = this.getConstrainedCamera(_point, opts)\n\n\t\tif (opts?.animation) {\n\t\t\tconst { width, height } = this.getViewportScreenBounds()\n\t\t\tthis._animateToViewport(\n\t\t\t\tnew Box(-camera.x, -camera.y, width / camera.z, height / camera.z),\n\t\t\t\topts\n\t\t\t)\n\t\t} else {\n\t\t\tthis._setCamera(camera, {\n\t\t\t\t...opts,\n\t\t\t\t// we already did the constraining, so we don't need to do it again\n\t\t\t\tforce: true,\n\t\t\t})\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Center the camera on a point (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.centerOnPoint({ x: 100, y: 100 })\n\t * editor.centerOnPoint({ x: 100, y: 100 }, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The point in the current page space to center on.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tcenterOnPoint(point: VecLike, opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { width: pw, height: ph } = this.getViewportPageBounds()\n\t\tthis.setCamera(new Vec(-(point.x - pw / 2), -(point.y - ph / 2), this.getCamera().z), opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current page's content in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToFit()\n\t * editor.zoomToFit({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToFit(opts?: TLCameraMoveOptions): this {\n\t\tconst ids = [...this.getCurrentPageShapeIds()]\n\t\tif (ids.length <= 0) return this\n\t\tconst pageBounds = Box.Common(compact(ids.map((id) => this.getShapePageBounds(id))))\n\t\tthis.zoomToBounds(pageBounds, opts)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the zoom back to 100%.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.resetZoom()\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.resetZoom(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tresetZoom(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked, constraints: constraints } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst currentCamera = this.getCamera()\n\t\tconst { x: cx, y: cy, z: cz } = currentCamera\n\t\tconst { x, y } = point\n\n\t\tlet z = 1\n\n\t\tif (constraints) {\n\t\t\t// For non-infinite fit, we'll set the camera to the natural zoom level...\n\t\t\t// unless it's already there, in which case we'll set zoom to 100%\n\t\t\tconst initialZoom = this.getInitialZoom()\n\t\t\tif (cz !== initialZoom) {\n\t\t\t\tz = initialZoom\n\t\t\t}\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(cx + (x / z - x) - (x / cz - x), cy + (y / z - y) - (y / cz - y), z),\n\t\t\topts\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera in.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomIn()\n\t * editor.zoomIn(editor.getViewportScreenCenter(), { animation: { duration: 200 } })\n\t * editor.zoomIn(editor.inputs.currentScreenPoint, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param point - The screen point to zoom in on. Defaults to the screen center\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomIn(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tlet zoom = last(zoomSteps)! * baseZoom\n\t\t\tfor (let i = 1; i < zoomSteps.length; i++) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz <= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z2\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera out.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomOut()\n\t * editor.zoomOut(editor.getViewportScreenCenter(), { animation: { duration: 120 } })\n\t * editor.zoomOut(editor.inputs.currentScreenPoint, { animation: { duration: 120 } })\n\t * ```\n\t *\n\t * @param point - The point to zoom out on. Defaults to the viewport screen center.\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomOut(point = this.getViewportScreenCenter(), opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst { zoomSteps } = this.getCameraOptions()\n\t\tif (zoomSteps !== null && zoomSteps.length > 1) {\n\t\t\tconst baseZoom = this.getBaseZoom()\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\t// start at the max\n\t\t\tlet zoom = zoomSteps[0] * baseZoom\n\t\t\tfor (let i = zoomSteps.length - 1; i > 0; i--) {\n\t\t\t\tconst z1 = zoomSteps[i - 1] * baseZoom\n\t\t\t\tconst z2 = zoomSteps[i] * baseZoom\n\t\t\t\tif (z2 - cz >= (z2 - z1) / 2) continue\n\t\t\t\tzoom = z1\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tthis.setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\tcx + (point.x / zoom - point.x) - (point.x / cz - point.x),\n\t\t\t\t\tcy + (point.y / zoom - point.y) - (point.y / cz - point.y),\n\t\t\t\t\tzoom\n\t\t\t\t),\n\t\t\t\topts\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to fit the current selection in the viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToSelection()\n\t * editor.zoomToSelection({ animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param opts - The camera move options.\n\t *\n\t * @public\n\t */\n\tzoomToSelection(opts?: TLCameraMoveOptions): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\tif (selectionPageBounds) {\n\t\t\tthis.zoomToBounds(selectionPageBounds, {\n\t\t\t\ttargetZoom: Math.max(1, this.getZoomLevel()),\n\t\t\t\t...opts,\n\t\t\t})\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Zoom the camera to the current selection if offscreen.\n\t *\n\t * @public\n\t */\n\tzoomToSelectionIfOffscreen(\n\t\tpadding = 16,\n\t\topts?: { targetZoom?: number; inset?: number } & TLCameraMoveOptions\n\t) {\n\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\tif (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {\n\t\t\tconst eb = selectionPageBounds\n\t\t\t\t.clone()\n\t\t\t\t// Expand the bounds by the padding\n\t\t\t\t.expandBy(padding / this.getZoomLevel())\n\t\t\t\t// then expand the bounds to include the viewport bounds\n\t\t\t\t.expand(viewportPageBounds)\n\n\t\t\t// then use the difference between the centers to calculate the offset\n\t\t\tconst nextBounds = viewportPageBounds.clone().translate({\n\t\t\t\tx: (eb.center.x - viewportPageBounds.center.x) * 2,\n\t\t\t\ty: (eb.center.y - viewportPageBounds.center.y) * 2,\n\t\t\t})\n\t\t\tthis.zoomToBounds(nextBounds, opts)\n\t\t}\n\t}\n\n\t/**\n\t * Zoom the camera to fit a bounding box (in the current page space).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToBounds(myBounds)\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 } })\n\t * editor.zoomToBounds(myBounds, { animation: { duration: 200 }, inset: 0, targetZoom: 1 })\n\t * ```\n\t *\n\t * @param bounds - The bounding box.\n\t * @param opts - The camera move options, target zoom, or custom inset amount.\n\t *\n\t * @public\n\t */\n\tzoomToBounds(\n\t\tbounds: BoxLike,\n\t\topts?: { targetZoom?: number; inset?: number } & TLCameraMoveOptions\n\t): this {\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()\n\t\tif (cameraOptions.isLocked && !opts?.force) return this\n\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\n\t\tconst inset = opts?.inset ?? Math.min(ZOOM_TO_FIT_PADDING, viewportScreenBounds.width * 0.28)\n\n\t\tconst baseZoom = this.getBaseZoom()\n\t\tconst zoomMin = cameraOptions.zoomSteps[0]\n\t\tconst zoomMax = last(cameraOptions.zoomSteps)!\n\n\t\tlet zoom = clamp(\n\t\t\tMath.min(\n\t\t\t\t(viewportScreenBounds.width - inset) / bounds.w,\n\t\t\t\t(viewportScreenBounds.height - inset) / bounds.h\n\t\t\t),\n\t\t\tzoomMin * baseZoom,\n\t\t\tzoomMax * baseZoom\n\t\t)\n\n\t\tif (opts?.targetZoom !== undefined) {\n\t\t\tzoom = Math.min(opts.targetZoom, zoom)\n\t\t}\n\n\t\tthis.setCamera(\n\t\t\tnew Vec(\n\t\t\t\t-bounds.x + (viewportScreenBounds.width - bounds.w * zoom) / 2 / zoom,\n\t\t\t\t-bounds.y + (viewportScreenBounds.height - bounds.h * zoom) / 2 / zoom,\n\t\t\t\tzoom\n\t\t\t),\n\t\t\topts\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop the current camera animation, if any.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopCameraAnimation()\n\t * ```\n\t *\n\t * @public\n\t */\n\tstopCameraAnimation(): this {\n\t\tthis.emit('stop-camera-animation')\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _viewportAnimation = null as null | {\n\t\telapsed: number\n\t\tduration: number\n\t\teasing(t: number): number\n\t\tstart: Box\n\t\tend: Box\n\t}\n\n\t/** @internal */\n\tprivate _animateViewport(ms: number): void {\n\t\tif (!this._viewportAnimation) return\n\n\t\tthis._viewportAnimation.elapsed += ms\n\n\t\tconst { elapsed, easing, duration, start, end } = this._viewportAnimation\n\n\t\tif (elapsed > duration) {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t\tthis._setCamera(new Vec(-end.x, -end.y, this.getViewportScreenBounds().width / end.width))\n\t\t\treturn\n\t\t}\n\n\t\tconst remaining = duration - elapsed\n\t\tconst t = easing(1 - remaining / duration)\n\n\t\tconst left = start.minX + (end.minX - start.minX) * t\n\t\tconst top = start.minY + (end.minY - start.minY) * t\n\t\tconst right = start.maxX + (end.maxX - start.maxX) * t\n\n\t\tthis._setCamera(new Vec(-left, -top, this.getViewportScreenBounds().width / (right - left)), {\n\t\t\tforce: true,\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _animateToViewport(\n\t\ttargetViewportPage: Box,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t) {\n\t\tconst { animation, ...rest } = opts\n\t\tif (!animation) return\n\t\tconst { duration = 0, easing = EASINGS.easeInOutCubic } = animation\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\n\t\t// If we have an existing animation, then stop it\n\t\tthis.stopCameraAnimation()\n\n\t\t// also stop following any user\n\t\tif (this.getInstanceState().followingUserId) {\n\t\t\tthis.stopFollowingUser()\n\t\t}\n\n\t\tif (duration === 0 || animationSpeed === 0) {\n\t\t\t// If we have no animation, then skip the animation and just set the camera\n\t\t\treturn this._setCamera(\n\t\t\t\tnew Vec(\n\t\t\t\t\t-targetViewportPage.x,\n\t\t\t\t\t-targetViewportPage.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / targetViewportPage.width\n\t\t\t\t),\n\t\t\t\t{ ...rest }\n\t\t\t)\n\t\t}\n\n\t\t// Set our viewport animation\n\t\tthis._viewportAnimation = {\n\t\t\telapsed: 0,\n\t\t\tduration: duration / animationSpeed,\n\t\t\teasing,\n\t\t\tstart: viewportPageBounds.clone(),\n\t\t\tend: targetViewportPage.clone(),\n\t\t}\n\n\t\t// If we ever get a \"stop-camera-animation\" event, we stop\n\t\tthis.once('stop-camera-animation', () => {\n\t\t\tthis.off('tick', this._animateViewport)\n\t\t\tthis._viewportAnimation = null\n\t\t})\n\n\t\t// On each tick, animate the viewport\n\t\tthis.on('tick', this._animateViewport)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Slide the camera in a certain direction.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.slideCamera({ speed: 1, direction: { x: 1, y: 0 }, friction: 0.1 })\n\t * ```\n\t *\n\t * @param opts - Options for the slide\n\t * @public\n\t */\n\tslideCamera(\n\t\topts = {} as {\n\t\t\tspeed: number\n\t\t\tdirection: VecLike\n\t\t\tfriction?: number\n\t\t\tspeedThreshold?: number\n\t\t\tforce?: boolean\n\t\t}\n\t): this {\n\t\tconst { isLocked } = this.getCameraOptions()\n\t\tif (isLocked && !opts?.force) return this\n\n\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\t\tif (animationSpeed === 0) return this\n\n\t\tthis.stopCameraAnimation()\n\n\t\tconst {\n\t\t\tspeed,\n\t\t\tfriction = this.options.cameraSlideFriction,\n\t\t\tdirection,\n\t\t\tspeedThreshold = 0.01,\n\t\t} = opts\n\t\tlet currentSpeed = Math.min(speed, 1)\n\n\t\tconst cancel = () => {\n\t\t\tthis.off('tick', moveCamera)\n\t\t\tthis.off('stop-camera-animation', cancel)\n\t\t}\n\n\t\tthis.once('stop-camera-animation', cancel)\n\n\t\tconst moveCamera = (elapsed: number) => {\n\t\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\t\tconst movementVec = Vec.Mul(direction, (currentSpeed * elapsed) / cz)\n\n\t\t\t// Apply friction\n\t\t\tcurrentSpeed *= 1 - friction\n\t\t\tif (currentSpeed < speedThreshold) {\n\t\t\t\tcancel()\n\t\t\t} else {\n\t\t\t\tthis._setCamera(new Vec(cx + movementVec.x, cy + movementVec.y, cz))\n\t\t\t}\n\t\t}\n\n\t\tthis.on('tick', moveCamera)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Animate the camera to a user's cursor position. This also briefly show the user's cursor if it's not currently visible.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.zoomToUser(myUserId)\n\t * editor.zoomToUser(myUserId, { animation: { duration: 200 } })\n\t * ```\n\t *\n\t * @param userId - The id of the user to animate to.\n\t * @param opts - The camera move options.\n\t * @public\n\t */\n\tzoomToUser(userId: string, opts: TLCameraMoveOptions = { animation: { duration: 500 } }): this {\n\t\tconst presence = this.getCollaborators().find((c) => c.userId === userId)\n\n\t\tif (!presence) return this\n\n\t\tconst cursor = presence.cursor\n\t\tif (!cursor) return this\n\n\t\tthis.run(() => {\n\t\t\t// If we're following someone, stop following them\n\t\t\tif (this.getInstanceState().followingUserId !== null) {\n\t\t\t\tthis.stopFollowingUser()\n\t\t\t}\n\n\t\t\t// If we're not on the same page, move to the page they're on\n\t\t\tconst isOnSamePage = presence.currentPageId === this.getCurrentPageId()\n\t\t\tif (!isOnSamePage) {\n\t\t\t\tthis.setCurrentPage(presence.currentPageId)\n\t\t\t}\n\n\t\t\t// Only animate the camera if the user is on the same page as us\n\t\t\tif (opts && opts.animation && !isOnSamePage) {\n\t\t\t\topts.animation = undefined\n\t\t\t}\n\n\t\t\tthis.centerOnPoint(cursor, opts)\n\n\t\t\t// Highlight the user's cursor\n\t\t\tconst { highlightedUserIds } = this.getInstanceState()\n\t\t\tthis.updateInstanceState({ highlightedUserIds: [...highlightedUserIds, userId] })\n\n\t\t\t// Unhighlight the user's cursor after a few seconds\n\t\t\tthis.timers.setTimeout(() => {\n\t\t\t\tconst highlightedUserIds = [...this.getInstanceState().highlightedUserIds]\n\t\t\t\tconst index = highlightedUserIds.indexOf(userId)\n\t\t\t\tif (index < 0) return\n\t\t\t\thighlightedUserIds.splice(index, 1)\n\t\t\t\tthis.updateInstanceState({ highlightedUserIds })\n\t\t\t}, this.options.collaboratorIdleTimeoutMs)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t// Viewport\n\n\t/** @internal */\n\tprivate _willSetInitialBounds = true\n\n\t/**\n\t * Update the viewport. The viewport will measure the size and screen position of its container\n\t * element. This should be done whenever the container's position on the screen changes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024))\n\t * editor.updateViewportScreenBounds(new Box(0, 0, 1280, 1024), true)\n\t * ```\n\t *\n\t * @param screenBounds - The new screen bounds of the viewport.\n\t * @param center - Whether to preserve the viewport page center as the viewport changes.\n\t *\n\t * @public\n\t */\n\tupdateViewportScreenBounds(screenBounds: Box | HTMLElement, center = false): this {\n\t\tif (!(screenBounds instanceof Box)) {\n\t\t\tconst rect = screenBounds.getBoundingClientRect()\n\t\t\tscreenBounds = new Box(\n\t\t\t\trect.left || rect.x,\n\t\t\t\trect.top || rect.y,\n\t\t\t\tMath.max(rect.width, 1),\n\t\t\t\tMath.max(rect.height, 1)\n\t\t\t)\n\t\t} else {\n\t\t\tscreenBounds.width = Math.max(screenBounds.width, 1)\n\t\t\tscreenBounds.height = Math.max(screenBounds.height, 1)\n\t\t}\n\n\t\tconst insets = [\n\t\t\t// top\n\t\t\tscreenBounds.minY !== 0,\n\t\t\t// right\n\t\t\t!approximately(document.body.scrollWidth, screenBounds.maxX, 1),\n\t\t\t// bottom\n\t\t\t!approximately(document.body.scrollHeight, screenBounds.maxY, 1),\n\t\t\t// left\n\t\t\tscreenBounds.minX !== 0,\n\t\t]\n\n\t\tconst { _willSetInitialBounds } = this\n\n\t\tthis._willSetInitialBounds = false\n\n\t\tconst { screenBounds: prevScreenBounds, insets: prevInsets } = this.getInstanceState()\n\t\tif (screenBounds.equals(prevScreenBounds) && insets.every((v, i) => v === prevInsets[i])) {\n\t\t\t// nothing to do\n\t\t\treturn this\n\t\t}\n\n\t\tif (_willSetInitialBounds) {\n\t\t\t// If we have just received the initial bounds, don't center the camera.\n\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\tthis.setCamera(this.getCamera())\n\t\t} else {\n\t\t\tif (center && !this.getInstanceState().followingUserId) {\n\t\t\t\t// Get the page center before the change, make the change, and restore it\n\t\t\t\tconst before = this.getViewportPageBounds().center\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis.centerOnPoint(before)\n\t\t\t} else {\n\t\t\t\t// Otherwise,\n\t\t\t\tthis.updateInstanceState({ screenBounds: screenBounds.toJson(), insets })\n\t\t\t\tthis._setCamera(Vec.From({ ...this.getCamera() }))\n\t\t\t}\n\t\t}\n\n\t\tthis._tickCameraState()\n\n\t\treturn this\n\t}\n\n\t/**\n\t * The bounds of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenBounds() {\n\t\tconst { x, y, w, h } = this.getInstanceState().screenBounds\n\t\treturn new Box(x, y, w, h)\n\t}\n\n\t/**\n\t * The center of the editor's viewport in screen space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportScreenCenter() {\n\t\tconst viewportScreenBounds = this.getViewportScreenBounds()\n\t\treturn new Vec(viewportScreenBounds.w / 2, viewportScreenBounds.h / 2)\n\t}\n\n\t/**\n\t * The current viewport in the current page space.\n\t *\n\t * @public\n\t */\n\t@computed getViewportPageBounds() {\n\t\tconst { w, h } = this.getViewportScreenBounds()\n\t\tconst { x: cx, y: cy, z: cz } = this.getCamera()\n\t\treturn new Box(-cx, -cy, w / cz, h / cz)\n\t}\n\n\t/**\n\t * Convert a point in screen space to a point in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.screenToPage({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in screen space.\n\t *\n\t * @public\n\t */\n\tscreenToPage(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x - screenBounds.x) / cz - cx,\n\t\t\t(point.y - screenBounds.y) / cz - cy,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current screen space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToScreen({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToScreen(point: VecLike) {\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec(\n\t\t\t(point.x + cx) * cz + screenBounds.x,\n\t\t\t(point.y + cy) * cz + screenBounds.y,\n\t\t\tpoint.z ?? 0.5\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in current viewport space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.pageToViewport({ x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param point - The point in page space.\n\t *\n\t * @public\n\t */\n\tpageToViewport(point: VecLike) {\n\t\tconst { x: cx, y: cy, z: cz = 1 } = this.getCamera()\n\t\treturn new Vec((point.x + cx) * cz, (point.y + cy) * cz, point.z ?? 0.5)\n\t}\n\t// Collaborators\n\n\t@computed\n\tprivate _getCollaboratorsQuery() {\n\t\treturn this.store.query.records('instance_presence', () => ({\n\t\t\tuserId: { neq: this.user.getId() },\n\t\t}))\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaborators() {\n\t\tconst allPresenceRecords = this._getCollaboratorsQuery().get()\n\t\tif (!allPresenceRecords.length) return EMPTY_ARRAY\n\t\tconst userIds = [...new Set(allPresenceRecords.map((c) => c.userId))].sort()\n\t\treturn userIds.map((id) => {\n\t\t\tconst latestPresence = maxBy(\n\t\t\t\tallPresenceRecords.filter((c) => c.userId === id),\n\t\t\t\t(p) => p.lastActivityTimestamp ?? 0\n\t\t\t)\n\t\t\treturn latestPresence!\n\t\t})\n\t}\n\n\t/**\n\t * Returns a list of presence records for all peer collaborators on the current page.\n\t * This will return the latest presence record for each connected user.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCollaboratorsOnCurrentPage() {\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\treturn this.getCollaborators().filter((c) => c.currentPageId === currentPageId)\n\t}\n\n\t// Following\n\n\t// When we are 'locked on' to a user, our camera is derived from their camera.\n\tprivate _isLockedOnFollowingUser = atom('isLockedOnFollowingUser', false)\n\n\t/**\n\t * Start viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.startFollowingUser(myUserId)\n\t * ```\n\t *\n\t * @param userId - The id of the user to follow.\n\t *\n\t * @public\n\t */\n\tstartFollowingUser(userId: string): this {\n\t\t// if we were already following someone, stop following them\n\t\tthis.stopFollowingUser()\n\n\t\tconst thisUserId = this.user.getId()\n\n\t\tif (!thisUserId) {\n\t\t\tconsole.warn('You should set the userId for the current instance before following a user')\n\t\t\t// allow to continue since it's probably fine most of the time.\n\t\t}\n\n\t\tconst leaderPresence = this._getFollowingPresence(userId)\n\n\t\tif (!leaderPresence) {\n\t\t\treturn this\n\t\t}\n\n\t\tconst latestLeaderPresence = computed('latestLeaderPresence', () => {\n\t\t\treturn this._getFollowingPresence(userId)\n\t\t})\n\n\t\ttransact(() => {\n\t\t\tthis.updateInstanceState({ followingUserId: userId }, { history: 'ignore' })\n\n\t\t\t// we listen for page changes separately from the 'moveTowardsUser' tick\n\t\t\tconst dispose = react('update current page', () => {\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tleaderPresence.currentPageId !== this.getCurrentPageId() &&\n\t\t\t\t\tthis.getPage(leaderPresence.currentPageId)\n\t\t\t\t) {\n\t\t\t\t\t// if the page changed, switch page\n\t\t\t\t\tthis.run(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t// sneaky store.put here, we can't go through setCurrentPage because it calls stopFollowingUser\n\t\t\t\t\t\t\tthis.store.put([\n\t\t\t\t\t\t\t\t{ ...this.getInstanceState(), currentPageId: leaderPresence.currentPageId },\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ history: 'ignore' }\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tconst cancel = () => {\n\t\t\t\tdispose()\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.off('frame', moveTowardsUser)\n\t\t\t\tthis.off('stop-following', cancel)\n\t\t\t}\n\n\t\t\tconst moveTowardsUser = () => {\n\t\t\t\t// Stop following if we can't find the user\n\t\t\t\tconst leaderPresence = latestLeaderPresence.get()\n\t\t\t\tif (!leaderPresence) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (this._isLockedOnFollowingUser.get()) return\n\n\t\t\t\tconst animationSpeed = this.user.getAnimationSpeed()\n\n\t\t\t\tif (animationSpeed === 0) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst targetViewport = this.getViewportPageBoundsForFollowing()\n\t\t\t\tif (!targetViewport) {\n\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst currentViewport = this.getViewportPageBounds()\n\n\t\t\t\tconst diffX =\n\t\t\t\t\tMath.abs(targetViewport.minX - currentViewport.minX) +\n\t\t\t\t\tMath.abs(targetViewport.maxX - currentViewport.maxX)\n\t\t\t\tconst diffY =\n\t\t\t\t\tMath.abs(targetViewport.minY - currentViewport.minY) +\n\t\t\t\t\tMath.abs(targetViewport.maxY - currentViewport.maxY)\n\n\t\t\t\t// Stop chasing if we're close enough!\n\t\t\t\tif (\n\t\t\t\t\tdiffX < this.options.followChaseViewportSnap &&\n\t\t\t\t\tdiffY < this.options.followChaseViewportSnap\n\t\t\t\t) {\n\t\t\t\t\tthis._isLockedOnFollowingUser.set(true)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Chase the user's viewport!\n\t\t\t\t// Interpolate between the current viewport and the target viewport based on animation speed.\n\t\t\t\t// This will produce an 'ease-out' effect.\n\t\t\t\tconst t = clamp(animationSpeed * 0.5, 0.1, 0.8)\n\n\t\t\t\tconst nextViewport = new Box(\n\t\t\t\t\tlerp(currentViewport.minX, targetViewport.minX, t),\n\t\t\t\t\tlerp(currentViewport.minY, targetViewport.minY, t),\n\t\t\t\t\tlerp(currentViewport.width, targetViewport.width, t),\n\t\t\t\t\tlerp(currentViewport.height, targetViewport.height, t)\n\t\t\t\t)\n\n\t\t\t\tconst nextCamera = new Vec(\n\t\t\t\t\t-nextViewport.x,\n\t\t\t\t\t-nextViewport.y,\n\t\t\t\t\tthis.getViewportScreenBounds().width / nextViewport.width\n\t\t\t\t)\n\n\t\t\t\t// Update the camera!\n\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\tthis._setCamera(nextCamera)\n\t\t\t}\n\n\t\t\tthis.once('stop-following', cancel)\n\t\t\tthis.addListener('frame', moveTowardsUser)\n\n\t\t\t// call once to start synchronously\n\t\t\tmoveTowardsUser()\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stop viewport-following a user.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stopFollowingUser()\n\t * ```\n\t * @public\n\t */\n\tstopFollowingUser(): this {\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\t// commit the current camera to the store\n\t\t\t\tthis.store.put([this.getCamera()])\n\t\t\t\t// this must happen after the camera is committed\n\t\t\t\tthis._isLockedOnFollowingUser.set(false)\n\t\t\t\tthis.updateInstanceState({ followingUserId: null })\n\t\t\t\tthis.emit('stop-following')\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tgetUnorderedRenderingShapes(\n\t\t// The rendering state. We use this method both for rendering, which\n\t\t// is based on other state, and for computing order for SVG export,\n\t\t// which should work even when things are for example off-screen.\n\t\tuseEditorState: boolean\n\t): TLRenderingShape[] {\n\t\t// Here we get the shape as well as any of its children, as well as their\n\t\t// opacities. If the shape is being erased, and none of its ancestors are\n\t\t// being erased, then we reduce the opacity of the shape and all of its\n\t\t// ancestors; but we don't apply this effect more than once among a set\n\t\t// of descendants so that it does not compound.\n\n\t\t// This is designed to keep all the shapes in a single list which\n\t\t// allows the DOM nodes to be reused even when they become children\n\t\t// of other nodes.\n\n\t\tconst renderingShapes: TLRenderingShape[] = []\n\n\t\tlet nextIndex = this.options.maxShapesPerPage * 2\n\t\tlet nextBackgroundIndex = this.options.maxShapesPerPage\n\n\t\tconst erasingShapeIds = this.getErasingShapeIds()\n\n\t\tconst addShapeById = (id: TLShapeId, opacity: number, isAncestorErasing: boolean) => {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (!shape) return\n\n\t\t\tif (this.isShapeHidden(shape)) {\n\t\t\t\t// process children just in case they are overriding the hidden state\n\t\t\t\tconst isErasing = isAncestorErasing || erasingShapeIds.includes(id)\n\t\t\t\tfor (const childId of this.getSortedChildIdsForParent(id)) {\n\t\t\t\t\taddShapeById(childId, opacity, isErasing)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\topacity *= shape.opacity\n\t\t\tlet isShapeErasing = false\n\t\t\tconst util = this.getShapeUtil(shape)\n\n\t\t\tif (useEditorState) {\n\t\t\t\tisShapeErasing = !isAncestorErasing && erasingShapeIds.includes(id)\n\t\t\t\tif (isShapeErasing) {\n\t\t\t\t\topacity *= 0.32\n\t\t\t\t}\n\t\t\t}\n\n\t\t\trenderingShapes.push({\n\t\t\t\tid,\n\t\t\t\tshape,\n\t\t\t\tutil,\n\t\t\t\tindex: nextIndex,\n\t\t\t\tbackgroundIndex: nextBackgroundIndex,\n\t\t\t\topacity,\n\t\t\t})\n\n\t\t\tnextIndex += 1\n\t\t\tnextBackgroundIndex += 1\n\n\t\t\tconst childIds = this.getSortedChildIdsForParent(id)\n\t\t\tif (!childIds.length) return\n\n\t\t\tlet backgroundIndexToRestore = null\n\t\t\tif (util.providesBackgroundForChildren(shape)) {\n\t\t\t\tbackgroundIndexToRestore = nextBackgroundIndex\n\t\t\t\tnextBackgroundIndex = nextIndex\n\t\t\t\tnextIndex += this.options.maxShapesPerPage\n\t\t\t}\n\n\t\t\tfor (const childId of childIds) {\n\t\t\t\taddShapeById(childId, opacity, isAncestorErasing || isShapeErasing)\n\t\t\t}\n\n\t\t\tif (backgroundIndexToRestore !== null) {\n\t\t\t\tnextBackgroundIndex = backgroundIndexToRestore\n\t\t\t}\n\t\t}\n\n\t\t// If we're using editor state, then we're only interested in on-screen shapes.\n\t\t// If we're not using the editor state, then we're interested in ALL shapes, even those from other pages.\n\t\tconst pages = useEditorState ? [this.getCurrentPage()] : this.getPages()\n\t\tfor (const page of pages) {\n\t\t\tfor (const childId of this.getSortedChildIdsForParent(page.id)) {\n\t\t\t\taddShapeById(childId, 1, false)\n\t\t\t}\n\t\t}\n\n\t\treturn renderingShapes\n\t}\n\n\t// Camera state\n\t// Camera state does two things: first, it allows us to subscribe to whether\n\t// the camera is moving or not; and second, it allows us to update the rendering\n\t// shapes on the canvas. Changing the rendering shapes may cause shapes to\n\t// unmount / remount in the DOM, which is expensive; and computing visibility is\n\t// also expensive in large projects. For this reason, we use a second bounding\n\t// box just for rendering, and we only update after the camera stops moving.\n\tprivate _cameraState = atom('camera state', 'idle' as 'idle' | 'moving')\n\tprivate _cameraStateTimeoutRemaining = 0\n\t_decayCameraStateTimeout(elapsed: number) {\n\t\tthis._cameraStateTimeoutRemaining -= elapsed\n\t\tif (this._cameraStateTimeoutRemaining > 0) return\n\t\tthis.off('tick', this._decayCameraStateTimeout)\n\t\tthis._cameraState.set('idle')\n\t}\n\t_tickCameraState() {\n\t\t// always reset the timeout\n\t\tthis._cameraStateTimeoutRemaining = this.options.cameraMovingTimeoutMs\n\t\t// If the state is idle, then start the tick\n\t\tif (this._cameraState.__unsafe__getWithoutCapture() !== 'idle') return\n\t\tthis._cameraState.set('moving')\n\t\tthis.on('tick', this._decayCameraStateTimeout)\n\t}\n\n\t/**\n\t * Whether the camera is moving or idle.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCameraState()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCameraState() {\n\t\treturn this._cameraState.get()\n\t}\n\n\t/**\n\t * Get the shapes that should be displayed in the current viewport.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getRenderingShapes()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getRenderingShapes() {\n\t\tconst renderingShapes = this.getUnorderedRenderingShapes(true)\n\n\t\t// Its IMPORTANT that the result be sorted by id AND include the index\n\t\t// that the shape should be displayed at. Steve, this is the past you\n\t\t// telling the present you not to change this.\n\n\t\t// We want to sort by id because moving elements about in the DOM will\n\t\t// cause the element to get removed by react as it moves the DOM node. This\n\t\t// causes <iframes/> to re-render which is hella annoying and a perf\n\t\t// drain. By always sorting by 'id' we keep the shapes always in the\n\t\t// same order; but we later use index to set the element's 'z-index'\n\t\t// to change the \"rendered\" position in z-space.\n\t\treturn renderingShapes.sort(sortById)\n\t}\n\n\t/* --------------------- Pages ---------------------- */\n\n\t@computed private _getAllPagesQuery() {\n\t\treturn this.store.query.records('page')\n\t}\n\n\t/**\n\t * Info about the project's current pages.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPages()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getPages(): TLPage[] {\n\t\treturn Array.from(this._getAllPagesQuery().get()).sort(sortByIndex)\n\t}\n\n\t/**\n\t * The current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPage()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPage(): TLPage {\n\t\treturn this.getPage(this.getCurrentPageId())!\n\t}\n\n\t/**\n\t * The current page id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageId()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageId(): TLPageId {\n\t\treturn this.getInstanceState().currentPageId\n\t}\n\n\t/**\n\t * Get a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPage(myPage.id)\n\t * editor.getPage(myPage)\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to get.\n\t *\n\t * @public\n\t */\n\tgetPage(page: TLPageId | TLPage): TLPage | undefined {\n\t\treturn this.store.get(typeof page === 'string' ? page : page.id)\n\t}\n\n\t/* @internal */\n\tprivate readonly _currentPageShapeIds: ReturnType<typeof deriveShapeIdsInCurrentPage>\n\n\t/**\n\t * An array of all of the shapes on the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getCurrentPageIds()\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetCurrentPageShapeIds() {\n\t\treturn this._currentPageShapeIds.get()\n\t}\n\n\t/**\n\t * @internal\n\t */\n\t@computed\n\tgetCurrentPageShapeIdsSorted() {\n\t\treturn Array.from(this.getCurrentPageShapeIds()).sort()\n\t}\n\n\t/**\n\t * Get the ids of shapes on a page.\n\t *\n\t * @example\n\t * ```ts\n\t * const idsOnPage1 = editor.getPageShapeIds('page1')\n\t * const idsOnPage2 = editor.getPageShapeIds(myPage2)\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to get the shape ids for.\n\t *\n\t * @public\n\t **/\n\tgetPageShapeIds(page: TLPageId | TLPage): Set<TLShapeId> {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tconst result = this.store.query.exec('shape', { parentId: { eq: pageId } })\n\t\treturn this.getShapeAndDescendantIds(result.map((s) => s.id))\n\t}\n\n\t/**\n\t * Set the current page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setCurrentPage('page1')\n\t * editor.setCurrentPage(myPage1)\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to set as the current page.\n\t *\n\t * @public\n\t */\n\tsetCurrentPage(page: TLPageId | TLPage): this {\n\t\tconst pageId = typeof page === 'string' ? page : page.id\n\t\tif (!this.store.has(pageId)) {\n\t\t\tconsole.error(\"Tried to set the current page id to a page that doesn't exist.\")\n\t\t\treturn this\n\t\t}\n\n\t\tthis.stopFollowingUser()\n\t\t// finish off any in-progress interactions\n\t\tthis.complete()\n\n\t\treturn this.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([{ ...this.getInstanceState(), currentPageId: pageId }])\n\t\t\t\t// ensure camera constraints are applied\n\t\t\t\tthis.setCamera(this.getCamera())\n\t\t\t},\n\t\t\t{ history: 'record-preserveRedoStack' }\n\t\t)\n\t}\n\n\t/**\n\t * Update a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updatePage({ id: 'page2', name: 'Page 2' })\n\t * ```\n\t *\n\t * @param partial - The partial of the shape to update.\n\t *\n\t * @public\n\t */\n\tupdatePage(partial: RequiredKeys<Partial<TLPage>, 'id'>): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst prev = this.getPage(partial.id)\n\t\tif (!prev) return this\n\n\t\treturn this.run(() => this.store.update(partial.id, (page) => ({ ...page, ...partial })))\n\t}\n\n\t/**\n\t * Create a page whilst ensuring that the page name is unique.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createPage(myPage)\n\t * editor.createPage({ name: 'Page 2' })\n\t * ```\n\t *\n\t * @param page - The page (or page partial) to create.\n\t *\n\t * @public\n\t */\n\tcreatePage(page: Partial<TLPage>): this {\n\t\tthis.run(() => {\n\t\t\tif (this.getIsReadonly()) return\n\t\t\tif (this.getPages().length >= this.options.maxPages) return\n\t\t\tconst pages = this.getPages()\n\n\t\t\tconst name = getIncrementedName(\n\t\t\t\tpage.name ?? 'Page 1',\n\t\t\t\tpages.map((p) => p.name)\n\t\t\t)\n\n\t\t\tlet index = page.index\n\n\t\t\tif (!index || pages.some((p) => p.index === index)) {\n\t\t\t\tindex = getIndexAbove(pages[pages.length - 1].index)\n\t\t\t}\n\n\t\t\tconst newPage = PageRecordType.create({\n\t\t\t\tmeta: {},\n\t\t\t\t...page,\n\t\t\t\tname,\n\t\t\t\tindex,\n\t\t\t})\n\n\t\t\tthis.store.put([newPage])\n\t\t})\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deletePage('page1')\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to delete.\n\t *\n\t * @public\n\t */\n\tdeletePage(page: TLPageId | TLPage): this {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tif (this.getIsReadonly()) return\n\t\t\t\tconst pages = this.getPages()\n\t\t\t\tif (pages.length === 1) return\n\n\t\t\t\tconst deletedPage = this.getPage(id)\n\t\t\t\tif (!deletedPage) return\n\n\t\t\t\tif (id === this.getCurrentPageId()) {\n\t\t\t\t\tconst index = pages.findIndex((page) => page.id === id)\n\t\t\t\t\tconst next = pages[index - 1] ?? pages[index + 1]\n\t\t\t\t\tthis.setCurrentPage(next.id)\n\t\t\t\t}\n\n\t\t\t\tconst shapes = this.getSortedChildIdsForParent(deletedPage.id)\n\t\t\t\tthis.deleteShapes(shapes)\n\n\t\t\t\tthis.store.remove([deletedPage.id])\n\t\t\t},\n\t\t\t{ ignoreShapeLock: true }\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate a page.\n\t *\n\t * @param page - The page (or the page id) to duplicate. Defaults to the current page.\n\t * @param createId - The id of the new page. Defaults to a new id.\n\t *\n\t * @public\n\t */\n\tduplicatePage(page: TLPageId | TLPage, createId: TLPageId = PageRecordType.createId()): this {\n\t\tif (this.getPages().length >= this.options.maxPages) return this\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tconst freshPage = this.getPage(id) // get the most recent version of the page anyway\n\t\tif (!freshPage) return this\n\n\t\tconst prevCamera = { ...this.getCamera() }\n\t\tconst content = this.getContentFromCurrentPage(this.getSortedChildIdsForParent(freshPage.id))\n\n\t\tthis.run(() => {\n\t\t\tconst pages = this.getPages()\n\t\t\tconst index = getIndexBetween(freshPage.index, pages[pages.indexOf(freshPage) + 1]?.index)\n\n\t\t\t// create the page (also creates the pagestate and camera for the new page)\n\t\t\tthis.createPage({ name: freshPage.name + ' Copy', id: createId, index })\n\t\t\t// set the new page as the current page\n\t\t\tthis.setCurrentPage(createId)\n\t\t\t// update the new page's camera to the previous page's camera\n\t\t\tthis.setCamera(prevCamera)\n\n\t\t\tif (content) {\n\t\t\t\t// If we had content on the previous page, put it on the new page\n\t\t\t\treturn this.putContentOntoCurrentPage(content)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Rename a page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.renamePage('page1', 'My Page')\n\t * ```\n\t *\n\t * @param page - The page (or the page id) to rename.\n\t * @param name - The new name.\n\t *\n\t * @public\n\t */\n\trenamePage(page: TLPageId | TLPage, name: string) {\n\t\tconst id = typeof page === 'string' ? page : page.id\n\t\tif (this.getIsReadonly()) return this\n\t\tthis.updatePage({ id, name })\n\t\treturn this\n\t}\n\n\t/* --------------------- Assets --------------------- */\n\n\t/** @internal */\n\t@computed private _getAllAssetsQuery() {\n\t\treturn this.store.query.records('asset')\n\t}\n\n\t/**\n\t * Get all assets in the editor.\n\t *\n\t * @public\n\t */\n\tgetAssets() {\n\t\treturn this._getAllAssetsQuery().get()\n\t}\n\n\t/**\n\t * Create one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createAssets([...myAssets])\n\t * ```\n\t *\n\t * @param assets - The assets to create.\n\t *\n\t * @public\n\t */\n\tcreateAssets(assets: TLAsset[]): this {\n\t\tif (this.getIsReadonly()) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(() => this.store.put(assets), { history: 'ignore' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Update one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateAssets([{ id: 'asset1', name: 'New name' }])\n\t * ```\n\t *\n\t * @param assets - The assets to update.\n\t *\n\t * @public\n\t */\n\tupdateAssets(assets: TLAssetPartial[]): this {\n\t\tif (this.getIsReadonly()) return this\n\t\tif (assets.length <= 0) return this\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put(\n\t\t\t\t\tassets.map((partial) => ({\n\t\t\t\t\t\t...this.store.get(partial.id)!,\n\t\t\t\t\t\t...partial,\n\t\t\t\t\t}))\n\t\t\t\t)\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Delete one or more assets.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteAssets(['asset1', 'asset2'])\n\t * ```\n\t *\n\t * @param assets - The assets (or asset ids) to delete.\n\t *\n\t * @public\n\t */\n\tdeleteAssets(assets: TLAssetId[] | TLAsset[]): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst ids =\n\t\t\ttypeof assets[0] === 'string'\n\t\t\t\t? (assets as TLAssetId[])\n\t\t\t\t: (assets as TLAsset[]).map((a) => a.id)\n\t\tif (ids.length <= 0) return this\n\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.props.assets.remove?.(ids)\n\t\t\t\tthis.store.remove(ids)\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an asset by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getAsset('asset1')\n\t * ```\n\t *\n\t * @param asset - The asset (or asset id) to get.\n\t *\n\t * @public\n\t */\n\tgetAsset<T extends TLAsset>(asset: T | T['id']): T | undefined {\n\t\treturn this.store.get(typeof asset === 'string' ? asset : asset.id) as T | undefined\n\t}\n\n\tasync resolveAssetUrl(\n\t\tassetId: TLAssetId | null,\n\t\tcontext: {\n\t\t\tscreenScale?: number\n\t\t\tshouldResolveToOriginal?: boolean\n\t\t\tdpr?: number\n\t\t}\n\t): Promise<string | null> {\n\t\tif (!assetId) return null\n\t\tconst asset = this.getAsset(assetId)\n\t\tif (!asset) return null\n\n\t\tconst {\n\t\t\tscreenScale = 1,\n\t\t\tshouldResolveToOriginal = false,\n\t\t\tdpr = this.getInstanceState().devicePixelRatio,\n\t\t} = context\n\n\t\t// We only look at the zoom level at powers of 2.\n\t\tconst zoomStepFunction = (zoom: number) => Math.pow(2, Math.ceil(Math.log2(zoom)))\n\t\tconst steppedScreenScale = zoomStepFunction(screenScale)\n\t\tconst networkEffectiveType: string | null =\n\t\t\t'connection' in navigator ? (navigator as any).connection.effectiveType : null\n\n\t\treturn await this.store.props.assets.resolve(asset, {\n\t\t\tscreenScale: screenScale || 1,\n\t\t\tsteppedScreenScale,\n\t\t\tdpr,\n\t\t\tnetworkEffectiveType,\n\t\t\tshouldResolveToOriginal,\n\t\t})\n\t}\n\t/**\n\t * Upload an asset to the store's asset service, returning a URL that can be used to resolve the\n\t * asset.\n\t */\n\tasync uploadAsset(\n\t\tasset: TLAsset,\n\t\tfile: File,\n\t\tabortSignal?: AbortSignal\n\t): Promise<{ src: string; meta?: JsonObject }> {\n\t\treturn await this.store.props.assets.upload(asset, file, abortSignal)\n\t}\n\n\t/* --------------------- Shapes --------------------- */\n\n\tprivate _shapeGeometryCaches: Record<string, ComputedCache<Geometry2d, TLShape>> = {}\n\n\t/**\n\t * Get the geometry of a shape in shape-space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeGeometry(myShape)\n\t * editor.getShapeGeometry(myShapeId)\n\t * editor.getShapeGeometry(myShapeId, { context: \"arrow\" })\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the geometry for.\n\t * @param opts - Additional options about the request for geometry. Passed to {@link ShapeUtil.getGeometry}.\n\t *\n\t * @public\n\t */\n\tgetShapeGeometry<T extends Geometry2d>(shape: TLShape | TLShapeId, opts?: TLGeometryOpts): T {\n\t\tconst context = opts?.context ?? 'none'\n\t\tif (!this._shapeGeometryCaches[context]) {\n\t\t\tthis._shapeGeometryCaches[context] = this.store.createComputedCache(\n\t\t\t\t'bounds',\n\t\t\t\t(shape) => {\n\t\t\t\t\tthis.fonts.trackFontsForShape(shape)\n\t\t\t\t\treturn this.getShapeUtil(shape).getGeometry(shape, opts)\n\t\t\t\t},\n\t\t\t\t{ areRecordsEqual: areShapesContentEqual }\n\t\t\t)\n\t\t}\n\t\treturn this._shapeGeometryCaches[context].get(\n\t\t\ttypeof shape === 'string' ? shape : shape.id\n\t\t)! as T\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeHandlesCache(): ComputedCache<TLHandle[] | undefined, TLShape> {\n\t\treturn this.store.createComputedCache(\n\t\t\t'handles',\n\t\t\t(shape) => {\n\t\t\t\treturn this.getShapeUtil(shape).getHandles?.(shape)\n\t\t\t},\n\t\t\t{\n\t\t\t\tareRecordsEqual: areShapesContentEqual,\n\t\t\t}\n\t\t)\n\t}\n\n\t/**\n\t * Get the handles (if any) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeHandles(myShape)\n\t * editor.getShapeHandles(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the handles for.\n\t * @public\n\t */\n\tgetShapeHandles<T extends TLShape>(shape: T | T['id']): TLHandle[] | undefined {\n\t\treturn this._getShapeHandlesCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the local transform for a shape as a matrix model. This transform reflects both its\n\t * translation (x, y) from from either its parent's top left corner, if the shape's parent is\n\t * another shape, or else from the 0,0 of the page, if the shape's parent is the page; and the\n\t * shape's rotation.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeLocalTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to get the local transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeLocalTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) throw Error('Editor.getTransform: shape not found')\n\t\treturn Mat.Identity().translate(freshShape.x, freshShape.y).rotate(freshShape.rotation)\n\t}\n\n\t/**\n\t * A cache of page transforms.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapePageTransformCache(): ComputedCache<Mat, TLShape> {\n\t\treturn this.store.createComputedCache<Mat, TLShape>('pageTransformCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) {\n\t\t\t\treturn this.getShapeLocalTransform(shape)\n\t\t\t}\n\n\t\t\t// If the shape's parent doesn't exist yet (e.g. when merging in changes from remote in the wrong order)\n\t\t\t// then we can't compute the transform yet, so just return the identity matrix.\n\t\t\t// In the future we should look at creating a store update mechanism that understands and preserves\n\t\t\t// ordering.\n\t\t\tconst parentTransform =\n\t\t\t\tthis._getShapePageTransformCache().get(shape.parentId) ?? Mat.Identity()\n\t\t\treturn Mat.Compose(parentTransform, this.getShapeLocalTransform(shape)!)\n\t\t})\n\t}\n\n\t/**\n\t * Get the local transform of a shape's parent as a matrix model.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParentTransform(myShape)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the parent transform for.\n\t *\n\t * @public\n\t */\n\tgetShapeParentTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape || isPageId(freshShape.parentId)) return Mat.Identity()\n\t\treturn this._getShapePageTransformCache().get(freshShape.parentId) ?? Mat.Identity()\n\t}\n\n\t/**\n\t * Get the transform of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageTransform(myShape)\n\t * editor.getShapePageTransform(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the page transform for.\n\t *\n\t * @public\n\t */\n\tgetShapePageTransform(shape: TLShape | TLShapeId): Mat {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id) ?? Mat.Identity()\n\t}\n\n\t/** @internal */\n\t@computed private _getShapePageBoundsCache(): ComputedCache<Box, TLShape> {\n\t\treturn this.store.createComputedCache<Box, TLShape>('pageBoundsCache', (shape) => {\n\t\t\tconst pageTransform = this.getShapePageTransform(shape)\n\t\t\tif (!pageTransform) return undefined\n\n\t\t\treturn Box.FromPoints(\n\t\t\t\tpageTransform.applyToPoints(this.getShapeGeometry(shape).boundsVertices)\n\t\t\t)\n\t\t})\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapePageBounds(myShape)\n\t * editor.getShapePageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapePageBounds(shape: TLShape | TLShapeId): Box | undefined {\n\t\treturn this._getShapePageBoundsCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * A cache of clip paths used for clipping.\n\t *\n\t * @internal\n\t */\n\t@computed private _getShapeClipPathCache(): ComputedCache<string, TLShape> {\n\t\treturn this.store.createComputedCache<string, TLShape>('clipPathCache', (shape) => {\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (!pageMask) return undefined\n\t\t\tif (pageMask.length === 0) {\n\t\t\t\treturn `polygon(0px 0px, 0px 0px, 0px 0px)`\n\t\t\t}\n\n\t\t\tconst pageTransform = this._getShapePageTransformCache().get(shape.id)\n\t\t\tif (!pageTransform) return undefined\n\n\t\t\tconst localMask = Mat.applyToPoints(Mat.Inverse(pageTransform), pageMask)\n\n\t\t\treturn `polygon(${localMask.map((p) => `${p.x}px ${p.y}px`).join(',')})`\n\t\t})\n\t}\n\n\t/**\n\t * Get the clip path for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const clipPath = editor.getShapeClipPath(shape)\n\t * const clipPath = editor.getShapeClipPath(shape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the clip path for.\n\t *\n\t * @returns The clip path or undefined.\n\t *\n\t * @public\n\t */\n\tgetShapeClipPath(shape: TLShape | TLShapeId): string | undefined {\n\t\treturn this._getShapeClipPathCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskCache(): ComputedCache<Vec[], TLShape> {\n\t\treturn this.store.createComputedCache('pageMaskCache', (shape) => {\n\t\t\tif (isPageId(shape.parentId)) return undefined\n\n\t\t\tconst clipPaths: Vec[][] = []\n\t\t\t// Get all ancestors that can potentially clip this shape\n\t\t\tfor (const ancestor of this.getShapeAncestors(shape.id)) {\n\t\t\t\tconst util = this.getShapeUtil(ancestor)\n\t\t\t\tconst clipPath = util.getClipPath?.(ancestor)\n\t\t\t\tif (!clipPath) continue\n\t\t\t\tif (util.shouldClipChild?.(shape) === false) continue\n\t\t\t\tconst pageTransform = this.getShapePageTransform(ancestor.id)\n\t\t\t\tclipPaths.push(pageTransform.applyToPoints(clipPath))\n\t\t\t}\n\t\t\tif (clipPaths.length === 0) return undefined\n\n\t\t\tconst pageMask = clipPaths.reduce((acc, b) => {\n\t\t\t\tconst intersection = intersectPolygonPolygon(acc, b)\n\t\t\t\tif (intersection) {\n\t\t\t\t\treturn intersection.map(Vec.Cast)\n\t\t\t\t}\n\t\t\t\treturn []\n\t\t\t})\n\n\t\t\treturn pageMask\n\t\t})\n\t}\n\n\t/**\n\t * Get the mask (in the current page space) for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const pageMask = editor.getShapeMask(shape.id)\n\t * ```\n\t *\n\t * @param shape - The shape (or the shape id) of the shape to get the mask for.\n\t *\n\t * @returns The mask for the shape.\n\t *\n\t * @public\n\t */\n\tgetShapeMask(shape: TLShapeId | TLShape): VecLike[] | undefined {\n\t\treturn this._getShapeMaskCache().get(typeof shape === 'string' ? shape : shape.id)\n\t}\n\n\t/**\n\t * Get the bounds of a shape in the current page space, incorporating any masks. For example, if the\n\t * shape were the child of a frame and was half way out of the frame, the bounds would be the half\n\t * of the shape that was in the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeMaskedPageBounds(myShape)\n\t * editor.getShapeMaskedPageBounds(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape to get the masked bounds for.\n\t *\n\t * @public\n\t */\n\tgetShapeMaskedPageBounds(shape: TLShapeId | TLShape): Box | undefined {\n\t\tif (typeof shape !== 'string') shape = shape.id\n\t\treturn this._getShapeMaskedPageBoundsCache().get(shape)\n\t}\n\n\t/** @internal */\n\t@computed private _getShapeMaskedPageBoundsCache(): ComputedCache<Box, TLShape> {\n\t\treturn this.store.createComputedCache('shapeMaskedPageBoundsCache', (shape) => {\n\t\t\tconst pageBounds = this._getShapePageBoundsCache().get(shape.id)\n\t\t\tif (!pageBounds) return\n\t\t\tconst pageMask = this._getShapeMaskCache().get(shape.id)\n\t\t\tif (pageMask) {\n\t\t\t\tif (pageMask.length === 0) return undefined\n\t\t\t\tconst { corners } = pageBounds\n\t\t\t\tif (corners.every((p, i) => p && Vec.Equals(p, pageMask[i]))) return pageBounds.clone()\n\t\t\t\tconst intersection = intersectPolygonPolygon(pageMask, corners)\n\t\t\t\tif (!intersection) return\n\t\t\t\treturn Box.FromPoints(intersection)\n\t\t\t}\n\t\t\treturn pageBounds\n\t\t})\n\t}\n\n\t/**\n\t * Get the ancestors of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestors = editor.getShapeAncestors(myShape)\n\t * const ancestors = editor.getShapeAncestors(myShapeId)\n\t * ```\n\t *\n\t * @param shape - The shape (or shape id) to get the ancestors for.\n\t * @param acc - The accumulator.\n\t *\n\t * @public\n\t */\n\tgetShapeAncestors(shape: TLShapeId | TLShape, acc: TLShape[] = []): TLShape[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return acc\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) {\n\t\t\tacc.reverse()\n\t\t\treturn acc\n\t\t}\n\n\t\tconst parent = this.store.get(parentId)\n\t\tif (!parent) return acc\n\t\tacc.push(parent)\n\t\treturn this.getShapeAncestors(parent, acc)\n\t}\n\n\t/**\n\t * Find the first ancestor matching the given predicate\n\t *\n\t * @example\n\t * ```ts\n\t * const ancestor = editor.findShapeAncestor(myShape)\n\t * const ancestor = editor.findShapeAncestor(myShape.id)\n\t * const ancestor = editor.findShapeAncestor(myShape.id, (shape) => shape.type === 'frame')\n\t * ```\n\t *\n\t * @param shape - The shape to check the ancestors for.\n\t * @param predicate - The predicate to match.\n\t *\n\t * @public\n\t */\n\tfindShapeAncestor(\n\t\tshape: TLShape | TLShapeId,\n\t\tpredicate: (parent: TLShape) => boolean\n\t): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return\n\n\t\tconst parentId = freshShape.parentId\n\t\tif (isPageId(parentId)) return\n\n\t\tconst parent = this.getShape(parentId)\n\t\tif (!parent) return\n\t\treturn predicate(parent) ? parent : this.findShapeAncestor(parent, predicate)\n\t}\n\n\t/**\n\t * Returns true if the the given shape has the given ancestor.\n\t *\n\t * @param shape - The shape.\n\t * @param ancestorId - The id of the ancestor.\n\t *\n\t * @public\n\t */\n\thasAncestor(shape: TLShape | TLShapeId | undefined, ancestorId: TLShapeId): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst freshShape = id && this.getShape(id)\n\t\tif (!freshShape) return false\n\t\tif (freshShape.parentId === ancestorId) return true\n\t\treturn this.hasAncestor(this.getShapeParent(freshShape), ancestorId)\n\t}\n\n\t/**\n\t * Get the common ancestor of two or more shapes that matches a predicate.\n\t *\n\t * @param shapes - The shapes (or shape ids) to check.\n\t * @param predicate - The predicate to match.\n\t */\n\tfindCommonAncestor(\n\t\tshapes: TLShape[] | TLShapeId[],\n\t\tpredicate?: (shape: TLShape) => boolean\n\t): TLShapeId | undefined {\n\t\tif (shapes.length === 0) {\n\t\t\treturn\n\t\t}\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst freshShapes = compact(ids.map((id) => this.getShape(id)))\n\n\t\tif (freshShapes.length === 1) {\n\t\t\tconst parentId = freshShapes[0].parentId\n\t\t\tif (isPageId(parentId)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\treturn predicate ? this.findShapeAncestor(freshShapes[0], predicate)?.id : parentId\n\t\t}\n\n\t\tconst [nodeA, ...others] = freshShapes\n\t\tlet ancestor = this.getShapeParent(nodeA)\n\t\twhile (ancestor) {\n\t\t\t// TODO: this is not ideal, optimize\n\t\t\tif (predicate && !predicate(ancestor)) {\n\t\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (others.every((shape) => this.hasAncestor(shape, ancestor!.id))) {\n\t\t\t\treturn ancestor!.id\n\t\t\t}\n\t\t\tancestor = this.getShapeParent(ancestor)\n\t\t}\n\t\treturn undefined\n\t}\n\n\t/**\n\t * Check whether a shape or its parent is locked.\n\t *\n\t * @param shape - The shape (or shape id) to check.\n\t *\n\t * @public\n\t */\n\tisShapeOrAncestorLocked(shape?: TLShape | TLShapeId): boolean {\n\t\tconst _shape = shape && this.getShape(shape)\n\t\tif (_shape === undefined) return false\n\t\tif (_shape.isLocked) return true\n\t\treturn this.isShapeOrAncestorLocked(this.getShapeParent(_shape))\n\t}\n\n\t/**\n\t * Get shapes that are outside of the viewport.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetNotVisibleShapes() {\n\t\treturn this._notVisibleShapes.get()\n\t}\n\n\tprivate _notVisibleShapes = notVisibleShapes(this)\n\n\t/**\n\t * Get culled shapes (those that should not render), taking into account which shapes are selected or editing.\n\t *\n\t * @public\n\t */\n\t@computed\n\tgetCulledShapes() {\n\t\tconst notVisibleShapes = this.getNotVisibleShapes()\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\tconst editingId = this.getEditingShapeId()\n\t\tconst culledShapes = new Set<TLShapeId>(notVisibleShapes)\n\t\t// we don't cull the shape we are editing\n\t\tif (editingId) {\n\t\t\tculledShapes.delete(editingId)\n\t\t}\n\t\t// we also don't cull selected shapes\n\t\tselectedShapeIds.forEach((id) => {\n\t\t\tculledShapes.delete(id)\n\t\t})\n\t\treturn culledShapes\n\t}\n\n\t/**\n\t * The bounds of the current page (the common bounds of all of the shapes on the page).\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageBounds(): Box | undefined {\n\t\tlet commonBounds: Box | undefined\n\n\t\tthis.getCurrentPageShapeIdsSorted().forEach((shapeId) => {\n\t\t\tconst bounds = this.getShapeMaskedPageBounds(shapeId)\n\t\t\tif (!bounds) return\n\t\t\tif (!commonBounds) {\n\t\t\t\tcommonBounds = bounds.clone()\n\t\t\t} else {\n\t\t\t\tcommonBounds = commonBounds.expand(bounds)\n\t\t\t}\n\t\t})\n\n\t\treturn commonBounds\n\t}\n\n\t/**\n\t * Get the top-most selected shape at the given point, ignoring groups.\n\t *\n\t * @param point - The point to check.\n\t *\n\t * @returns The top-most selected shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetSelectedShapeAtPoint(point: VecLike): TLShape | undefined {\n\t\tconst selectedShapeIds = this.getSelectedShapeIds()\n\t\treturn this.getCurrentPageShapesSorted()\n\t\t\t.filter((shape) => shape.type !== 'group' && selectedShapeIds.includes(shape.id))\n\t\t\t.reverse() // find last\n\t\t\t.find((shape) => this.isPointInShape(shape, point, { hitInside: true, margin: 0 }))\n\t}\n\n\t/**\n\t * Get the shape at the current point.\n\t *\n\t * @param point - The point to check.\n\t * @param opts - Options for the check: `hitInside` to check if the point is inside the shape, `margin` to check if the point is within a margin of the shape, `hitFrameInside` to check if the point is inside the frame, and `filter` to filter the shapes to check.\n\t *\n\t * @returns The shape at the given point, or undefined if there is no shape at the point.\n\t */\n\tgetShapeAtPoint(point: VecLike, opts: TLGetShapeAtPointOptions = {}): TLShape | undefined {\n\t\tconst zoomLevel = this.getZoomLevel()\n\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\tconst {\n\t\t\tfilter,\n\t\t\tmargin = 0,\n\t\t\thitLocked = false,\n\t\t\thitLabels = false,\n\t\t\thitInside = false,\n\t\t\thitFrameInside = false,\n\t\t} = opts\n\n\t\tconst [innerMargin, outerMargin] = Array.isArray(margin) ? margin : [margin, margin]\n\n\t\tlet inHollowSmallestArea = Infinity\n\t\tlet inHollowSmallestAreaHit: TLShape | null = null\n\n\t\tlet inMarginClosestToEdgeDistance = Infinity\n\t\tlet inMarginClosestToEdgeHit: TLShape | null = null\n\n\t\tconst shapesToCheck = (\n\t\t\topts.renderingOnly\n\t\t\t\t? this.getCurrentPageRenderingShapesSorted()\n\t\t\t\t: this.getCurrentPageShapesSorted()\n\t\t).filter((shape) => {\n\t\t\tif (\n\t\t\t\t(shape.isLocked && !hitLocked) ||\n\t\t\t\tthis.isShapeHidden(shape) ||\n\t\t\t\tthis.isShapeOfType(shape, 'group')\n\t\t\t)\n\t\t\t\treturn false\n\t\t\tconst pageMask = this.getShapeMask(shape)\n\t\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\t\t\tif (filter && !filter(shape)) return false\n\t\t\treturn true\n\t\t})\n\n\t\tfor (let i = shapesToCheck.length - 1; i >= 0; i--) {\n\t\t\tconst shape = shapesToCheck[i]\n\t\t\tconst geometry = this.getShapeGeometry(shape)\n\t\t\tconst isGroup = geometry instanceof Group2d\n\n\t\t\tconst pointInShapeSpace = this.getPointInShapeSpace(shape, point)\n\n\t\t\t// Check labels first\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType<TLFrameShape>(shape, 'frame') ||\n\t\t\t\t((this.isShapeOfType<TLNoteShape>(shape, 'note') ||\n\t\t\t\t\tthis.isShapeOfType<TLArrowShape>(shape, 'arrow') ||\n\t\t\t\t\t(this.isShapeOfType<TLGeoShape>(shape, 'geo') && shape.props.fill === 'none')) &&\n\t\t\t\t\tthis.getShapeUtil(shape).getText(shape)?.trim())\n\t\t\t) {\n\t\t\t\tfor (const childGeometry of (geometry as Group2d).children) {\n\t\t\t\t\tif (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {\n\t\t\t\t\t\treturn shape\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.isShapeOfType<TLFrameShape>(shape, 'frame')) {\n\t\t\t\t// On the rare case that we've hit a frame (not its label), test again hitInside to be forced true;\n\t\t\t\t// this prevents clicks from passing through the body of a frame to shapes behind it.\n\n\t\t\t\t// If the hit is within the frame's outer margin, then select the frame\n\t\t\t\tconst distance = geometry.distanceToPoint(pointInShapeSpace, hitFrameInside)\n\t\t\t\tif (\n\t\t\t\t\thitFrameInside\n\t\t\t\t\t\t? (distance > 0 && distance <= outerMargin) ||\n\t\t\t\t\t\t\t(distance <= 0 && distance > -innerMargin)\n\t\t\t\t\t\t: distance > 0 && distance <= outerMargin\n\t\t\t\t) {\n\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t}\n\n\t\t\t\tif (geometry.hitTestPoint(pointInShapeSpace, 0, true)) {\n\t\t\t\t\t// Once we've hit a frame, we want to end the search. If we have hit a shape\n\t\t\t\t\t// already, then this would either be above the frame or a child of the frame,\n\t\t\t\t\t// so we want to return that. Otherwise, the point is in the empty space of the\n\t\t\t\t\t// frame. If `hitFrameInside` is true (e.g. used drawing an arrow into the\n\t\t\t\t\t// frame) we the frame itself; other wise, (e.g. when hovering or pointing)\n\t\t\t\t\t// we would want to return null.\n\t\t\t\t\treturn (\n\t\t\t\t\t\tinMarginClosestToEdgeHit ||\n\t\t\t\t\t\tinHollowSmallestAreaHit ||\n\t\t\t\t\t\t(hitFrameInside ? shape : undefined)\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlet distance: number\n\n\t\t\tif (isGroup) {\n\t\t\t\tlet minDistance = Infinity\n\t\t\t\tfor (const childGeometry of geometry.children) {\n\t\t\t\t\tif (childGeometry.isLabel && !hitLabels) continue\n\n\t\t\t\t\t// hit test the all of the child geometries that aren't labels\n\t\t\t\t\tconst tDistance = childGeometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\tif (tDistance < minDistance) {\n\t\t\t\t\t\tminDistance = tDistance\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tdistance = minDistance\n\t\t\t} else {\n\t\t\t\t// If the margin is zero and the geometry has a very small width or height,\n\t\t\t\t// then check the actual distance. This is to prevent a bug where straight\n\t\t\t\t// lines would never pass the broad phase (point-in-bounds) check.\n\t\t\t\tif (outerMargin === 0 && (geometry.bounds.w < 1 || geometry.bounds.h < 1)) {\n\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t} else {\n\t\t\t\t\t// Broad phase\n\t\t\t\t\tif (geometry.bounds.containsPoint(pointInShapeSpace, outerMargin)) {\n\t\t\t\t\t\t// Narrow phase (actual distance)\n\t\t\t\t\t\tdistance = geometry.distanceToPoint(pointInShapeSpace, hitInside)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Failed the broad phase, geddafugaotta'ere!\n\t\t\t\t\t\tdistance = Infinity\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (geometry.isClosed) {\n\t\t\t\t// For closed shapes, the distance will be positive if outside of\n\t\t\t\t// the shape or negative if inside of the shape. If the distance\n\t\t\t\t// is greater than the margin, then it's a miss. Otherwise...\n\n\t\t\t\t// Are we close to the shape's edge?\n\t\t\t\tif (distance <= outerMargin || (hitInside && distance <= 0 && distance > -innerMargin)) {\n\t\t\t\t\tif (geometry.isFilled || (isGroup && geometry.children[0].isFilled)) {\n\t\t\t\t\t\t// If the shape is filled, then it's a hit. Remember, we're\n\t\t\t\t\t\t// starting from the TOP-MOST shape in z-index order, so any\n\t\t\t\t\t\t// other hits would be occluded by the shape.\n\t\t\t\t\t\treturn inMarginClosestToEdgeHit || shape\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the shape is bigger than the viewport, then skip it.\n\t\t\t\t\t\tif (this.getShapePageBounds(shape)!.contains(viewportPageBounds)) continue\n\n\t\t\t\t\t\t// If we're close to the edge of the shape, and if it's the closest edge among\n\t\t\t\t\t\t// all the edges that we've gotten close to so far, then we will want to hit the\n\t\t\t\t\t\t// shape unless we hit something else or closer in later iterations.\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\thitInside\n\t\t\t\t\t\t\t\t? // On hitInside, the distance will be negative for hits inside\n\t\t\t\t\t\t\t\t\t// If the distance is positive, check against the outer margin\n\t\t\t\t\t\t\t\t\t(distance > 0 && distance <= outerMargin) ||\n\t\t\t\t\t\t\t\t\t// If the distance is negative, check against the inner margin\n\t\t\t\t\t\t\t\t\t(distance <= 0 && distance > -innerMargin)\n\t\t\t\t\t\t\t\t: // If hitInside is false, then sadly _we do not know_ whether the\n\t\t\t\t\t\t\t\t\t// point is inside or outside of the shape, so we check against\n\t\t\t\t\t\t\t\t\t// the max of the two margins\n\t\t\t\t\t\t\t\t\tMath.abs(distance) <= Math.max(innerMargin, outerMargin)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tif (Math.abs(distance) < inMarginClosestToEdgeDistance) {\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeDistance = Math.abs(distance)\n\t\t\t\t\t\t\t\tinMarginClosestToEdgeHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (!inMarginClosestToEdgeHit) {\n\t\t\t\t\t\t\t// If we're not within margin distance to any edge, and if the\n\t\t\t\t\t\t\t// shape is hollow, then we want to hit the shape with the\n\t\t\t\t\t\t\t// smallest area. (There's a bug here with self-intersecting\n\t\t\t\t\t\t\t// shapes, like a closed drawing of an \"8\", but that's a bigger\n\t\t\t\t\t\t\t// problem to solve.)\n\t\t\t\t\t\t\tconst { area } = geometry\n\t\t\t\t\t\t\tif (area < inHollowSmallestArea) {\n\t\t\t\t\t\t\t\tinHollowSmallestArea = area\n\t\t\t\t\t\t\t\tinHollowSmallestAreaHit = shape\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// For open shapes (e.g. lines or draw shapes) always use the margin.\n\t\t\t\t// If the distance is less than the margin, return the shape as the hit.\n\t\t\t\t// Use the editor's configurable hit test margin.\n\t\t\t\tif (distance < this.options.hitTestMargin / zoomLevel) {\n\t\t\t\t\treturn shape\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we haven't hit any filled shapes or frames, then return either\n\t\t// the shape who we hit within the margin (and of those, the one that\n\t\t// had the shortest distance between the point and the shape edge),\n\t\t// or else the hollow shape with the smallest area\u2014or if we didn't hit\n\t\t// any margins or any hollow shapes, then null.\n\t\treturn inMarginClosestToEdgeHit || inHollowSmallestAreaHit || undefined\n\t}\n\n\t/**\n\t * Get the shapes, if any, at a given page point.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapesAtPoint({ x: 100, y: 100 })\n\t * editor.getShapesAtPoint({ x: 100, y: 100 }, { hitInside: true, margin: 8 })\n\t * ```\n\t *\n\t * @param point - The page point to test.\n\t * @param opts - The options for the hit point testing.\n\t *\n\t * @returns An array of shapes at the given point, sorted in reverse order of their absolute z-index (top-most shape first).\n\t *\n\t * @public\n\t */\n\tgetShapesAtPoint(\n\t\tpoint: VecLike,\n\t\topts = {} as { margin?: number; hitInside?: boolean }\n\t): TLShape[] {\n\t\treturn this.getCurrentPageShapesSorted()\n\t\t\t.filter((shape) => !this.isShapeHidden(shape) && this.isPointInShape(shape, point, opts))\n\t\t\t.reverse()\n\t}\n\n\t/**\n\t * Test whether a point (in the current page space) will will a shape. This method takes into account masks,\n\t * such as when a shape is the child of a frame and is partially clipped by the frame.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isPointInShape({ x: 100, y: 100 }, myShape)\n\t * ```\n\t *\n\t * @param shape - The shape to test against.\n\t * @param point - The page point to test (in the current page space).\n\t * @param opts - The options for the hit point testing.\n\t *\n\t * @public\n\t */\n\tisPointInShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tpoint: VecLike,\n\t\topts = {} as {\n\t\t\tmargin?: number\n\t\t\thitInside?: boolean\n\t\t}\n\t): boolean {\n\t\tconst { hitInside = false, margin = 0 } = opts\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\t// If the shape is masked, and if the point falls outside of that\n\t\t// mask, then it's definitely a miss\u2014we don't need to test further.\n\t\tconst pageMask = this.getShapeMask(id)\n\t\tif (pageMask && !pointInPolygon(point, pageMask)) return false\n\n\t\treturn this.getShapeGeometry(id).hitTestPoint(\n\t\t\tthis.getPointInShapeSpace(shape, point),\n\t\t\tmargin,\n\t\t\thitInside\n\t\t)\n\t}\n\n\t/**\n\t * Convert a point in the current page space to a point in the local space of a shape. For example, if a\n\t * shape's page point were `{ x: 100, y: 100 }`, a page point at `{ x: 110, y: 110 }` would be at\n\t * `{ x: 10, y: 10 }` in the shape's local space.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInShapeSpace(myShape, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInShapeSpace(shape: TLShape | TLShapeId, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this._getShapePageTransformCache().get(id)!.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * Convert a delta in the current page space to a point in the local space of a shape's parent.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getPointInParentSpace(myShape.id, { x: 100, y: 100 })\n\t * ```\n\t *\n\t * @param shape - The shape to get the point in the local space of.\n\t * @param point - The page point to get in the local space of the shape.\n\t *\n\t * @public\n\t */\n\tgetPointInParentSpace(shape: TLShapeId | TLShape, point: VecLike): Vec {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)\n\t\tif (!freshShape) return new Vec(0, 0)\n\t\tif (isPageId(freshShape.parentId)) return Vec.From(point)\n\n\t\tconst parentTransform = this.getShapePageTransform(freshShape.parentId)\n\t\tif (!parentTransform) return Vec.From(point)\n\t\treturn parentTransform.clone().invert().applyToPoint(point)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapes(): TLShape[] {\n\t\treturn Array.from(this.getCurrentPageShapeIds(), (id) => this.store.get(id)! as TLShape)\n\t}\n\n\t/**\n\t * An array containing all of the shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageShapesSorted(): TLShape[] {\n\t\tconst result: TLShape[] = []\n\t\tconst topLevelShapes = this.getSortedChildIdsForParent(this.getCurrentPageId())\n\n\t\tfor (let i = 0, n = topLevelShapes.length; i < n; i++) {\n\t\t\tpushShapeWithDescendants(this, topLevelShapes[i], result)\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * An array containing all of the rendering shapes in the current page, sorted in z-index order (accounting\n\t * for nested shapes): e.g. A, B, BA, BB, C.\n\t *\n\t * @public\n\t */\n\t@computed getCurrentPageRenderingShapesSorted(): TLShape[] {\n\t\tconst culledShapes = this.getCulledShapes()\n\t\treturn this.getCurrentPageShapesSorted().filter(\n\t\t\t({ id }) => !culledShapes.has(id) && !this.isShapeHidden(id)\n\t\t)\n\t}\n\n\t/**\n\t * Get whether a shape matches the type of a TLShapeUtil.\n\t *\n\t * @example\n\t * ```ts\n\t * const isArrowShape = isShapeOfType<TLArrowShape>(someShape, 'arrow')\n\t * ```\n\t *\n\t * @param util - the TLShapeUtil constructor to test against\n\t * @param shape - the shape to test\n\t *\n\t * @public\n\t */\n\tisShapeOfType<T extends TLUnknownShape>(shape: TLUnknownShape, type: T['type']): shape is T\n\tisShapeOfType<T extends TLUnknownShape>(\n\t\tshapeId: TLUnknownShape['id'],\n\t\ttype: T['type']\n\t): shapeId is T['id']\n\tisShapeOfType<T extends TLUnknownShape>(\n\t\targ: TLUnknownShape | TLUnknownShape['id'],\n\t\ttype: T['type']\n\t) {\n\t\tconst shape = typeof arg === 'string' ? this.getShape(arg) : arg\n\t\tif (!shape) return false\n\t\treturn shape.type === type\n\t}\n\n\t/**\n\t * Get a shape by its id.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShape('box1')\n\t * ```\n\t *\n\t * @param shape - The shape (or the id of the shape) to get.\n\t *\n\t * @public\n\t */\n\tgetShape<T extends TLShape = TLShape>(shape: TLShape | TLParentId): T | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (!isShapeId(id)) return undefined\n\t\treturn this.store.get(id) as T\n\t}\n\n\t/**\n\t * Get the parent shape for a given shape. Returns undefined if the shape is the direct child of\n\t * the page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getShapeParent(myShape)\n\t * ```\n\t *\n\t * @public\n\t */\n\tgetShapeParent(shape?: TLShape | TLShapeId): TLShape | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tif (!id) return undefined\n\t\tconst freshShape = this.getShape(id)\n\t\tif (freshShape === undefined || !isShapeId(freshShape.parentId)) return undefined\n\t\treturn this.getShape(freshShape.parentId)\n\t}\n\n\t/**\n\t * If siblingShape and targetShape are siblings, this returns targetShape. If targetShape has an\n\t * ancestor who is a sibling of siblingShape, this returns that ancestor. Otherwise, this returns\n\t * undefined.\n\t *\n\t * @internal\n\t */\n\tgetShapeNearestSibling(\n\t\tsiblingShape: TLShape,\n\t\ttargetShape: TLShape | undefined\n\t): TLShape | undefined {\n\t\tif (!targetShape) {\n\t\t\treturn undefined\n\t\t}\n\t\tif (targetShape.parentId === siblingShape.parentId) {\n\t\t\treturn targetShape\n\t\t}\n\n\t\tconst ancestor = this.findShapeAncestor(\n\t\t\ttargetShape,\n\t\t\t(ancestor) => ancestor.parentId === siblingShape.parentId\n\t\t)\n\n\t\treturn ancestor\n\t}\n\n\t/**\n\t * Get whether the given shape is the descendant of the given page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.isShapeInPage(myShape)\n\t * editor.isShapeInPage(myShape, 'page1')\n\t * ```\n\t *\n\t * @param shape - The shape to check.\n\t * @param pageId - The id of the page to check against. Defaults to the current page.\n\t *\n\t * @public\n\t */\n\tisShapeInPage(shape: TLShape | TLShapeId, pageId = this.getCurrentPageId()): boolean {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst shapeToCheck = this.getShape(id)\n\t\tif (!shapeToCheck) return false\n\n\t\tlet shapeIsInPage = false\n\n\t\tif (shapeToCheck.parentId === pageId) {\n\t\t\tshapeIsInPage = true\n\t\t} else {\n\t\t\tlet parent = this.getShape(shapeToCheck.parentId)\n\t\t\tisInPageSearch: while (parent) {\n\t\t\t\tif (parent.parentId === pageId) {\n\t\t\t\t\tshapeIsInPage = true\n\t\t\t\t\tbreak isInPageSearch\n\t\t\t\t}\n\t\t\t\tparent = this.getShape(parent.parentId)\n\t\t\t}\n\t\t}\n\n\t\treturn shapeIsInPage\n\t}\n\n\t/**\n\t * Get the id of the containing page for a given shape.\n\t *\n\t * @param shape - The shape to get the page id for.\n\t *\n\t * @returns The id of the page that contains the shape, or undefined if the shape is undefined.\n\t *\n\t * @public\n\t */\n\tgetAncestorPageId(shape?: TLShape | TLShapeId): TLPageId | undefined {\n\t\tconst id = typeof shape === 'string' ? shape : shape?.id\n\t\tconst _shape = id && this.getShape(id)\n\t\tif (!_shape) return undefined\n\t\tif (isPageId(_shape.parentId)) {\n\t\t\treturn _shape.parentId\n\t\t} else {\n\t\t\treturn this.getAncestorPageId(this.getShape(_shape.parentId))\n\t\t}\n\t}\n\n\t// Parents and children\n\n\t/**\n\t * A cache of parents to children.\n\t *\n\t * @internal\n\t */\n\tprivate readonly _parentIdsToChildIds: ReturnType<typeof parentsToChildren>\n\n\t/**\n\t * Reparent shapes to a new parent. This operation preserves the shape's current page positions /\n\t * rotations.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.reparentShapes([box1, box2], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1')\n\t * editor.reparentShapes([box1.id, box2.id], 'frame1', 4)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to reparent.\n\t * @param parentId - The id of the new parent shape.\n\t * @param insertIndex - The index to insert the children.\n\t *\n\t * @public\n\t */\n\treparentShapes(shapes: TLShapeId[] | TLShape[], parentId: TLParentId, insertIndex?: IndexKey) {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string' ? (shapes as TLShapeId[]) : shapes.map((s) => (s as TLShape).id)\n\t\tif (ids.length === 0) return this\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tconst parentTransform = isPageId(parentId)\n\t\t\t? Mat.Identity()\n\t\t\t: this.getShapePageTransform(parentId)!\n\n\t\tconst parentPageRotation = parentTransform.rotation()\n\n\t\tlet indices: IndexKey[] = []\n\n\t\tconst sibs = compact(this.getSortedChildIdsForParent(parentId).map((id) => this.getShape(id)))\n\n\t\tif (insertIndex) {\n\t\t\tconst sibWithInsertIndex = sibs.find((s) => s.index === insertIndex)\n\t\t\tif (sibWithInsertIndex) {\n\t\t\t\t// If there's a sibling with the same index as the insert index...\n\t\t\t\tconst sibAbove = sibs[sibs.indexOf(sibWithInsertIndex) + 1]\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the sibling has a sibling above it, insert the shapes\n\t\t\t\t\t// between the sibling and its sibling above it.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Or if the sibling is the top sibling, insert the shapes\n\t\t\t\t\t// above the sibling\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If there's no collision, then we can start at the insert index\n\t\t\t\tconst sibAbove = sibs.sort(sortByIndex).find((s) => s.index > insertIndex)\n\n\t\t\t\tif (sibAbove) {\n\t\t\t\t\t// If the siblings include a sibling with a higher index, insert the shapes\n\t\t\t\t\t// between the insert index and the sibling with the higher index.\n\t\t\t\t\tindices = getIndicesBetween(insertIndex, sibAbove.index, ids.length)\n\t\t\t\t} else {\n\t\t\t\t\t// Otherwise, we're at the top of the order, so insert the shapes above\n\t\t\t\t\t// the insert index.\n\t\t\t\t\tindices = getIndicesAbove(insertIndex, ids.length)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// If insert index is not specified, start the index at the top.\n\t\t\tconst sib = sibs.length && sibs[sibs.length - 1]\n\t\t\tindices = sib ? getIndicesAbove(sib.index, ids.length) : getIndices(ids.length)\n\t\t}\n\n\t\tconst invertedParentTransform = parentTransform.clone().invert()\n\n\t\tconst shapesToReparent = compact(ids.map((id) => this.getShape(id))).sort(sortByIndex)\n\n\t\t// Ignore locked shapes so that we can reparent locked shapes, for example\n\t\t// when a locked shape's parent is deleted.\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tfor (let i = 0; i < shapesToReparent.length; i++) {\n\t\t\t\t\tconst shape = shapesToReparent[i]\n\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape)!\n\t\t\t\t\tif (!pageTransform) continue\n\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tif (!pagePoint) continue\n\n\t\t\t\t\tconst newPoint = invertedParentTransform.applyToPoint(pagePoint)\n\t\t\t\t\tconst newRotation = pageTransform.rotation() - parentPageRotation\n\n\t\t\t\t\tif (shape.id === parentId) {\n\t\t\t\t\t\tthrow Error('Attempted to reparent a shape to itself!')\n\t\t\t\t\t}\n\n\t\t\t\t\tchanges.push({\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\tparentId: parentId,\n\t\t\t\t\t\tx: newPoint.x,\n\t\t\t\t\t\ty: newPoint.y,\n\t\t\t\t\t\trotation: newRotation,\n\t\t\t\t\t\tindex: indices[i],\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tthis.updateShapes(changes)\n\t\t\t},\n\t\t\t{ ignoreShapeLock: true }\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the index above the highest child of a given parent.\n\t *\n\t * @param parent - The parent (or the id) of the parent.\n\t *\n\t * @returns The index.\n\t *\n\t * @public\n\t */\n\tgetHighestIndexForParent(parent: TLParentId | TLPage | TLShape): IndexKey {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst children = this._parentIdsToChildIds.get()[parentId]\n\n\t\tif (!children || children.length === 0) {\n\t\t\treturn getIndexAbove(ZERO_INDEX_KEY)\n\t\t}\n\t\tconst shape = this.getShape(children[children.length - 1])!\n\t\treturn getIndexAbove(shape.index)\n\t}\n\n\t/**\n\t * Get an array of all the children of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getSortedChildIdsForParent('frame1')\n\t * ```\n\t *\n\t * @param parent - The parent (or the id) of the parent shape.\n\t *\n\t * @public\n\t */\n\tgetSortedChildIdsForParent(parent: TLParentId | TLPage | TLShape): TLShapeId[] {\n\t\tconst parentId = typeof parent === 'string' ? parent : parent.id\n\t\tconst ids = this._parentIdsToChildIds.get()[parentId]\n\t\tif (!ids) return EMPTY_ARRAY\n\t\treturn ids\n\t}\n\n\t/**\n\t * Run a visitor function for all descendants of a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.visitDescendants('frame1', myCallback)\n\t * ```\n\t *\n\t * @param parent - The parent (or the id) of the parent shape.\n\t * @param visitor - The visitor function.\n\t *\n\t * @public\n\t */\n\tvisitDescendants(\n\t\tparent: TLParentId | TLPage | TLShape,\n\t\tvisitor: (id: TLShapeId) => void | false\n\t): this {\n\t\tconst children = this.getSortedChildIdsForParent(parent)\n\t\tfor (const id of children) {\n\t\t\tif (visitor(id) === false) continue\n\t\t\tthis.visitDescendants(id, visitor)\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the shape ids of all descendants of the given shapes (including the shapes themselves). IDs are returned in z-index order.\n\t *\n\t * @param ids - The ids of the shapes to get descendants of.\n\t *\n\t * @returns The descendant ids.\n\t *\n\t * @public\n\t */\n\tgetShapeAndDescendantIds(ids: TLShapeId[]): Set<TLShapeId> {\n\t\tconst shapeIds = new Set<TLShapeId>()\n\t\tfor (const shape of ids.map((id) => this.getShape(id)!).sort(sortByIndex)) {\n\t\t\tshapeIds.add(shape.id)\n\t\t\tthis.visitDescendants(shape, (descendantId) => {\n\t\t\t\tshapeIds.add(descendantId)\n\t\t\t})\n\t\t}\n\t\treturn shapeIds\n\t}\n\n\t/**\n\t * Get the shape that some shapes should be dropped on at a given point.\n\t *\n\t * @param point - The point to find the parent for.\n\t * @param droppingShapes - The shapes that are being dropped.\n\t *\n\t * @returns The shape to drop on.\n\t *\n\t * @public\n\t */\n\tgetDraggingOverShape(point: Vec, droppingShapes: TLShape[]): TLShape | undefined {\n\t\t// get fresh moving shapes\n\t\tconst draggingShapes = compact(droppingShapes.map((s) => this.getShape(s))).filter(\n\t\t\t(s) => !s.isLocked && !this.isShapeHidden(s)\n\t\t)\n\n\t\tconst maybeDraggingOverShapes = this.getShapesAtPoint(point, {\n\t\t\thitInside: true,\n\t\t\tmargin: 0,\n\t\t}).filter(\n\t\t\t(s) =>\n\t\t\t\t!droppingShapes.includes(s) &&\n\t\t\t\t!s.isLocked &&\n\t\t\t\t!this.isShapeHidden(s) &&\n\t\t\t\t!draggingShapes.includes(s)\n\t\t)\n\n\t\tfor (const maybeDraggingOverShape of maybeDraggingOverShapes) {\n\t\t\tconst shapeUtil = this.getShapeUtil(maybeDraggingOverShape)\n\t\t\t// Any shape that can handle any dragging interactions is a valid target\n\t\t\tif (\n\t\t\t\tshapeUtil.onDragShapesOver ||\n\t\t\t\tshapeUtil.onDragShapesIn ||\n\t\t\t\tshapeUtil.onDragShapesOut ||\n\t\t\t\tshapeUtil.onDropShapesOver\n\t\t\t) {\n\t\t\t\treturn maybeDraggingOverShape\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the shape that should be selected when you click on a given shape, assuming there is\n\t * nothing already selected. It will not return anything higher than or including the current\n\t * focus layer.\n\t *\n\t * @param shape - The shape to get the outermost selectable shape for.\n\t * @param filter - A function to filter the selectable shapes.\n\t *\n\t * @returns The outermost selectable shape.\n\t *\n\t * @public\n\t */\n\tgetOutermostSelectableShape(\n\t\tshape: TLShape | TLShapeId,\n\t\tfilter?: (shape: TLShape) => boolean\n\t): TLShape {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst freshShape = this.getShape(id)!\n\t\tlet match = freshShape\n\t\tlet node = freshShape as TLShape | undefined\n\n\t\tconst focusedGroup = this.getFocusedGroup()\n\n\t\twhile (node) {\n\t\t\tif (\n\t\t\t\tthis.isShapeOfType<TLGroupShape>(node, 'group') &&\n\t\t\t\tfocusedGroup?.id !== node.id &&\n\t\t\t\t!this.hasAncestor(focusedGroup, node.id) &&\n\t\t\t\t(filter?.(node) ?? true)\n\t\t\t) {\n\t\t\t\tmatch = node\n\t\t\t} else if (focusedGroup?.id === node.id) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tnode = this.getShapeParent(node)\n\t\t}\n\n\t\treturn match\n\t}\n\n\t/* -------------------- Bindings -------------------- */\n\n\t@computed\n\tprivate _getBindingsIndexCache() {\n\t\tconst index = bindingsIndex(this)\n\t\treturn this.store.createComputedCache<TLBinding[], TLShape>(\n\t\t\t'bindingsIndex',\n\t\t\t(shape) => {\n\t\t\t\treturn index.get().get(shape.id)\n\t\t\t},\n\t\t\t// we can ignore the shape equality check here because the index is\n\t\t\t// computed incrementally based on what bindings are in the store\n\t\t\t{ areRecordsEqual: () => true }\n\t\t)\n\t}\n\n\t/**\n\t * Get a binding from the store by its ID if it exists.\n\t */\n\tgetBinding(id: TLBindingId): TLBinding | undefined {\n\t\treturn this.store.get(id) as TLBinding | undefined\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _from_ a particular shape. These are the bindings whose\n\t * `fromId` matched the shape's ID.\n\t */\n\tgetBindingsFromShape<Binding extends TLUnknownBinding = TLBinding>(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.fromId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings of a certain type _to_ a particular shape. These are the bindings whose\n\t * `toId` matches the shape's ID.\n\t */\n\tgetBindingsToShape<Binding extends TLUnknownBinding = TLBinding>(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\treturn this.getBindingsInvolvingShape(id).filter(\n\t\t\t(b) => b.toId === id && b.type === type\n\t\t) as Binding[]\n\t}\n\n\t/**\n\t * Get all bindings involving a particular shape. This includes bindings where the shape is the\n\t * `fromId` or `toId`. If a type is provided, only bindings of that type are returned.\n\t */\n\tgetBindingsInvolvingShape<Binding extends TLUnknownBinding = TLBinding>(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype?: Binding['type']\n\t): Binding[] {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tconst result = this._getBindingsIndexCache().get(id) ?? EMPTY_ARRAY\n\t\tif (!type) return result as Binding[]\n\t\treturn result.filter((b) => b.type === type) as Binding[]\n\t}\n\n\t/**\n\t * Create bindings from a list of partial bindings. You can omit the ID and most props of a\n\t * binding, but the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBindings<B extends TLBinding = TLBinding>(partials: TLBindingCreate<B>[]) {\n\t\tconst bindings: TLBinding[] = []\n\t\tfor (const partial of partials) {\n\t\t\tconst fromShape = this.getShape(partial.fromId)\n\t\t\tconst toShape = this.getShape(partial.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: partial })) continue\n\n\t\t\tconst util = this.getBindingUtil<TLUnknownBinding>(partial.type)\n\t\t\tconst defaultProps = util.getDefaultProps()\n\t\t\tconst binding = this.store.schema.types.binding.create({\n\t\t\t\t...partial,\n\t\t\t\tid: partial.id ?? createBindingId(),\n\t\t\t\tprops: {\n\t\t\t\t\t...defaultProps,\n\t\t\t\t\t...partial.props,\n\t\t\t\t},\n\t\t\t}) as TLBinding\n\n\t\t\tbindings.push(binding)\n\t\t}\n\n\t\tthis.store.put(bindings)\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a single binding from a partial. You can omit the ID and most props of a binding, but\n\t * the `type`, `toId`, and `fromId` must all be provided.\n\t */\n\tcreateBinding<B extends TLBinding = TLBinding>(partial: TLBindingCreate<B>) {\n\t\treturn this.createBindings([partial])\n\t}\n\n\t/**\n\t * Update bindings from a list of partial bindings. Each partial must include an ID, which will\n\t * be used to match the binding to it's existing record. If there is no existing record, that\n\t * binding is skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBindings(partials: (TLBindingUpdate | null | undefined)[]) {\n\t\tconst updated: TLBinding[] = []\n\n\t\tfor (const partial of partials) {\n\t\t\tif (!partial) continue\n\n\t\t\tconst current = this.getBinding(partial.id)\n\t\t\tif (!current) continue\n\n\t\t\tconst updatedBinding = applyPartialToRecordWithProps(current, partial)\n\t\t\tif (updatedBinding === current) continue\n\n\t\t\tconst fromShape = this.getShape(updatedBinding.fromId)\n\t\t\tconst toShape = this.getShape(updatedBinding.toId)\n\t\t\tif (!fromShape || !toShape) continue\n\t\t\tif (!this.canBindShapes({ fromShape, toShape, binding: updatedBinding })) continue\n\n\t\t\tupdated.push(updatedBinding)\n\t\t}\n\n\t\tthis.store.put(updated)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a binding from a partial binding. Each partial must include an ID, which will be used\n\t * to match the binding to it's existing record. If there is no existing record, that binding is\n\t * skipped. The changes from the partial are merged into the existing record.\n\t */\n\tupdateBinding<B extends TLBinding = TLBinding>(partial: TLBindingUpdate<B>) {\n\t\treturn this.updateBindings([partial])\n\t}\n\n\t/**\n\t * Delete several bindings by their IDs. If a binding ID doesn't exist, it's ignored.\n\t */\n\tdeleteBindings(bindings: (TLBinding | TLBindingId)[], { isolateShapes = false } = {}) {\n\t\tconst ids = bindings.map((binding) => (typeof binding === 'string' ? binding : binding.id))\n\t\tif (isolateShapes) {\n\t\t\tthis.store.atomic(() => {\n\t\t\t\tfor (const id of ids) {\n\t\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\t\tif (!binding) continue\n\t\t\t\t\tconst util = this.getBindingUtil(binding)\n\t\t\t\t\tutil.onBeforeIsolateFromShape?.({ binding, removedShape: this.getShape(binding.toId)! })\n\t\t\t\t\tutil.onBeforeIsolateToShape?.({ binding, removedShape: this.getShape(binding.fromId)! })\n\t\t\t\t\tthis.store.remove([id])\n\t\t\t\t}\n\t\t\t})\n\t\t} else {\n\t\t\tthis.store.remove(ids)\n\t\t}\n\t\treturn this\n\t}\n\t/**\n\t * Delete a binding by its ID. If the binding doesn't exist, it's ignored.\n\t */\n\tdeleteBinding(binding: TLBinding | TLBindingId, opts?: Parameters<this['deleteBindings']>[1]) {\n\t\treturn this.deleteBindings([binding], opts)\n\t}\n\tcanBindShapes({\n\t\tfromShape,\n\t\ttoShape,\n\t\tbinding,\n\t}: {\n\t\tfromShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\ttoShape: TLShape | { type: TLShape['type'] } | TLShape['type']\n\t\tbinding: TLBinding | { type: TLBinding['type'] } | TLBinding['type']\n\t}): boolean {\n\t\tconst fromShapeType = typeof fromShape === 'string' ? fromShape : fromShape.type\n\t\tconst toShapeType = typeof toShape === 'string' ? toShape : toShape.type\n\t\tconst bindingType = typeof binding === 'string' ? binding : binding.type\n\n\t\tconst canBindOpts = { fromShapeType, toShapeType, bindingType }\n\n\t\tif (fromShapeType === toShapeType) {\n\t\t\treturn this.getShapeUtil(fromShapeType).canBind(canBindOpts)\n\t\t}\n\n\t\treturn (\n\t\t\tthis.getShapeUtil(fromShapeType).canBind(canBindOpts) &&\n\t\t\tthis.getShapeUtil(toShapeType).canBind(canBindOpts)\n\t\t)\n\t}\n\n\t/* -------------------- Commands -------------------- */\n\n\t/**\n\t * Rotate shapes by a delta in radians.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI)\n\t * editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI / 2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param delta - The delta in radians to apply to the selection rotation.\n\t * @param opts - The options for the rotation.\n\t */\n\trotateShapesBy(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\tdelta: number,\n\t\topts?: { center?: VecLike }\n\t): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\n\t\tconst snapshot = getRotationSnapshot({ editor: this, ids })\n\t\tif (!snapshot) return this\n\t\tapplyRotationToSnapshotShapes({\n\t\t\tdelta,\n\t\t\tsnapshot,\n\t\t\teditor: this,\n\t\t\tstage: 'one-off',\n\t\t\tcenterOverride: opts?.center,\n\t\t})\n\n\t\treturn this\n\t}\n\n\t// Gets a shape partial that includes life cycle changes: on translate start, on translate, on translate end\n\tprivate getChangesToTranslateShape(initialShape: TLShape, newShapeCoords: VecLike): TLShape {\n\t\tlet workingShape = initialShape\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tconst afterTranslateStart = util.onTranslateStart?.(workingShape)\n\t\tif (afterTranslateStart) {\n\t\t\tworkingShape = applyPartialToRecordWithProps(workingShape, afterTranslateStart)\n\t\t}\n\n\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\tid: initialShape.id,\n\t\t\ttype: initialShape.type,\n\t\t\tx: newShapeCoords.x,\n\t\t\ty: newShapeCoords.y,\n\t\t})\n\n\t\tconst afterTranslate = util.onTranslate?.(initialShape, workingShape)\n\t\tif (afterTranslate) {\n\t\t\tworkingShape = applyPartialToRecordWithProps(workingShape, afterTranslate)\n\t\t}\n\n\t\tconst afterTranslateEnd = util.onTranslateEnd?.(initialShape, workingShape)\n\t\tif (afterTranslateEnd) {\n\t\t\tworkingShape = applyPartialToRecordWithProps(workingShape, afterTranslateEnd)\n\t\t}\n\n\t\treturn workingShape\n\t}\n\n\t/**\n\t * Move shapes by a delta.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.nudgeShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t * @param offset - The offset to apply to the shapes.\n\t */\n\tnudgeShapes(shapes: TLShapeId[] | TLShape[], offset: VecLike): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length <= 0) return this\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)!\n\t\t\tconst localDelta = Vec.From(offset)\n\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\tif (parentTransform) localDelta.rot(-parentTransform.rotation())\n\n\t\t\tchanges.push(this.getChangesToTranslateShape(shape, localDelta.add(shape)))\n\t\t}\n\n\t\tthis.updateShapes(changes)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Duplicate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.duplicateShapes(['box1', 'box2'], { x: 8, y: 8 })\n\t * editor.duplicateShapes(editor.getSelectedShapes(), { x: 8, y: 8 })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to duplicate.\n\t * @param offset - The offset (in pixels) to apply to the duplicated shapes.\n\t *\n\t * @public\n\t */\n\tduplicateShapes(shapes: TLShapeId[] | TLShape[], offset?: VecLike): this {\n\t\tthis.run(() => {\n\t\t\tconst _ids =\n\t\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t\tconst ids = this._shouldIgnoreShapeLock ? _ids : this._getUnlockedShapeIds(_ids)\n\t\t\tif (ids.length <= 0) return this\n\n\t\t\tconst initialIds = new Set(ids)\n\t\t\tconst shapeIdSet = this.getShapeAndDescendantIds(ids)\n\n\t\t\tconst orderedShapeIds = [...shapeIdSet].reverse()\n\t\t\tconst shapeIds = new Map<TLShapeId, TLShapeId>()\n\t\t\tfor (const shapeId of shapeIdSet) {\n\t\t\t\tshapeIds.set(shapeId, createShapeId())\n\t\t\t}\n\n\t\t\tconst { shapesToCreateWithOriginals, bindingsToCreate } = withIsolatedShapes(\n\t\t\t\tthis,\n\t\t\t\tshapeIdSet,\n\t\t\t\t(bindingIdsToMaintain) => {\n\t\t\t\t\tconst bindingsToCreate: TLBinding[] = []\n\t\t\t\t\tfor (const originalId of bindingIdsToMaintain) {\n\t\t\t\t\t\tconst originalBinding = this.getBinding(originalId)\n\t\t\t\t\t\tif (!originalBinding) continue\n\n\t\t\t\t\t\tconst duplicatedId = createBindingId()\n\t\t\t\t\t\tbindingsToCreate.push({\n\t\t\t\t\t\t\t...originalBinding,\n\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\tfromId: assertExists(shapeIds.get(originalBinding.fromId)),\n\t\t\t\t\t\t\ttoId: assertExists(shapeIds.get(originalBinding.toId)),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapesToCreateWithOriginals: { shape: TLShape; originalShape: TLShape }[] = []\n\t\t\t\t\tfor (const originalId of orderedShapeIds) {\n\t\t\t\t\t\tconst duplicatedId = assertExists(shapeIds.get(originalId))\n\t\t\t\t\t\tconst originalShape = this.getShape(originalId)\n\t\t\t\t\t\tif (!originalShape) continue\n\n\t\t\t\t\t\tlet ox = 0\n\t\t\t\t\t\tlet oy = 0\n\n\t\t\t\t\t\tif (offset && initialIds.has(originalId)) {\n\t\t\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(originalShape)\n\t\t\t\t\t\t\tconst vec = new Vec(offset.x, offset.y).rot(-parentTransform!.rotation())\n\t\t\t\t\t\t\tox = vec.x\n\t\t\t\t\t\t\toy = vec.y\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tshapesToCreateWithOriginals.push({\n\t\t\t\t\t\t\tshape: {\n\t\t\t\t\t\t\t\t...originalShape,\n\t\t\t\t\t\t\t\tid: duplicatedId,\n\t\t\t\t\t\t\t\tx: originalShape.x + ox,\n\t\t\t\t\t\t\t\ty: originalShape.y + oy,\n\t\t\t\t\t\t\t\t// Use a dummy index for now, it will get updated outside of the `withIsolatedShapes`\n\t\t\t\t\t\t\t\tindex: 'a1' as IndexKey,\n\t\t\t\t\t\t\t\tparentId:\n\t\t\t\t\t\t\t\t\tshapeIds.get(originalShape.parentId as TLShapeId) ?? originalShape.parentId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toriginalShape,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\treturn { shapesToCreateWithOriginals, bindingsToCreate }\n\t\t\t\t}\n\t\t\t)\n\n\t\t\t// We will update the indexes after the `withIsolatedShapes`, since we cannot rely on the indexes\n\t\t\t// to be correct inside of it.\n\t\t\tshapesToCreateWithOriginals.forEach(({ shape, originalShape }) => {\n\t\t\t\tconst parentId = originalShape.parentId\n\t\t\t\tconst siblings = this.getSortedChildIdsForParent(parentId)\n\t\t\t\tconst currentIndex = siblings.indexOf(originalShape.id)\n\t\t\t\tconst siblingAboveId = siblings[currentIndex + 1]\n\t\t\t\tconst siblingAbove = siblingAboveId ? this.getShape(siblingAboveId) : undefined\n\n\t\t\t\tconst index = getIndexBetween(originalShape.index, siblingAbove?.index)\n\n\t\t\t\tshape.index = index\n\t\t\t})\n\t\t\tconst shapesToCreate = shapesToCreateWithOriginals.map(({ shape }) => shape)\n\n\t\t\tif (!this.canCreateShapes(shapesToCreate)) {\n\t\t\t\talertMaxShapes(this)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.createShapes(shapesToCreate)\n\t\t\tthis.createBindings(bindingsToCreate)\n\n\t\t\tthis.setSelectedShapes(\n\t\t\t\tcompact(\n\t\t\t\t\tids.map((oldId) => {\n\t\t\t\t\t\tconst newId = shapeIds.get(oldId)\n\t\t\t\t\t\tif (!newId) return null\n\t\t\t\t\t\tif (!this.getShape(newId)) return null\n\t\t\t\t\t\treturn newId\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t)\n\n\t\t\tif (offset !== undefined) {\n\t\t\t\t// If we've offset the duplicated shapes, check to see whether their new bounds is entirely\n\t\t\t\t// contained in the current viewport. If not, then animate the camera to be centered on the\n\t\t\t\t// new shapes.\n\t\t\t\tconst selectionPageBounds = this.getSelectionPageBounds()\n\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\tif (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {\n\t\t\t\t\tthis.centerOnPoint(selectionPageBounds.center, {\n\t\t\t\t\t\tanimation: { duration: this.options.animationMediumMs },\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Move shapes to page.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.moveShapesToPage(['box1', 'box2'], 'page1')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) of the shapes to move.\n\t * @param pageId - The id of the page where the shapes will be moved.\n\t *\n\t * @public\n\t */\n\tmoveShapesToPage(shapes: TLShapeId[] | TLShape[], pageId: TLPageId): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return this\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\n\t\tif (pageId === currentPageId) return this\n\t\tif (!this.store.has(pageId)) return this\n\n\t\t// Basically copy the shapes\n\t\tconst content = this.getContentFromCurrentPage(ids)\n\n\t\t// Just to be sure\n\t\tif (!content) return this\n\n\t\t// If there is no space on pageId, or if the selected shapes\n\t\t// would take the new page above the limit, don't move the shapes\n\t\tif (this.getPageShapeIds(pageId).size + content.shapes.length > this.options.maxShapesPerPage) {\n\t\t\talertMaxShapes(this, pageId)\n\t\t\treturn this\n\t\t}\n\n\t\tconst fromPageZ = this.getCamera().z\n\n\t\tthis.run(() => {\n\t\t\t// Delete the shapes on the current page\n\t\t\tthis.deleteShapes(ids)\n\n\t\t\t// Move to the next page\n\t\t\tthis.setCurrentPage(pageId)\n\n\t\t\t// Put the shape content onto the new page; parents and indices will\n\t\t\t// be taken care of by the putContent method; make sure to pop any focus\n\t\t\t// layers so that the content will be put onto the page.\n\t\t\tthis.setFocusedGroup(null)\n\t\t\tthis.selectNone()\n\t\t\tthis.putContentOntoCurrentPage(content, {\n\t\t\t\tselect: true,\n\t\t\t\tpreserveIds: true,\n\t\t\t\tpreservePosition: true,\n\t\t\t})\n\n\t\t\t// Force the new page's camera to be at the same zoom level as the\n\t\t\t// \"from\" page's camera, then center the \"to\" page's camera on the\n\t\t\t// pasted shapes\n\t\t\tthis.setCamera({ ...this.getCamera(), z: fromPageZ })\n\t\t\tthis.centerOnPoint(this.getSelectionRotatedPageBounds()!.center)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Toggle the lock state of one or more shapes. If there is a mix of locked and unlocked shapes, all shapes will be locked.\n\t *\n\t * @param shapes - The shapes (or shape ids) to toggle.\n\t *\n\t * @public\n\t */\n\ttoggleLock(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly() || ids.length === 0) return this\n\n\t\tlet allLocked = true,\n\t\t\tallUnlocked = true\n\t\tconst shapesToToggle: TLShape[] = []\n\t\tfor (const id of ids) {\n\t\t\tconst shape = this.getShape(id)\n\t\t\tif (shape) {\n\t\t\t\tshapesToToggle.push(shape)\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\tallUnlocked = false\n\t\t\t\t} else {\n\t\t\t\t\tallLocked = false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.run(() => {\n\t\t\tif (allUnlocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t\tthis.setSelectedShapes([])\n\t\t\t} else if (allLocked) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: false }))\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\tshapesToToggle.map((shape) => ({ id: shape.id, type: shape.type, isLocked: true }))\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes to the back of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendToBack(['id1', 'id2'])\n\t * editor.sendToBack(box1, box2)\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tsendToBack(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toBack', ids as TLShapeId[], {\n\t\t\tconsiderAllShapes: true,\n\t\t})\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Send shapes backward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendBackward(['id1', 'id2'])\n\t * editor.sendBackward([box1, box2])\n\t * ```\n\t *\n\t * By default, the operation will only consider overlapping shapes.\n\t * To consider all shapes, pass `{ considerAllShapes: true }` in the options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.sendBackward(['id1', 'id2'], { considerAllShapes: true })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t * @param opts - The options for the backward operation.\n\t *\n\t * @public\n\t */\n\tsendBackward(shapes: TLShapeId[] | TLShape[], opts: { considerAllShapes?: boolean } = {}): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'backward', ids as TLShapeId[], opts)\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes forward in the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringForward(['id1', 'id2'])\n\t * editor.bringForward(box1, box2)\n\t * ```\n\t *\n\t * By default, the operation will only consider overlapping shapes.\n\t * To consider all shapes, pass `{ considerAllShapes: true }` in the options.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringForward(['id1', 'id2'], { considerAllShapes: true })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t * @param opts - The options for the forward operation.\n\t *\n\t * @public\n\t */\n\tbringForward(shapes: TLShapeId[] | TLShape[], opts: { considerAllShapes?: boolean } = {}): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'forward', ids as TLShapeId[], opts)\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Bring shapes to the front of the page's object list.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.bringToFront(['id1', 'id2'])\n\t * editor.bringToFront([box1, box2])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to move.\n\t *\n\t * @public\n\t */\n\tbringToFront(shapes: TLShapeId[] | TLShape[]): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tconst changes = getReorderingShapesChanges(this, 'toFront', ids as TLShapeId[])\n\t\tif (changes) this.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * @internal\n\t */\n\tprivate collectShapesViaArrowBindings(info: {\n\t\tinitialShapes: TLShape[]\n\t\tresultShapes: TLShape[]\n\t\tresultBounds: Box[]\n\t\tbindings: TLBinding[]\n\t\tvisited: Set<TLShapeId>\n\t}) {\n\t\tconst { initialShapes, resultShapes, resultBounds, bindings, visited } = info\n\t\tfor (const binding of bindings) {\n\t\t\tfor (const id of [binding.fromId, binding.toId]) {\n\t\t\t\tif (!visited.has(id)) {\n\t\t\t\t\tconst aligningShape = initialShapes.find((s) => s.id === id)\n\t\t\t\t\tif (aligningShape && !visited.has(aligningShape.id)) {\n\t\t\t\t\t\tvisited.add(aligningShape.id)\n\t\t\t\t\t\tconst shapePageBounds = this.getShapePageBounds(aligningShape)\n\t\t\t\t\t\tif (!shapePageBounds) continue\n\t\t\t\t\t\tresultShapes.push(aligningShape)\n\t\t\t\t\t\tresultBounds.push(shapePageBounds)\n\t\t\t\t\t\tthis.collectShapesViaArrowBindings({\n\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\tbindings: this.getBindingsInvolvingShape(aligningShape, 'arrow'),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Flip shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.flipShapes([box1, box2], 'horizontal', 32)\n\t * editor.flipShapes(editor.getSelectedShapeIds(), 'horizontal', 32)\n\t * ```\n\t *\n\t * @param shapes - The ids of the shapes to flip.\n\t * @param operation - Whether to flip horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tflipShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t// Collect a greedy list of shapes to flip\n\t\tconst shapesToFlipFirstPass = compact(ids.map((id) => this.getShape(id)))\n\n\t\tfor (const shape of shapesToFlipFirstPass) {\n\t\t\tif (this.isShapeOfType<TLGroupShape>(shape, 'group')) {\n\t\t\t\tconst childrenOfGroups = compact(\n\t\t\t\t\tthis.getSortedChildIdsForParent(shape.id).map((id) => this.getShape(id))\n\t\t\t\t)\n\t\t\t\tshapesToFlipFirstPass.push(...childrenOfGroups)\n\t\t\t}\n\t\t}\n\n\t\t// exclude shapes that can't be flipped\n\t\tconst shapesToFlip: {\n\t\t\tshape: TLShape\n\t\t\tlocalBounds: Box\n\t\t\tpageTransform: Mat\n\t\t\tisAspectRatioLocked: boolean\n\t\t}[] = []\n\n\t\tconst allBounds: Box[] = []\n\n\t\tfor (const shape of shapesToFlipFirstPass) {\n\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\tif (\n\t\t\t\t!util.canBeLaidOut(shape, {\n\t\t\t\t\ttype: 'flip',\n\t\t\t\t\tshapes: shapesToFlipFirstPass,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst pageBounds = this.getShapePageBounds(shape)\n\t\t\tconst localBounds = this.getShapeGeometry(shape).bounds\n\t\t\tconst pageTransform = this.getShapePageTransform(shape.id)\n\t\t\tif (!(pageBounds && localBounds && pageTransform)) continue\n\t\t\tshapesToFlip.push({\n\t\t\t\tshape,\n\t\t\t\tlocalBounds,\n\t\t\t\tpageTransform,\n\t\t\t\tisAspectRatioLocked: util.isAspectRatioLocked(shape),\n\t\t\t})\n\t\t\tallBounds.push(pageBounds)\n\t\t}\n\n\t\tif (!shapesToFlip.length) return this\n\n\t\tconst scaleOriginPage = Box.Common(allBounds).center\n\n\t\tthis.run(() => {\n\t\t\tfor (const { shape, localBounds, pageTransform, isAspectRatioLocked } of shapesToFlip) {\n\t\t\t\tthis.resizeShape(\n\t\t\t\t\tshape.id,\n\t\t\t\t\t{ x: operation === 'horizontal' ? -1 : 1, y: operation === 'vertical' ? -1 : 1 },\n\t\t\t\t\t{\n\t\t\t\t\t\tinitialBounds: localBounds,\n\t\t\t\t\t\tinitialPageTransform: pageTransform,\n\t\t\t\t\t\tinitialShape: shape,\n\t\t\t\t\t\tisAspectRatioLocked,\n\t\t\t\t\t\tmode: 'scale_shape',\n\t\t\t\t\t\tscaleOrigin: scaleOriginPage,\n\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Stack shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stackShapes([box1, box2], 'horizontal')\n\t * editor.stackShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stack.\n\t * @param operation - Whether to stack horizontally or vertically.\n\t * @param gap - The gap to leave between shapes. By default, uses the editor's `adjacentShapeMargin` option.\n\t *\n\t * @public\n\t */\n\tstackShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'horizontal' | 'vertical',\n\t\tgap?: number\n\t): this {\n\t\tconst _gap = gap ?? this.options.adjacentShapeMargin\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\t\tif (this.getIsReadonly()) return this\n\n\t\t// todo: this has a lot of extra code to handle stacking with custom gaps or auto gaps or other things like that. I don't think anyone has ever used this stuff.\n\n\t\t// always fresh shapes\n\t\tconst shapesToStackFirstPass = compact(ids.map((id) => this.getShape(id)))\n\n\t\tconst shapeClustersToStack: {\n\t\t\tshapes: TLShape[]\n\t\t\tpageBounds: Box\n\t\t}[] = []\n\t\tconst allBounds: Box[] = []\n\t\tconst visited = new Set<TLShapeId>()\n\n\t\tfor (const shape of shapesToStackFirstPass) {\n\t\t\tif (visited.has(shape.id)) continue\n\t\t\tvisited.add(shape.id)\n\n\t\t\tconst shapePageBounds = this.getShapePageBounds(shape)\n\t\t\tif (!shapePageBounds) continue\n\n\t\t\tif (\n\t\t\t\t!this.getShapeUtil(shape).canBeLaidOut?.(shape, {\n\t\t\t\t\ttype: 'stack',\n\t\t\t\t\tshapes: shapesToStackFirstPass,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst shapesMovingTogether = [shape]\n\t\t\tconst boundsOfShapesMovingTogether: Box[] = [shapePageBounds]\n\n\t\t\tthis.collectShapesViaArrowBindings({\n\t\t\t\tbindings: this.getBindingsToShape(shape.id, 'arrow'),\n\t\t\t\tinitialShapes: shapesToStackFirstPass,\n\t\t\t\tresultShapes: shapesMovingTogether,\n\t\t\t\tresultBounds: boundsOfShapesMovingTogether,\n\t\t\t\tvisited,\n\t\t\t})\n\n\t\t\tconst commonPageBounds = Box.Common(boundsOfShapesMovingTogether)\n\t\t\tif (!commonPageBounds) continue\n\n\t\t\tshapeClustersToStack.push({\n\t\t\t\tshapes: shapesMovingTogether,\n\t\t\t\tpageBounds: commonPageBounds,\n\t\t\t})\n\n\t\t\tallBounds.push(commonPageBounds)\n\t\t}\n\n\t\tconst len = shapeClustersToStack.length\n\t\tif ((_gap === 0 && len < 3) || len < 2) return this\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tdim = 'height'\n\t\t}\n\n\t\tlet shapeGap: number = 0\n\n\t\tif (_gap === 0) {\n\t\t\t// note: this is not used in the current tldraw.com; there we use a specified stack\n\n\t\t\tconst gaps: Record<number, number> = {}\n\n\t\t\tshapeClustersToStack.sort((a, b) => a.pageBounds[min] - b.pageBounds[min])\n\n\t\t\t// Collect all of the gaps between shapes. We want to find\n\t\t\t// patterns (equal gaps between shapes) and use the most common\n\t\t\t// one as the gap for all of the shapes.\n\t\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\t\tconst currCluster = shapeClustersToStack[i]\n\t\t\t\tconst nextCluster = shapeClustersToStack[i + 1]\n\t\t\t\tconst gap = nextCluster.pageBounds[min] - currCluster.pageBounds[max]\n\t\t\t\tif (!gaps[gap]) {\n\t\t\t\t\tgaps[gap] = 0\n\t\t\t\t}\n\t\t\t\tgaps[gap]++\n\t\t\t}\n\n\t\t\t// Which gap is the most common?\n\t\t\tlet maxCount = 1\n\t\t\tfor (const [gap, count] of Object.entries(gaps)) {\n\t\t\t\tif (count > maxCount) {\n\t\t\t\t\tmaxCount = count\n\t\t\t\t\tshapeGap = parseFloat(gap)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If there is no most-common gap, use the average gap.\n\t\t\tif (maxCount === 1) {\n\t\t\t\tlet totalCount = 0\n\t\t\t\tfor (const [gap, count] of Object.entries(gaps)) {\n\t\t\t\t\tshapeGap += parseFloat(gap) * count\n\t\t\t\t\ttotalCount += count\n\t\t\t\t}\n\t\t\t\tshapeGap /= totalCount\n\t\t\t}\n\t\t} else {\n\t\t\t// If a gap was provided, then use that instead.\n\t\t\tshapeGap = _gap\n\t\t}\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tlet v = shapeClustersToStack[0].pageBounds[max]\n\n\t\tfor (let i = 1; i < shapeClustersToStack.length; i++) {\n\t\t\tconst { shapes, pageBounds } = shapeClustersToStack[i]\n\t\t\tconst delta = new Vec()\n\t\t\tdelta[val] = v + shapeGap - pageBounds[val]\n\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tconst shapeDelta = delta.clone()\n\n\t\t\t\t// If the shape has another shape as its parent, and if the parent has a rotation, we need to rotate the counter-rotate delta\n\t\t\t\t// todo: ensure that the parent isn't being aligned together with its children\n\t\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\t\tif (parent) {\n\t\t\t\t\tconst parentTransform = this.getShapePageTransform(parent)\n\t\t\t\t\tif (parentTransform) shapeDelta.rot(-parentTransform.rotation())\n\t\t\t\t}\n\n\t\t\t\tshapeDelta.add(shape) // add the shape's x and y to the delta\n\t\t\t\tchanges.push(this.getChangesToTranslateShape(shape, shapeDelta))\n\t\t\t}\n\n\t\t\tv += pageBounds[dim] + shapeGap\n\t\t}\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Pack shapes into a grid centered on their current position. Based on potpack (https://github.com/mapbox/potpack).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.packShapes([box1, box2])\n\t * editor.packShapes(editor.getSelectedShapeIds(), 32)\n\t * ```\n\t *\n\t *\n\t * @param shapes - The shapes (or shape ids) to pack.\n\t * @param gap - The padding to apply to the packed shapes. Defaults to the editor's `adjacentShapeMargin` option.\n\t */\n\tpackShapes(shapes: TLShapeId[] | TLShape[], _gap?: number): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst gap = _gap ?? this.options.adjacentShapeMargin\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t// Always fresh shapes\n\t\tconst shapesToPackFirstPass = compact(ids.map((id) => this.getShape(id)))\n\n\t\tconst shapeClustersToPack: {\n\t\t\tshapes: TLShape[]\n\t\t\tpageBounds: Box\n\t\t\tnextPageBounds: Box\n\t\t}[] = []\n\n\t\tconst allBounds: Box[] = []\n\t\tconst visited = new Set<TLShapeId>()\n\n\t\tfor (const shape of shapesToPackFirstPass) {\n\t\t\tif (visited.has(shape.id)) continue\n\t\t\tvisited.add(shape.id)\n\n\t\t\tconst shapePageBounds = this.getShapePageBounds(shape)\n\t\t\tif (!shapePageBounds) continue\n\n\t\t\tif (\n\t\t\t\t!this.getShapeUtil(shape).canBeLaidOut?.(shape, {\n\t\t\t\t\ttype: 'pack',\n\t\t\t\t\tshapes: shapesToPackFirstPass,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst shapesMovingTogether = [shape]\n\t\t\tconst boundsOfShapesMovingTogether: Box[] = [shapePageBounds]\n\n\t\t\tthis.collectShapesViaArrowBindings({\n\t\t\t\tbindings: this.getBindingsToShape(shape.id, 'arrow'),\n\t\t\t\tinitialShapes: shapesToPackFirstPass,\n\t\t\t\tresultShapes: shapesMovingTogether,\n\t\t\t\tresultBounds: boundsOfShapesMovingTogether,\n\t\t\t\tvisited,\n\t\t\t})\n\n\t\t\tconst commonPageBounds = Box.Common(boundsOfShapesMovingTogether)\n\t\t\tif (!commonPageBounds) continue\n\n\t\t\tshapeClustersToPack.push({\n\t\t\t\tshapes: shapesMovingTogether,\n\t\t\t\tpageBounds: commonPageBounds,\n\t\t\t\tnextPageBounds: commonPageBounds.clone(),\n\t\t\t})\n\n\t\t\tallBounds.push(commonPageBounds)\n\t\t}\n\n\t\tif (shapeClustersToPack.length < 2) return this\n\n\t\tlet area = 0\n\t\tfor (const { pageBounds } of shapeClustersToPack) {\n\t\t\tarea += pageBounds.width * pageBounds.height\n\t\t}\n\n\t\tconst commonBounds = Box.Common(allBounds)\n\n\t\tconst maxWidth = commonBounds.width\n\n\t\t// sort the shape clusters by width and then height, descending\n\t\tshapeClustersToPack\n\t\t\t.sort((a, b) => a.pageBounds.width - b.pageBounds.width)\n\t\t\t.sort((a, b) => a.pageBounds.height - b.pageBounds.height)\n\n\t\t// Start with is (sort of) the square of the area\n\t\tconst startWidth = Math.max(Math.ceil(Math.sqrt(area / 0.95)), maxWidth)\n\n\t\t// first shape fills the width and is infinitely tall\n\t\tconst spaces: Box[] = [new Box(commonBounds.x, commonBounds.y, startWidth, Infinity)]\n\n\t\tlet width = 0\n\t\tlet height = 0\n\t\tlet space: Box\n\t\tlet last: Box\n\n\t\tfor (const { nextPageBounds } of shapeClustersToPack) {\n\t\t\t// starting at the back (smaller shapes)\n\t\t\tfor (let i = spaces.length - 1; i >= 0; i--) {\n\t\t\t\tspace = spaces[i]\n\n\t\t\t\t// find a space that is big enough to contain the shape\n\t\t\t\tif (nextPageBounds.width > space.width || nextPageBounds.height > space.height) continue\n\n\t\t\t\t// add the shape to its top-left corner\n\t\t\t\tnextPageBounds.x = space.x\n\t\t\t\tnextPageBounds.y = space.y\n\n\t\t\t\theight = Math.max(height, nextPageBounds.maxY)\n\t\t\t\twidth = Math.max(width, nextPageBounds.maxX)\n\n\t\t\t\tif (nextPageBounds.width === space.width && nextPageBounds.height === space.height) {\n\t\t\t\t\t// remove the space on a perfect fit\n\t\t\t\t\tlast = spaces.pop()!\n\t\t\t\t\tif (i < spaces.length) spaces[i] = last\n\t\t\t\t} else if (nextPageBounds.height === space.height) {\n\t\t\t\t\t// fit the shape into the space (width)\n\t\t\t\t\tspace.x += nextPageBounds.width + gap\n\t\t\t\t\tspace.width -= nextPageBounds.width + gap\n\t\t\t\t} else if (nextPageBounds.width === space.width) {\n\t\t\t\t\t// fit the shape into the space (height)\n\t\t\t\t\tspace.y += nextPageBounds.height + gap\n\t\t\t\t\tspace.height -= nextPageBounds.height + gap\n\t\t\t\t} else {\n\t\t\t\t\t// split the space into two spaces\n\t\t\t\t\tspaces.push(\n\t\t\t\t\t\tnew Box(\n\t\t\t\t\t\t\tspace.x + (nextPageBounds.width + gap),\n\t\t\t\t\t\t\tspace.y,\n\t\t\t\t\t\t\tspace.width - (nextPageBounds.width + gap),\n\t\t\t\t\t\t\tnextPageBounds.height\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t\tspace.y += nextPageBounds.height + gap\n\t\t\t\t\tspace.height -= nextPageBounds.height + gap\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tconst commonAfter = Box.Common(shapeClustersToPack.map((s) => s.nextPageBounds))\n\t\tconst centerDelta = Vec.Sub(commonBounds.center, commonAfter.center)\n\n\t\tconst changes: TLShapePartial<any>[] = []\n\n\t\tfor (const { shapes, pageBounds, nextPageBounds } of shapeClustersToPack) {\n\t\t\tconst delta = Vec.Sub(nextPageBounds.point, pageBounds.point).add(centerDelta)\n\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tconst shapeDelta = delta.clone()\n\n\t\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\t\tif (parent) {\n\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\tif (parentTransform) shapeDelta.rot(-parentTransform.rotation())\n\t\t\t\t}\n\n\t\t\t\tshapeDelta.add(shape)\n\t\t\t\tchanges.push(this.getChangesToTranslateShape(shape, shapeDelta))\n\t\t\t}\n\t\t}\n\n\t\tif (changes.length) {\n\t\t\tthis.updateShapes(changes)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Align shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.alignShapes([box1, box2], 'left')\n\t * editor.alignShapes(editor.getSelectedShapeIds(), 'left')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to align.\n\t * @param operation - The align operation to apply.\n\t *\n\t * @public\n\t */\n\talignShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\toperation: 'left' | 'center-horizontal' | 'right' | 'top' | 'center-vertical' | 'bottom'\n\t): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t// Always get fresh shapes\n\t\tconst shapesToAlignFirstPass = compact(ids.map((id) => this.getShape(id)))\n\n\t\tconst shapeClustersToAlign: {\n\t\t\tshapes: TLShape[]\n\t\t\tpageBounds: Box\n\t\t}[] = []\n\t\tconst allBounds: Box[] = []\n\t\tconst visited = new Set<TLShapeId>()\n\n\t\tfor (const shape of shapesToAlignFirstPass) {\n\t\t\tif (visited.has(shape.id)) continue\n\t\t\tvisited.add(shape.id)\n\n\t\t\tconst shapePageBounds = this.getShapePageBounds(shape)\n\t\t\tif (!shapePageBounds) continue\n\n\t\t\tif (\n\t\t\t\t!this.getShapeUtil(shape).canBeLaidOut?.(shape, {\n\t\t\t\t\ttype: 'align',\n\t\t\t\t\tshapes: shapesToAlignFirstPass,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// In this implementation, we want to create psuedo-groups out of shapes that\n\t\t\t// are moving together. At the moment shapes only move together if they're connected\n\t\t\t// by arrows. So let's say A -> B -> C -> D and A, B, and C are selected. If we're\n\t\t\t// aligning A, B, and C, then we want these to move together as one unit.\n\n\t\t\tconst shapesMovingTogether = [shape]\n\t\t\tconst boundsOfShapesMovingTogether: Box[] = [shapePageBounds]\n\n\t\t\tthis.collectShapesViaArrowBindings({\n\t\t\t\tbindings: this.getBindingsToShape(shape.id, 'arrow'),\n\t\t\t\tinitialShapes: shapesToAlignFirstPass,\n\t\t\t\tresultShapes: shapesMovingTogether,\n\t\t\t\tresultBounds: boundsOfShapesMovingTogether,\n\t\t\t\tvisited,\n\t\t\t})\n\n\t\t\tconst commonPageBounds = Box.Common(boundsOfShapesMovingTogether)\n\t\t\tif (!commonPageBounds) continue\n\n\t\t\tshapeClustersToAlign.push({\n\t\t\t\tshapes: shapesMovingTogether,\n\t\t\t\tpageBounds: commonPageBounds,\n\t\t\t})\n\n\t\t\tallBounds.push(commonPageBounds)\n\t\t}\n\n\t\tif (shapeClustersToAlign.length < 2) return this\n\n\t\tconst commonBounds = Box.Common(allBounds)\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapeClustersToAlign.forEach(({ shapes, pageBounds }) => {\n\t\t\tconst delta = new Vec()\n\n\t\t\tswitch (operation) {\n\t\t\t\tcase 'top': {\n\t\t\t\t\tdelta.y = commonBounds.minY - pageBounds.minY\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-vertical': {\n\t\t\t\t\tdelta.y = commonBounds.midY - pageBounds.minY - pageBounds.height / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'bottom': {\n\t\t\t\t\tdelta.y = commonBounds.maxY - pageBounds.minY - pageBounds.height\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'left': {\n\t\t\t\t\tdelta.x = commonBounds.minX - pageBounds.minX\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'center-horizontal': {\n\t\t\t\t\tdelta.x = commonBounds.midX - pageBounds.minX - pageBounds.width / 2\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'right': {\n\t\t\t\t\tdelta.x = commonBounds.maxX - pageBounds.minX - pageBounds.width\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tconst shapeDelta = delta.clone()\n\n\t\t\t\t// If the shape has another shape as its parent, and if the parent has a rotation, we need to rotate the counter-rotate delta\n\t\t\t\t// todo: ensure that the parent isn't being aligned together with its children\n\t\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\t\tif (parent) {\n\t\t\t\t\tconst parentTransform = this.getShapePageTransform(parent)\n\t\t\t\t\tif (parentTransform) shapeDelta.rot(-parentTransform.rotation())\n\t\t\t\t}\n\n\t\t\t\tshapeDelta.add(shape) // add the shape's x and y to the delta\n\t\t\t\tchanges.push(this.getChangesToTranslateShape(shape, shapeDelta))\n\t\t\t}\n\t\t})\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Distribute shape positions.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.distributeShapes([box1, box2], 'horizontal')\n\t * editor.distributeShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to distribute.\n\t * @param operation - Whether to distribute shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tdistributeShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\t// always fresh shapes\n\t\tconst shapesToDistributeFirstPass = compact(ids.map((id) => this.getShape(id)))\n\n\t\tconst shapeClustersToDistribute: {\n\t\t\tshapes: TLShape[]\n\t\t\tpageBounds: Box\n\t\t}[] = []\n\n\t\tconst allBounds: Box[] = []\n\t\tconst visited = new Set<TLShapeId>()\n\n\t\tfor (const shape of shapesToDistributeFirstPass) {\n\t\t\tif (visited.has(shape.id)) continue\n\t\t\tvisited.add(shape.id)\n\n\t\t\tconst shapePageBounds = this.getShapePageBounds(shape)\n\t\t\tif (!shapePageBounds) continue\n\n\t\t\tif (\n\t\t\t\t!this.getShapeUtil(shape).canBeLaidOut?.(shape, {\n\t\t\t\t\ttype: 'distribute',\n\t\t\t\t\tshapes: shapesToDistributeFirstPass,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst shapesMovingTogether = [shape]\n\t\t\tconst boundsOfShapesMovingTogether: Box[] = [shapePageBounds]\n\n\t\t\tthis.collectShapesViaArrowBindings({\n\t\t\t\tbindings: this.getBindingsToShape(shape.id, 'arrow'),\n\t\t\t\tinitialShapes: shapesToDistributeFirstPass,\n\t\t\t\tresultShapes: shapesMovingTogether,\n\t\t\t\tresultBounds: boundsOfShapesMovingTogether,\n\t\t\t\tvisited,\n\t\t\t})\n\n\t\t\tconst commonPageBounds = Box.Common(boundsOfShapesMovingTogether)\n\t\t\tif (!commonPageBounds) continue\n\n\t\t\tshapeClustersToDistribute.push({\n\t\t\t\tshapes: shapesMovingTogether,\n\t\t\t\tpageBounds: commonPageBounds,\n\t\t\t})\n\n\t\t\tallBounds.push(commonPageBounds)\n\t\t}\n\n\t\tif (shapeClustersToDistribute.length < 3) return this\n\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet max: 'maxX' | 'maxY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tmax = 'maxX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tmax = 'maxY'\n\t\t\tdim = 'height'\n\t\t}\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tconst first = shapeClustersToDistribute.sort((a, b) => a.pageBounds[min] - b.pageBounds[min])[0]\n\t\tconst last = shapeClustersToDistribute.sort((a, b) => b.pageBounds[max] - a.pageBounds[max])[0]\n\n\t\t// If the first shape group is also the last shape group, distribute without it\n\t\tif (first === last) {\n\t\t\tconst excludedShapeIds = new Set(first.shapes.map((s) => s.id))\n\t\t\treturn this.distributeShapes(\n\t\t\t\tids.filter((id) => !excludedShapeIds.has(id)),\n\t\t\t\toperation\n\t\t\t)\n\t\t}\n\n\t\tconst shapeClustersToMove = shapeClustersToDistribute\n\t\t\t.filter((shape) => shape !== first && shape !== last)\n\t\t\t.sort((a, b) => {\n\t\t\t\tif (a.pageBounds[min] === b.pageBounds[min]) {\n\t\t\t\t\treturn a.shapes[0].id < b.shapes[0].id ? -1 : 1\n\t\t\t\t}\n\t\t\t\treturn a.pageBounds[min] - b.pageBounds[min]\n\t\t\t})\n\n\t\t// The gap is the amount of space \"left over\" between the first and last shape. This can be a negative number if the shapes are overlapping.\n\t\tconst maxFirst = first.pageBounds[max]\n\t\tconst range = last.pageBounds[min] - maxFirst\n\t\tconst summedShapeDimensions = shapeClustersToMove.reduce((acc, s) => acc + s.pageBounds[dim], 0)\n\t\tconst gap = (range - summedShapeDimensions) / (shapeClustersToMove.length + 1)\n\n\t\tfor (let v = maxFirst + gap, i = 0; i < shapeClustersToMove.length; i++) {\n\t\t\tconst { shapes, pageBounds } = shapeClustersToMove[i]\n\t\t\tconst delta = new Vec()\n\t\t\tdelta[val] = v - pageBounds[val]\n\n\t\t\t// If for some reason the new position would be more than the maximum, we need to adjust the delta\n\t\t\t// This will likely throw off some of the other placements but hey, it's better than changing the common bounds\n\t\t\tif (v + pageBounds[dim] > last.pageBounds[max] - 1) {\n\t\t\t\tdelta[val] = last.pageBounds[max] - pageBounds[max] - 1\n\t\t\t}\n\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tconst shapeDelta = delta.clone()\n\n\t\t\t\t// If the shape has another shape as its parent, and if the parent has a rotation, we need to rotate the counter-rotate delta\n\t\t\t\t// todo: ensure that the parent isn't being aligned together with its children\n\t\t\t\tconst parent = this.getShapeParent(shape)\n\t\t\t\tif (parent) {\n\t\t\t\t\tconst parentTransform = this.getShapePageTransform(parent)\n\t\t\t\t\tif (parentTransform) shapeDelta.rot(-parentTransform.rotation())\n\t\t\t\t}\n\n\t\t\t\tshapeDelta.add(shape) // add the shape's x and y to the delta\n\t\t\t\tchanges.push(this.getChangesToTranslateShape(shape, shapeDelta))\n\t\t\t}\n\n\t\t\tv += pageBounds[dim] + gap\n\t\t}\n\n\t\tthis.updateShapes(changes)\n\t\treturn this\n\t}\n\n\t/**\n\t * Stretch shape sizes and positions to fill their common bounding box.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.stretchShapes([box1, box2], 'horizontal')\n\t * editor.stretchShapes(editor.getSelectedShapeIds(), 'horizontal')\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to stretch.\n\t * @param operation - Whether to stretch shapes horizontally or vertically.\n\t *\n\t * @public\n\t */\n\tstretchShapes(shapes: TLShapeId[] | TLShape[], operation: 'horizontal' | 'vertical'): this {\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (this.getIsReadonly()) return this\n\n\t\t// always fresh shapes, skip anything that isn't rotated 90 deg\n\t\tconst shapesToStretchFirstPass = compact(ids.map((id) => this.getShape(id))).filter(\n\t\t\t(s) => this.getShapePageTransform(s)?.rotation() % (PI / 2) === 0\n\t\t)\n\n\t\tconst shapeClustersToStretch: {\n\t\t\tshapes: TLShape[]\n\t\t\tpageBounds: Box\n\t\t}[] = []\n\n\t\tconst allBounds: Box[] = []\n\t\tconst visited = new Set<TLShapeId>()\n\n\t\tfor (const shape of shapesToStretchFirstPass) {\n\t\t\tif (visited.has(shape.id)) continue\n\t\t\tvisited.add(shape.id)\n\n\t\t\tconst shapePageBounds = this.getShapePageBounds(shape)\n\t\t\tif (!shapePageBounds) continue\n\n\t\t\tconst shapesMovingTogether = [shape]\n\t\t\tconst boundsOfShapesMovingTogether: Box[] = [shapePageBounds]\n\n\t\t\tif (\n\t\t\t\t!this.getShapeUtil(shape).canBeLaidOut?.(shape, {\n\t\t\t\t\ttype: 'stretch',\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tthis.collectShapesViaArrowBindings({\n\t\t\t\tbindings: this.getBindingsToShape(shape.id, 'arrow'),\n\t\t\t\tinitialShapes: shapesToStretchFirstPass,\n\t\t\t\tresultShapes: shapesMovingTogether,\n\t\t\t\tresultBounds: boundsOfShapesMovingTogether,\n\t\t\t\tvisited,\n\t\t\t})\n\n\t\t\tconst commonPageBounds = Box.Common(boundsOfShapesMovingTogether)\n\t\t\tif (!commonPageBounds) continue\n\n\t\t\tshapeClustersToStretch.push({\n\t\t\t\tshapes: shapesMovingTogether,\n\t\t\t\tpageBounds: commonPageBounds,\n\t\t\t})\n\n\t\t\tallBounds.push(commonPageBounds)\n\t\t}\n\n\t\tif (shapeClustersToStretch.length < 2) return this\n\n\t\tconst commonBounds = Box.Common(allBounds)\n\t\tlet val: 'x' | 'y'\n\t\tlet min: 'minX' | 'minY'\n\t\tlet dim: 'width' | 'height'\n\n\t\tif (operation === 'horizontal') {\n\t\t\tval = 'x'\n\t\t\tmin = 'minX'\n\t\t\tdim = 'width'\n\t\t} else {\n\t\t\tval = 'y'\n\t\t\tmin = 'minY'\n\t\t\tdim = 'height'\n\t\t}\n\n\t\tthis.run(() => {\n\t\t\tshapeClustersToStretch.forEach(({ shapes, pageBounds }) => {\n\t\t\t\tconst localOffset = new Vec()\n\t\t\t\tlocalOffset[val] = commonBounds[min] - pageBounds[min]\n\n\t\t\t\tconst scaleOrigin = pageBounds.center.clone()\n\t\t\t\tscaleOrigin[val] = commonBounds[min]\n\n\t\t\t\tconst scale = new Vec(1, 1)\n\t\t\t\tscale[val] = commonBounds[dim] / pageBounds[dim]\n\n\t\t\t\tfor (const shape of shapes) {\n\t\t\t\t\t// First translate\n\t\t\t\t\tconst shapeLocalOffset = localOffset.clone()\n\t\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\t\tif (parentTransform) localOffset.rot(-parentTransform.rotation())\n\t\t\t\t\tshapeLocalOffset.add(shape)\n\t\t\t\t\tconst changes = this.getChangesToTranslateShape(shape, shapeLocalOffset)\n\t\t\t\t\tthis.updateShape(changes)\n\n\t\t\t\t\t// Then resize\n\t\t\t\t\tthis.resizeShape(shape.id, scale, {\n\t\t\t\t\t\tinitialBounds: this.getShapeGeometry(shape).bounds,\n\t\t\t\t\t\tscaleOrigin,\n\t\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\t\tscaleAxisRotation: 0,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Resize a shape.\n\t *\n\t * @param shape - The shape (or the shape id of the shape) to resize.\n\t * @param scale - The scale factor to apply to the shape.\n\t * @param opts - Additional options.\n\t *\n\t * @public\n\t */\n\tresizeShape(shape: TLShapeId | TLShape, scale: VecLike, opts: TLResizeShapeOptions = {}): this {\n\t\tconst id = typeof shape === 'string' ? shape : shape.id\n\t\tif (this.getIsReadonly()) return this\n\n\t\tif (!Number.isFinite(scale.x)) scale = new Vec(1, scale.y)\n\t\tif (!Number.isFinite(scale.y)) scale = new Vec(scale.x, 1)\n\n\t\tconst initialShape = opts.initialShape ?? this.getShape(id)\n\t\tif (!initialShape) return this\n\n\t\tconst scaleOrigin = opts.scaleOrigin ?? this.getShapePageBounds(id)?.center\n\t\tif (!scaleOrigin) return this\n\n\t\tconst pageTransform = opts.initialPageTransform\n\t\t\t? Mat.Cast(opts.initialPageTransform)\n\t\t\t: this.getShapePageTransform(id)\n\t\tif (!pageTransform) return this\n\n\t\tconst pageRotation = pageTransform.rotation()\n\n\t\tif (pageRotation == null) return this\n\n\t\tconst scaleAxisRotation = opts.scaleAxisRotation ?? pageRotation\n\n\t\tconst initialBounds = opts.initialBounds ?? this.getShapeGeometry(id).bounds\n\n\t\tif (!initialBounds) return this\n\n\t\tconst isAspectRatioLocked =\n\t\t\topts.isAspectRatioLocked ?? this.getShapeUtil(initialShape).isAspectRatioLocked(initialShape)\n\n\t\tif (!areAnglesCompatible(pageRotation, scaleAxisRotation)) {\n\t\t\t// shape is awkwardly rotated, keep the aspect ratio locked and adopt the scale factor\n\t\t\t// from whichever axis is being scaled the least, to avoid the shape getting bigger\n\t\t\t// than the bounds of the selection\n\t\t\t// const minScale = Math.min(Math.abs(scale.x), Math.abs(scale.y))\n\t\t\treturn this._resizeUnalignedShape(id, scale, {\n\t\t\t\t...opts,\n\t\t\t\tinitialBounds,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscaleAxisRotation,\n\t\t\t\tinitialPageTransform: pageTransform,\n\t\t\t\tisAspectRatioLocked,\n\t\t\t\tinitialShape,\n\t\t\t})\n\t\t}\n\n\t\tconst util = this.getShapeUtil(initialShape)\n\n\t\tif (isAspectRatioLocked) {\n\t\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\t\tscale = new Vec(scale.x, Math.sign(scale.y) * Math.abs(scale.x))\n\t\t\t} else {\n\t\t\t\tscale = new Vec(Math.sign(scale.x) * Math.abs(scale.y), scale.y)\n\t\t\t}\n\t\t}\n\n\t\tlet didResize = false\n\n\t\tif (util.onResize && util.canResize(initialShape)) {\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPagePoint = this._scalePagePoint(\n\t\t\t\tMat.applyToPoint(pageTransform, new Vec(0, 0)),\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst newLocalPoint = this.getPointInParentSpace(initialShape.id, newPagePoint)\n\n\t\t\t// resize the shape's local bounding box\n\t\t\tconst myScale = new Vec(scale.x, scale.y)\n\t\t\t// the shape is aligned with the rest of the shapes in the selection, but may be\n\t\t\t// 90deg offset from the main rotation of the selection, in which case\n\t\t\t// we need to flip the width and height scale factors\n\t\t\tconst areWidthAndHeightAlignedWithCorrectAxis = approximately(\n\t\t\t\t(pageRotation - scaleAxisRotation) % Math.PI,\n\t\t\t\t0\n\t\t\t)\n\t\t\tmyScale.x = areWidthAndHeightAlignedWithCorrectAxis ? scale.x : scale.y\n\t\t\tmyScale.y = areWidthAndHeightAlignedWithCorrectAxis ? scale.y : scale.x\n\n\t\t\t// adjust initial model for situations where the parent has moved during the resize\n\t\t\t// e.g. groups\n\t\t\tconst initialPagePoint = Mat.applyToPoint(pageTransform, new Vec())\n\n\t\t\t// need to adjust the shape's x and y points in case the parent has moved since start of resizing\n\t\t\tconst { x, y } = this.getPointInParentSpace(initialShape.id, initialPagePoint)\n\n\t\t\tlet workingShape = initialShape\n\t\t\tif (!opts.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tinitialShape,\n\t\t\t\t\tutil.onResizeStart?.(initialShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst resizedShape = util.onResize(\n\t\t\t\t{ ...initialShape, x, y },\n\t\t\t\t{\n\t\t\t\t\tnewPoint: newLocalPoint,\n\t\t\t\t\thandle: opts.dragHandle ?? 'bottom_right',\n\t\t\t\t\t// don't set isSingle to true for children\n\t\t\t\t\tmode: opts.mode ?? 'scale_shape',\n\t\t\t\t\tscaleX: myScale.x,\n\t\t\t\t\tscaleY: myScale.y,\n\t\t\t\t\tinitialBounds,\n\t\t\t\t\tinitialShape,\n\t\t\t\t}\n\t\t\t)\n\n\t\t\tif (resizedShape) {\n\t\t\t\tdidResize = true\n\t\t\t}\n\n\t\t\tworkingShape = applyPartialToRecordWithProps(workingShape, {\n\t\t\t\tid,\n\t\t\t\ttype: initialShape.type as any,\n\t\t\t\tx: newLocalPoint.x,\n\t\t\t\ty: newLocalPoint.y,\n\t\t\t\t...resizedShape,\n\t\t\t})\n\n\t\t\tif (!opts.skipStartAndEndCallbacks) {\n\t\t\t\tworkingShape = applyPartialToRecordWithProps(\n\t\t\t\t\tworkingShape,\n\t\t\t\t\tutil.onResizeEnd?.(initialShape, workingShape) ?? undefined\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tthis.updateShapes([workingShape])\n\t\t}\n\n\t\tif (!didResize) {\n\t\t\t// reposition shape (rather than resizing it) based on where its resized center would be\n\n\t\t\tconst initialPageCenter = Mat.applyToPoint(pageTransform, initialBounds.center)\n\t\t\t// get the model changes from the shape util\n\t\t\tconst newPageCenter = this._scalePagePoint(\n\t\t\t\tinitialPageCenter,\n\t\t\t\tscaleOrigin,\n\t\t\t\tscale,\n\t\t\t\tscaleAxisRotation\n\t\t\t)\n\n\t\t\tconst initialPageCenterInParentSpace = this.getPointInParentSpace(\n\t\t\t\tinitialShape.id,\n\t\t\t\tinitialPageCenter\n\t\t\t)\n\t\t\tconst newPageCenterInParentSpace = this.getPointInParentSpace(initialShape.id, newPageCenter)\n\n\t\t\tconst delta = Vec.Sub(newPageCenterInParentSpace, initialPageCenterInParentSpace)\n\t\t\t// apply the changes to the model\n\t\t\tthis.updateShapes([\n\t\t\t\t{\n\t\t\t\t\tid,\n\t\t\t\t\ttype: initialShape.type as any,\n\t\t\t\t\tx: initialShape.x + delta.x,\n\t\t\t\t\ty: initialShape.y + delta.y,\n\t\t\t\t},\n\t\t\t])\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate _scalePagePoint(\n\t\tpoint: VecLike,\n\t\tscaleOrigin: VecLike,\n\t\tscale: VecLike,\n\t\tscaleAxisRotation: number\n\t) {\n\t\tconst relativePoint = Vec.RotWith(point, scaleOrigin, -scaleAxisRotation).sub(scaleOrigin)\n\n\t\t// calculate the new point position relative to the scale origin\n\t\tconst newRelativePagePoint = Vec.MulV(relativePoint, scale)\n\n\t\t// and rotate it back to page coords to get the new page point of the resized shape\n\t\tconst destination = Vec.Add(newRelativePagePoint, scaleOrigin).rotWith(\n\t\t\tscaleOrigin,\n\t\t\tscaleAxisRotation\n\t\t)\n\n\t\treturn destination\n\t}\n\n\t/** @internal */\n\tprivate _resizeUnalignedShape(\n\t\tid: TLShapeId,\n\t\tscale: VecLike,\n\t\toptions: {\n\t\t\tinitialBounds: Box\n\t\t\tscaleOrigin: VecLike\n\t\t\tscaleAxisRotation: number\n\t\t\tinitialShape: TLShape\n\t\t\tisAspectRatioLocked: boolean\n\t\t\tinitialPageTransform: MatLike\n\t\t}\n\t) {\n\t\tconst { type } = options.initialShape\n\t\t// If a shape is not aligned with the scale axis we need to treat it differently to avoid skewing.\n\t\t// Instead of skewing we normalize the scale aspect ratio (i.e. keep the same scale magnitude in both axes)\n\t\t// and then after applying the scale to the shape we also rotate it if required and translate it so that it's center\n\t\t// point ends up in the right place.\n\n\t\tconst shapeScale = new Vec(scale.x, scale.y)\n\n\t\t// // make sure we are constraining aspect ratio, and using the smallest scale axis to avoid shapes getting bigger\n\t\t// // than the selection bounding box\n\t\tif (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\tshapeScale.x = Math.sign(scale.x) * Math.abs(scale.y)\n\t\t} else {\n\t\t\tshapeScale.y = Math.sign(scale.y) * Math.abs(scale.x)\n\t\t}\n\n\t\t// first we can scale the shape about its center point\n\t\tthis.resizeShape(id, shapeScale, {\n\t\t\tinitialShape: options.initialShape,\n\t\t\tinitialBounds: options.initialBounds,\n\t\t\tisAspectRatioLocked: options.isAspectRatioLocked,\n\t\t})\n\n\t\t// then if the shape is flipped in one axis only, we need to apply an extra rotation\n\t\t// to make sure the shape is mirrored correctly\n\t\tif (Math.sign(scale.x) * Math.sign(scale.y) < 0) {\n\t\t\tlet { rotation } = Mat.Decompose(options.initialPageTransform)\n\t\t\trotation -= 2 * rotation\n\t\t\tthis.updateShapes([{ id, type, rotation }])\n\t\t}\n\n\t\t// Next we need to translate the shape so that it's center point ends up in the right place.\n\t\t// To do that we first need to calculate the center point of the shape in the current page space before the scale was applied.\n\t\tconst preScaleShapePageCenter = Mat.applyToPoint(\n\t\t\toptions.initialPageTransform,\n\t\t\toptions.initialBounds.center\n\t\t)\n\n\t\t// And now we scale the center point by the original scale factor\n\t\tconst postScaleShapePageCenter = this._scalePagePoint(\n\t\t\tpreScaleShapePageCenter,\n\t\t\toptions.scaleOrigin,\n\t\t\tscale,\n\t\t\toptions.scaleAxisRotation\n\t\t)\n\n\t\t// now calculate how far away the shape is from where it needs to be\n\t\tconst pageBounds = this.getShapePageBounds(id)!\n\t\tconst pageTransform = this.getShapePageTransform(id)!\n\t\tconst currentPageCenter = pageBounds.center\n\t\tconst shapePageTransformOrigin = pageTransform.point()\n\t\tif (!currentPageCenter || !shapePageTransformOrigin) return this\n\t\tconst pageDelta = Vec.Sub(postScaleShapePageCenter, currentPageCenter)\n\n\t\t// and finally figure out what the shape's new position should be\n\t\tconst postScaleShapePagePoint = Vec.Add(shapePageTransformOrigin, pageDelta)\n\t\tconst { x, y } = this.getPointInParentSpace(id, postScaleShapePagePoint)\n\n\t\tthis.updateShapes([{ id, type, x, y }])\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get the initial meta value for a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getInitialMetaForShape = (shape) => {\n\t * if (shape.type === 'note') {\n\t * return { createdBy: myCurrentUser.id }\n\t * }\n\t * }\n\t * ```\n\t *\n\t * @param shape - The shape to get the initial meta for.\n\t *\n\t * @public\n\t */\n\tgetInitialMetaForShape(_shape: TLShape): JsonObject {\n\t\treturn {}\n\t}\n\n\t/**\n\t * Get whether the provided shape can be created.\n\t *\n\t * @param shape - The shape or shape IDs to check.\n\t *\n\t * @public\n\t */\n\tcanCreateShape<T extends TLUnknownShape>(\n\t\tshape: OptionalKeys<TLShapePartial<T>, 'id'> | T['id']\n\t): boolean {\n\t\treturn this.canCreateShapes([shape])\n\t}\n\n\t/**\n\t * Get whether the provided shapes can be created.\n\t *\n\t * @param shapes - The shapes or shape IDs to create.\n\t *\n\t * @public\n\t */\n\tcanCreateShapes<T extends TLUnknownShape>(\n\t\tshapes: (T['id'] | OptionalKeys<TLShapePartial<T>, 'id'>)[]\n\t): boolean {\n\t\treturn shapes.length + this.getCurrentPageShapeIds().size <= this.options.maxShapesPerPage\n\t}\n\n\t/**\n\t * Create a single shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShape(myShape)\n\t * editor.createShape({ id: 'box1', type: 'text', props: { richText: toRichText(\"ok\") } })\n\t * ```\n\t *\n\t * @param shape - The shape (or shape partial) to create.\n\t *\n\t * @public\n\t */\n\tcreateShape<T extends TLUnknownShape>(shape: OptionalKeys<TLShapePartial<T>, 'id'>): this {\n\t\tthis.createShapes([shape])\n\t\treturn this\n\t}\n\n\t/**\n\t * Create shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createShapes([myShape])\n\t * editor.createShapes([{ id: 'box1', type: 'text', props: { richText: toRichText(\"ok\") } }])\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape partials) to create.\n\t *\n\t * @public\n\t */\n\tcreateShapes<T extends TLUnknownShape>(shapes: OptionalKeys<TLShapePartial<T>, 'id'>[]): this {\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.createShapes: must provide an array of shapes or shape partials')\n\t\t}\n\t\tif (this.getIsReadonly()) return this\n\t\tif (shapes.length <= 0) return this\n\n\t\tconst currentPageShapeIds = this.getCurrentPageShapeIds()\n\n\t\tconst maxShapesReached =\n\t\t\tshapes.length + currentPageShapeIds.size > this.options.maxShapesPerPage\n\n\t\tif (maxShapesReached) {\n\t\t\t// can't create more shapes than fit on the page\n\t\t\talertMaxShapes(this)\n\t\t\t// todo: throw an error here? Otherwise we'll need to check every time whether the shapes were actually created\n\t\t\treturn this\n\t\t}\n\n\t\tconst focusedGroupId = this.getFocusedGroupId()\n\n\t\tthis.run(() => {\n\t\t\t// 1. Parents\n\n\t\t\t// Make sure that each partial will become the child of either the\n\t\t\t// page or another shape that exists (or that will exist) in this page.\n\n\t\t\t// find last parent id\n\t\t\tconst currentPageShapesSorted = this.getCurrentPageShapesSorted()\n\n\t\t\tconst partials = shapes.map((partial) => {\n\t\t\t\tif (!partial.id) {\n\t\t\t\t\tpartial = { id: createShapeId(), ...partial }\n\t\t\t\t}\n\n\t\t\t\t// If the partial does not provide the parentId OR if the provided\n\t\t\t\t// parentId is NOT in the store AND NOT among the other shapes being\n\t\t\t\t// created, then we need to find a parent for the shape. This can be\n\t\t\t\t// another shape that exists under that point and which can receive\n\t\t\t\t// children of the creating shape's type, or else the page itself.\n\t\t\t\tif (\n\t\t\t\t\t!partial.parentId ||\n\t\t\t\t\t!(this.store.has(partial.parentId) || shapes.some((p) => p.id === partial.parentId))\n\t\t\t\t) {\n\t\t\t\t\tlet parentId: TLParentId = this.getFocusedGroupId()\n\n\t\t\t\t\tconst isPositioned = partial.x !== undefined && partial.y !== undefined\n\n\t\t\t\t\t// If the shape has been explicitly positioned, we'll try to find a parent at\n\t\t\t\t\t// that position. If not, we'll assume the user isn't deliberately placing the\n\t\t\t\t\t// shape and the positioning will be handled later by another system.\n\t\t\t\t\tif (isPositioned) {\n\t\t\t\t\t\tfor (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {\n\t\t\t\t\t\t\tconst parent = currentPageShapesSorted[i]\n\t\t\t\t\t\t\tconst util = this.getShapeUtil(parent)\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tutil.canReceiveNewChildrenOfType(parent, partial.type) &&\n\t\t\t\t\t\t\t\t!this.isShapeHidden(parent) &&\n\t\t\t\t\t\t\t\tthis.isPointInShape(\n\t\t\t\t\t\t\t\t\tparent,\n\t\t\t\t\t\t\t\t\t// If no parent is provided, then we can treat the\n\t\t\t\t\t\t\t\t\t// shape's provided x/y as being in the page's space.\n\t\t\t\t\t\t\t\t\t{ x: partial.x ?? 0, y: partial.y ?? 0 },\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tmargin: 0,\n\t\t\t\t\t\t\t\t\t\thitInside: true,\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tparentId = parent.id\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst prevParentId = partial.parentId\n\n\t\t\t\t\t// a shape cannot be its own parent. This was a rare issue with frames/groups in the syncFuzz tests.\n\t\t\t\t\tif (parentId === partial.id) {\n\t\t\t\t\t\tparentId = focusedGroupId\n\t\t\t\t\t}\n\n\t\t\t\t\t// If the parentid has changed...\n\t\t\t\t\tif (parentId !== prevParentId) {\n\t\t\t\t\t\tpartial = { ...partial }\n\n\t\t\t\t\t\tpartial.parentId = parentId\n\n\t\t\t\t\t\t// If the parent is a shape (rather than a page) then insert the\n\t\t\t\t\t\t// shapes into the shape's children. Adjust the point and page rotation to be\n\t\t\t\t\t\t// preserved relative to the parent.\n\t\t\t\t\t\tif (isShapeId(parentId)) {\n\t\t\t\t\t\t\tconst point = this.getPointInShapeSpace(this.getShape(parentId)!, {\n\t\t\t\t\t\t\t\tx: partial.x ?? 0,\n\t\t\t\t\t\t\t\ty: partial.y ?? 0,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tpartial.x = point.x\n\t\t\t\t\t\t\tpartial.y = point.y\n\t\t\t\t\t\t\tpartial.rotation =\n\t\t\t\t\t\t\t\t-this.getShapePageTransform(parentId)!.rotation() + (partial.rotation ?? 0)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn partial\n\t\t\t})\n\n\t\t\t// 2. Indices\n\n\t\t\t// Get the highest index among the parents of each of the\n\t\t\t// the shapes being created; we'll increment from there.\n\n\t\t\tconst parentIndices = new Map<TLParentId, IndexKey>()\n\n\t\t\tconst shapeRecordsToCreate: TLShape[] = []\n\n\t\t\tconst { opacityForNextShape } = this.getInstanceState()\n\n\t\t\tfor (const partial of partials) {\n\t\t\t\tconst util = this.getShapeUtil(partial as TLShapePartial)\n\n\t\t\t\t// If an index is not explicitly provided, then add the\n\t\t\t\t// shapes to the top of their parents' children; using the\n\t\t\t\t// value in parentsMappedToIndex, get the index above, use it,\n\t\t\t\t// and set it back to parentsMappedToIndex for next time.\n\t\t\t\tlet index = partial.index\n\n\t\t\t\tif (!index) {\n\t\t\t\t\t// Hello bug-seeker: have you just created a frame and then a shape\n\t\t\t\t\t// and found that the shape is automatically the child of the frame?\n\t\t\t\t\t// this is the reason why! It would be harder to have each shape specify\n\t\t\t\t\t// the frame as the parent when creating a shape inside of a frame, so\n\t\t\t\t\t// we do it here.\n\t\t\t\t\tconst parentId = partial.parentId ?? focusedGroupId\n\n\t\t\t\t\tif (!parentIndices.has(parentId)) {\n\t\t\t\t\t\tparentIndices.set(parentId, this.getHighestIndexForParent(parentId))\n\t\t\t\t\t}\n\t\t\t\t\tindex = parentIndices.get(parentId)!\n\t\t\t\t\tparentIndices.set(parentId, getIndexAbove(index))\n\t\t\t\t}\n\n\t\t\t\t// The initial props starts as the shape utility's default props\n\t\t\t\tconst initialProps = util.getDefaultProps()\n\n\t\t\t\t// We then look up each key in the tab state's styles; and if it's there,\n\t\t\t\t// we use the value from the tab state's styles instead of the default.\n\t\t\t\tfor (const [style, propKey] of this.styleProps[partial.type]) {\n\t\t\t\t\t;(initialProps as any)[propKey] = this.getStyleForNextShape(style)\n\t\t\t\t}\n\n\t\t\t\t// When we create the shape, take in the partial (the props coming into the\n\t\t\t\t// function) and merge it with the default props.\n\t\t\t\tlet shapeRecordToCreate = (\n\t\t\t\t\tthis.store.schema.types.shape as RecordType<\n\t\t\t\t\t\tTLShape,\n\t\t\t\t\t\t'type' | 'props' | 'index' | 'parentId'\n\t\t\t\t\t>\n\t\t\t\t).create({\n\t\t\t\t\t...partial,\n\t\t\t\t\tindex,\n\t\t\t\t\topacity: partial.opacity ?? opacityForNextShape,\n\t\t\t\t\tparentId: partial.parentId ?? focusedGroupId,\n\t\t\t\t\tprops: 'props' in partial ? { ...initialProps, ...partial.props } : initialProps,\n\t\t\t\t})\n\n\t\t\t\tif (shapeRecordToCreate.index === undefined) {\n\t\t\t\t\tthrow Error('no index!')\n\t\t\t\t}\n\n\t\t\t\tconst next = this.getShapeUtil(shapeRecordToCreate).onBeforeCreate?.(shapeRecordToCreate)\n\n\t\t\t\tif (next) {\n\t\t\t\t\tshapeRecordToCreate = next\n\t\t\t\t}\n\n\t\t\t\tshapeRecordsToCreate.push(shapeRecordToCreate)\n\t\t\t}\n\n\t\t\t// Add meta properties, if any, to the shapes\n\t\t\tshapeRecordsToCreate.forEach((shape) => {\n\t\t\t\tshape.meta = {\n\t\t\t\t\t...this.getInitialMetaForShape(shape),\n\t\t\t\t\t...shape.meta,\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tthis.emit('created-shapes', shapeRecordsToCreate)\n\t\t\tthis.emit('edit')\n\t\t\tthis.store.put(shapeRecordsToCreate)\n\t\t})\n\n\t\treturn this\n\t}\n\n\tprivate animatingShapes = new Map<TLShapeId, string>()\n\n\t/**\n\t * Animate a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 })\n\t * editor.animateShape({ id: 'box1', type: 'box', x: 100, y: 100 }, { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t * @param opts - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShape(\n\t\tpartial: TLShapePartial | null | undefined,\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\treturn this.animateShapes([partial], opts)\n\t}\n\n\t/**\n\t * Animate shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }])\n\t * editor.animateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }], { animation: { duration: 100, ease: t => t*t } })\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t * @param opts - The animation's options.\n\t *\n\t * @public\n\t */\n\tanimateShapes(\n\t\tpartials: (TLShapePartial | null | undefined)[],\n\t\topts = { animation: DEFAULT_ANIMATION_OPTIONS } as TLCameraMoveOptions\n\t): this {\n\t\tif (!opts.animation) return this\n\t\tconst { duration = 500, easing = EASINGS.linear } = opts.animation\n\n\t\tconst animationId = uniqueId()\n\n\t\tlet remaining = duration\n\t\tlet t: number\n\n\t\tinterface ShapeAnimation {\n\t\t\tstart: TLShape\n\t\t\tend: TLShape\n\t\t}\n\n\t\tconst animations: ShapeAnimation[] = []\n\n\t\tlet partial: TLShapePartial | null | undefined, result: ShapeAnimation\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tpartial = partials[i]\n\t\t\tif (!partial) continue\n\n\t\t\tconst shape = this.getShape(partial.id)!\n\t\t\tif (!shape) continue\n\n\t\t\tresult = {\n\t\t\t\tstart: structuredClone(shape),\n\t\t\t\tend: applyPartialToRecordWithProps(structuredClone(shape), partial),\n\t\t\t}\n\n\t\t\tanimations.push(result)\n\t\t\tthis.animatingShapes.set(shape.id, animationId)\n\t\t}\n\n\t\tconst handleTick = (elapsed: number) => {\n\t\t\tremaining -= elapsed\n\n\t\t\tif (remaining < 0) {\n\t\t\t\tconst { animatingShapes } = this\n\t\t\t\tconst partialsToUpdate = partials.filter(\n\t\t\t\t\t(p) => p && animatingShapes.get(p.id) === animationId\n\t\t\t\t)\n\t\t\t\tif (partialsToUpdate.length) {\n\t\t\t\t\t// the regular update shapes also removes the shape from\n\t\t\t\t\t// the animating shapes set\n\t\t\t\t\tthis.updateShapes(partialsToUpdate)\n\t\t\t\t}\n\n\t\t\t\tthis.off('tick', handleTick)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tt = easing(1 - remaining / duration)\n\n\t\t\tconst { animatingShapes } = this\n\n\t\t\tconst updates: TLShapePartial[] = []\n\n\t\t\tlet animationIdForShape: string | undefined\n\t\t\tfor (let i = 0, n = animations.length; i < n; i++) {\n\t\t\t\tconst { start, end } = animations[i]\n\t\t\t\t// Is the animation for this shape still active?\n\t\t\t\tanimationIdForShape = animatingShapes.get(start.id)\n\t\t\t\tif (animationIdForShape !== animationId) continue\n\n\t\t\t\tupdates.push({\n\t\t\t\t\t...end,\n\t\t\t\t\tx: start.x + (end.x - start.x) * t,\n\t\t\t\t\ty: start.y + (end.y - start.y) * t,\n\t\t\t\t\topacity: start.opacity + (end.opacity - start.opacity) * t,\n\t\t\t\t\trotation: start.rotation + (end.rotation - start.rotation) * t,\n\t\t\t\t\tprops: this.getShapeUtil(end).getInterpolatedProps?.(start, end, t) ?? end.props,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// The _updateShapes method does NOT remove the\n\t\t\t// shapes from the animated shapes set\n\t\t\tthis._updateShapes(updates)\n\t\t}\n\n\t\tthis.on('tick', handleTick)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Create a group containing the provided shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.groupShapes([myShape, myOtherShape])\n\t * editor.groupShapes([myShape, myOtherShape], { groupId: myGroupId, select: false })\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to group. Defaults to the selected shapes.\n\t * @param opts - An options object.\n\t *\n\t * @public\n\t */\n\tgroupShapes(shapes: TLShape[], opts?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(ids: TLShapeId[], opts?: Partial<{ groupId: TLShapeId; select: boolean }>): this\n\tgroupShapes(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\topts = {} as Partial<{ groupId: TLShapeId; select: boolean }>\n\t): this {\n\t\tconst { groupId = createShapeId(), select = true } = opts\n\n\t\tif (!Array.isArray(shapes)) {\n\t\t\tthrow Error('Editor.groupShapes: must provide an array of shapes or shape ids')\n\t\t}\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes.map((s) => (s as TLShape).id) as TLShapeId[])\n\n\t\tif (ids.length <= 1) return this\n\n\t\tconst shapesToGroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\t\tconst sortedShapeIds = shapesToGroup.sort(sortByIndex).map((s) => s.id)\n\t\tconst pageBounds = Box.Common(compact(shapesToGroup.map((id) => this.getShapePageBounds(id))))\n\n\t\tconst { x, y } = pageBounds.point\n\n\t\tconst parentId = this.findCommonAncestor(shapesToGroup) ?? this.getCurrentPageId()\n\n\t\t// Only group when the select tool is active\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\n\t\t// If not already in idle, cancel the current interaction (get back to idle)\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// Find all the shapes that have the same parentId, and use the highest index.\n\t\tconst shapesWithRootParent = shapesToGroup\n\t\t\t.filter((shape) => shape.parentId === parentId)\n\t\t\t.sort(sortByIndex)\n\n\t\tconst highestIndex = shapesWithRootParent[shapesWithRootParent.length - 1]?.index\n\n\t\tthis.run(() => {\n\t\t\tthis.createShapes<TLGroupShape>([\n\t\t\t\t{\n\t\t\t\t\tid: groupId,\n\t\t\t\t\ttype: 'group',\n\t\t\t\t\tparentId,\n\t\t\t\t\tindex: highestIndex,\n\t\t\t\t\tx,\n\t\t\t\t\ty,\n\t\t\t\t\topacity: 1,\n\t\t\t\t\tprops: {},\n\t\t\t\t},\n\t\t\t])\n\t\t\tthis.reparentShapes(sortedShapeIds, groupId)\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the grouped shapes' children are selected\n\t\t\t\tthis.select(groupId)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Ungroup some shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.ungroupShapes([myGroup, myOtherGroup])\n\t * editor.ungroupShapes([myGroup], { select: false })\n\t * ```\n\t *\n\t * @param shapes - The group shapes (or shape ids) to ungroup.\n\t * @param opts - An options object.\n\t *\n\t * @public\n\t */\n\tungroupShapes(ids: TLShapeId[], opts?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShape[], opts?: Partial<{ select: boolean }>): this\n\tungroupShapes(shapes: TLShapeId[] | TLShape[], opts = {} as Partial<{ select: boolean }>) {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst { select = true } = opts\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tconst shapesToUngroup = compact(\n\t\t\t(this._shouldIgnoreShapeLock ? ids : this._getUnlockedShapeIds(ids)).map((id) =>\n\t\t\t\tthis.getShape(id)\n\t\t\t)\n\t\t)\n\n\t\tif (shapesToUngroup.length === 0) return this\n\n\t\t// todo: the editor shouldn't know about the select tool, move to group / ungroup actions\n\t\tif (this.getCurrentToolId() !== 'select') return this\n\t\tif (!this.isIn('select.idle')) {\n\t\t\tthis.cancel()\n\t\t}\n\n\t\t// The ids of the selected shapes after ungrouping;\n\t\t// these include all of the grouped shapes children,\n\t\t// plus any shapes that were selected apart from the groups.\n\t\tconst idsToSelect = new Set<TLShapeId>()\n\n\t\t// Get all groups in the selection\n\t\tconst groups: TLGroupShape[] = []\n\n\t\tshapesToUngroup.forEach((shape) => {\n\t\t\tif (this.isShapeOfType<TLGroupShape>(shape, 'group')) {\n\t\t\t\tgroups.push(shape)\n\t\t\t} else {\n\t\t\t\tidsToSelect.add(shape.id)\n\t\t\t}\n\t\t})\n\n\t\tif (groups.length === 0) return this\n\n\t\tthis.run(() => {\n\t\t\tlet group: TLGroupShape\n\n\t\t\tfor (let i = 0, n = groups.length; i < n; i++) {\n\t\t\t\tgroup = groups[i]\n\t\t\t\tconst childIds = this.getSortedChildIdsForParent(group.id)\n\n\t\t\t\tfor (let j = 0, n = childIds.length; j < n; j++) {\n\t\t\t\t\tidsToSelect.add(childIds[j])\n\t\t\t\t}\n\n\t\t\t\tthis.reparentShapes(childIds, group.parentId, group.index)\n\t\t\t}\n\n\t\t\tthis.deleteShapes(groups.map((group) => group.id))\n\n\t\t\tif (select) {\n\t\t\t\t// the select option determines whether the ungrouped shapes' children are selected\n\t\t\t\tthis.select(...idsToSelect)\n\t\t\t}\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Update a shape using a partial of the shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShape({ id: 'box1', type: 'geo', props: { w: 100, h: 100 } })\n\t * ```\n\t *\n\t * @param partial - The shape partial to update.\n\t *\n\t * @public\n\t */\n\tupdateShape<T extends TLUnknownShape>(partial: TLShapePartial<T> | null | undefined) {\n\t\tthis.updateShapes([partial])\n\t\treturn this\n\t}\n\n\t/**\n\t * Update shapes using partials of each shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updateShapes([{ id: 'box1', type: 'geo', props: { w: 100, h: 100 } }])\n\t * ```\n\t *\n\t * @param partials - The shape partials to update.\n\t *\n\t * @public\n\t */\n\tupdateShapes<T extends TLUnknownShape>(partials: (TLShapePartial<T> | null | undefined)[]) {\n\t\tconst compactedPartials: TLShapePartial<T>[] = Array(partials.length)\n\n\t\tfor (let i = 0, n = partials.length; i < n; i++) {\n\t\t\tconst partial = partials[i]\n\t\t\tif (!partial) continue\n\t\t\t// Get the current shape referenced by the partial\n\t\t\tconst shape = this.getShape(partial.id)\n\t\t\tif (!shape) continue\n\n\t\t\t// If we're \"forcing\" the update, then we'll update the shape\n\t\t\t// regardless of whether it / its ancestor is locked\n\t\t\tif (!this._shouldIgnoreShapeLock) {\n\t\t\t\tif (shape.isLocked) {\n\t\t\t\t\t// If the shape itself is locked (even if one of its ancestors is\n\t\t\t\t\t// also locked) then only allow an update that unlocks the shape.\n\t\t\t\t\tif (!(Object.hasOwn(partial, 'isLocked') && !partial.isLocked)) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else if (this.isShapeOrAncestorLocked(shape)) {\n\t\t\t\t\t// If the shape itself is unlocked, and any of the shape's\n\t\t\t\t\t// ancestors are locked then we'll skip the update\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove any animating shapes from the list of partials\n\t\t\tthis.animatingShapes.delete(partial.id)\n\n\t\t\tcompactedPartials.push(partial)\n\t\t}\n\n\t\tthis._updateShapes(compactedPartials)\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_updateShapes(_partials: (TLShapePartial | null | undefined)[]) {\n\t\tif (this.getIsReadonly()) return\n\n\t\tthis.run(() => {\n\t\t\tconst updates = []\n\n\t\t\tlet shape: TLShape | undefined\n\t\t\tlet updated: TLShape\n\n\t\t\tfor (let i = 0, n = _partials.length; i < n; i++) {\n\t\t\t\tconst partial = _partials[i]\n\t\t\t\t// Skip nullish partials (sometimes created by map fns returning undefined)\n\t\t\t\tif (!partial) continue\n\n\t\t\t\t// Get the current shape referenced by the partial\n\t\t\t\t// If there is no current shape, we'll skip this update\n\t\t\t\tshape = this.getShape(partial.id)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\t// Get the updated version of the shape\n\t\t\t\t// If the update had no effect, we'll skip this update\n\t\t\t\tupdated = applyPartialToRecordWithProps(shape, partial)\n\t\t\t\tif (updated === shape) continue\n\n\t\t\t\t//if any shape has an onBeforeUpdate handler, call it and, if the handler returns a\n\t\t\t\t// new shape, replace the old shape with the new one. This is used for example when\n\t\t\t\t// repositioning a text shape based on its new text content.\n\t\t\t\tupdated = this.getShapeUtil(shape).onBeforeUpdate?.(shape, updated) ?? updated\n\n\t\t\t\tupdates.push(updated)\n\t\t\t}\n\n\t\t\tthis.emit('edited-shapes', updates)\n\t\t\tthis.emit('edit')\n\t\t\tthis.store.put(updates)\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _getUnlockedShapeIds(ids: TLShapeId[]): TLShapeId[] {\n\t\treturn ids.filter((id) => !this.getShape(id)?.isLocked)\n\t}\n\n\t/**\n\t * Delete shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShapes(['box1', 'box2'])\n\t * ```\n\t *\n\t * @param ids - The ids of the shapes to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShapes(ids: TLShapeId[]): this\n\tdeleteShapes(shapes: TLShape[]): this\n\tdeleteShapes(_ids: TLShapeId[] | TLShape[]): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tif (!Array.isArray(_ids)) {\n\t\t\tthrow Error('Editor.deleteShapes: must provide an array of shapes or shapeIds')\n\t\t}\n\n\t\tconst shapeIds =\n\t\t\ttypeof _ids[0] === 'string' ? (_ids as TLShapeId[]) : (_ids as TLShape[]).map((s) => s.id)\n\n\t\t// Normally we don't want to delete locked shapes, but if the force option is set, we'll delete them anyway\n\t\tconst shapeIdsToDelete = this._shouldIgnoreShapeLock\n\t\t\t? shapeIds\n\t\t\t: this._getUnlockedShapeIds(shapeIds)\n\n\t\tif (shapeIdsToDelete.length === 0) return this\n\n\t\t// We also need to delete these shapes' descendants\n\t\tconst allShapeIdsToDelete = new Set<TLShapeId>(shapeIdsToDelete)\n\n\t\tfor (const id of shapeIdsToDelete) {\n\t\t\tthis.visitDescendants(id, (childId) => {\n\t\t\t\tallShapeIdsToDelete.add(childId)\n\t\t\t})\n\t\t}\n\n\t\tthis.emit('deleted-shapes', [...allShapeIdsToDelete])\n\t\tthis.emit('edit')\n\t\treturn this.run(() => this.store.remove([...allShapeIdsToDelete]))\n\t}\n\n\t/**\n\t * Delete a shape.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.deleteShape(shape.id)\n\t * ```\n\t *\n\t * @param id - The id of the shape to delete.\n\t *\n\t * @public\n\t */\n\tdeleteShape(id: TLShapeId): this\n\tdeleteShape(shape: TLShape): this\n\tdeleteShape(_id: TLShapeId | TLShape) {\n\t\tthis.deleteShapes([typeof _id === 'string' ? _id : _id.id])\n\t\treturn this\n\t}\n\n\t/* --------------------- Styles --------------------- */\n\n\t/**\n\t * Get all the current styles among the users selected shapes\n\t *\n\t * @internal\n\t */\n\tprivate _extractSharedStyles(shape: TLShape, sharedStyleMap: SharedStyleMap) {\n\t\tif (this.isShapeOfType<TLGroupShape>(shape, 'group')) {\n\t\t\t// For groups, ignore the styles of the group shape and instead include the styles of the\n\t\t\t// group's children. These are the shapes that would have their styles changed if the\n\t\t\t// user called `setStyle` on the current selection.\n\t\t\tconst childIds = this._parentIdsToChildIds.get()[shape.id]\n\t\t\tif (!childIds) return\n\n\t\t\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\t\t\tthis._extractSharedStyles(this.getShape(childIds[i])!, sharedStyleMap)\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const [style, propKey] of this.styleProps[shape.type]) {\n\t\t\t\tsharedStyleMap.applyValue(style, getOwnProperty(shape.props, propKey))\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * A derived map containing all current styles among the user's selected shapes.\n\t *\n\t * @internal\n\t */\n\t@computed\n\tprivate _getSelectionSharedStyles(): ReadonlySharedStyleMap {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tconst sharedStyles = new SharedStyleMap()\n\t\tfor (const selectedShape of selectedShapes) {\n\t\t\tthis._extractSharedStyles(selectedShape, sharedStyles)\n\t\t}\n\n\t\treturn sharedStyles\n\t}\n\n\t/**\n\t * Get the style for the next shape.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getStyleForNextShape(DefaultColorStyle)\n\t * ```\n\t *\n\t * @param style - The style to get.\n\t *\n\t * @public */\n\tgetStyleForNextShape<T>(style: StyleProp<T>): T {\n\t\tconst value = this.getInstanceState().stylesForNextShape[style.id]\n\t\treturn value === undefined ? style.defaultValue : (value as T)\n\t}\n\n\tgetShapeStyleIfExists<T>(shape: TLShape, style: StyleProp<T>): T | undefined {\n\t\tconst styleKey = this.styleProps[shape.type].get(style)\n\t\tif (styleKey === undefined) return undefined\n\t\treturn getOwnProperty(shape.props, styleKey) as T | undefined\n\t}\n\n\t/**\n\t * A map of all the current styles either in the current selection, or that are relevant to the\n\t * current tool.\n\t *\n\t * @example\n\t * ```ts\n\t * const color = editor.getSharedStyles().get(DefaultColorStyle)\n\t * if (color && color.type === 'shared') {\n\t * print('All selected shapes have the same color:', color.value)\n\t * }\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed<ReadonlySharedStyleMap>({ isEqual: (a, b) => a.equals(b) })\n\tgetSharedStyles(): ReadonlySharedStyleMap {\n\t\t// If we're in selecting and if we have a selection, return the shared styles from the\n\t\t// current selection\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\treturn this._getSelectionSharedStyles()\n\t\t}\n\n\t\t// If the current tool is associated with a shape, return the styles for that shape.\n\t\t// Otherwise, just return an empty map.\n\t\tconst currentTool = this.root.getCurrent()!\n\t\tconst styles = new SharedStyleMap()\n\n\t\tif (!currentTool) return styles\n\n\t\tif (currentTool.shapeType) {\n\t\t\tif (\n\t\t\t\tcurrentTool.shapeType === 'frame' &&\n\t\t\t\t!(this.getShapeUtil('frame')!.options as any).showColors\n\t\t\t) {\n\t\t\t\tfor (const style of this.styleProps[currentTool.shapeType].keys()) {\n\t\t\t\t\tif (style.id === 'tldraw:color') continue\n\t\t\t\t\tstyles.applyValue(style, this.getStyleForNextShape(style))\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (const style of this.styleProps[currentTool.shapeType].keys()) {\n\t\t\t\t\tstyles.applyValue(style, this.getStyleForNextShape(style))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn styles\n\t}\n\n\t/**\n\t * Get the currently selected shared opacity.\n\t * If any shapes are selected, this returns the shared opacity of the selected shapes.\n\t * Otherwise, this returns the chosen opacity for the next shape.\n\t *\n\t * @public\n\t */\n\t@computed getSharedOpacity(): SharedStyle<number> {\n\t\tif (this.isIn('select') && this.getSelectedShapeIds().length > 0) {\n\t\t\tconst shapesToCheck: TLShape[] = []\n\t\t\tconst addShape = (shapeId: TLShapeId) => {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) return\n\t\t\t\t// For groups, ignore the opacity of the group shape and instead include\n\t\t\t\t// the opacity of the group's children. These are the shapes that would have\n\t\t\t\t// their opacity changed if the user called `setOpacity` on the current selection.\n\t\t\t\tif (this.isShapeOfType<TLGroupShape>(shape, 'group')) {\n\t\t\t\t\tfor (const childId of this.getSortedChildIdsForParent(shape.id)) {\n\t\t\t\t\t\taddShape(childId)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToCheck.push(shape)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const shapeId of this.getSelectedShapeIds()) {\n\t\t\t\taddShape(shapeId)\n\t\t\t}\n\n\t\t\tlet opacity: number | null = null\n\t\t\tfor (const shape of shapesToCheck) {\n\t\t\t\tif (opacity === null) {\n\t\t\t\t\topacity = shape.opacity\n\t\t\t\t} else if (opacity !== shape.opacity) {\n\t\t\t\t\treturn { type: 'mixed' }\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (opacity !== null) return { type: 'shared', value: opacity }\n\t\t}\n\t\treturn { type: 'shared', value: this.getInstanceState().opacityForNextShape }\n\t}\n\n\t/**\n\t * Set the opacity for the next shapes. This will effect subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForNextShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t * @param historyOptions - The history options for the change.\n\t */\n\tsetOpacityForNextShapes(opacity: number, historyOptions?: TLHistoryBatchOptions): this {\n\t\tthis.updateInstanceState({ opacityForNextShape: opacity }, historyOptions)\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the current opacity. This will effect any selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setOpacityForSelectedShapes(0.5)\n\t * ```\n\t *\n\t * @param opacity - The opacity to set. Must be a number between 0 and 1 inclusive.\n\t */\n\tsetOpacityForSelectedShapes(opacity: number): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst shapesToUpdate: TLShape[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType<TLGroupShape>(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tshapesToUpdate.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const id of selectedShapes) {\n\t\t\t\taddShapeById(id)\n\t\t\t}\n\n\t\t\tthis.updateShapes(\n\t\t\t\tshapesToUpdate.map((shape) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\topacity,\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp} for the next shapes. This change will be applied to subsequently created shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red')\n\t * editor.setStyleForNextShapes(DefaultColorStyle, 'red', { ephemeral: true })\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t * @param historyOptions - The history options for the change.\n\t *\n\t * @public\n\t */\n\tsetStyleForNextShapes<T>(\n\t\tstyle: StyleProp<T>,\n\t\tvalue: T,\n\t\thistoryOptions?: TLHistoryBatchOptions\n\t): this {\n\t\tconst stylesForNextShape = this.getInstanceState().stylesForNextShape\n\n\t\tthis.updateInstanceState(\n\t\t\t{ stylesForNextShape: { ...stylesForNextShape, [style.id]: value } },\n\t\t\thistoryOptions\n\t\t)\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Set the value of a {@link @tldraw/tlschema#StyleProp}. This change will be applied to the currently selected shapes.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.setStyleForSelectedShapes(DefaultColorStyle, 'red')\n\t * ```\n\t *\n\t * @param style - The style to set.\n\t * @param value - The value to set.\n\t *\n\t * @public\n\t */\n\tsetStyleForSelectedShapes<S extends StyleProp<any>>(style: S, value: StylePropValue<S>): this {\n\t\tconst selectedShapes = this.getSelectedShapes()\n\n\t\tif (selectedShapes.length > 0) {\n\t\t\tconst updates: {\n\t\t\t\tutil: ShapeUtil\n\t\t\t\toriginalShape: TLShape\n\t\t\t\tupdatePartial: TLShapePartial\n\t\t\t}[] = []\n\n\t\t\t// We can have many deep levels of grouped shape\n\t\t\t// Making a recursive function to look through all the levels\n\t\t\tconst addShapeById = (shape: TLShape) => {\n\t\t\t\tif (this.isShapeOfType<TLGroupShape>(shape, 'group')) {\n\t\t\t\t\tconst childIds = this.getSortedChildIdsForParent(shape.id)\n\t\t\t\t\tfor (const childId of childIds) {\n\t\t\t\t\t\taddShapeById(this.getShape(childId)!)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\tconst stylePropKey = this.styleProps[shape.type].get(style)\n\t\t\t\t\tif (stylePropKey) {\n\t\t\t\t\t\tconst shapePartial: TLShapePartial = {\n\t\t\t\t\t\t\tid: shape.id,\n\t\t\t\t\t\t\ttype: shape.type,\n\t\t\t\t\t\t\tprops: { [stylePropKey]: value },\n\t\t\t\t\t\t}\n\t\t\t\t\t\tupdates.push({\n\t\t\t\t\t\t\tutil,\n\t\t\t\t\t\t\toriginalShape: shape,\n\t\t\t\t\t\t\tupdatePartial: shapePartial,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const shape of selectedShapes) {\n\t\t\t\taddShapeById(shape)\n\t\t\t}\n\n\t\t\tthis.updateShapes(updates.map(({ updatePartial }) => updatePartial))\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/* --------------------- Content -------------------- */\n\n\t/** @internal */\n\texternalAssetContentHandlers: {\n\t\t[K in TLExternalAsset['type']]: {\n\t\t\t[Key in K]: null | ((info: TLExternalAsset & { type: Key }) => Promise<TLAsset | undefined>)\n\t\t}[K]\n\t} = {\n\t\tfile: null,\n\t\turl: null,\n\t}\n\n\t/** @internal */\n\tprivate readonly temporaryAssetPreview = new Map<TLAssetId, string>()\n\n\t/**\n\t * Register an external asset handler. This handler will be called when the editor needs to\n\t * create an asset for some external content, like an image/video file or a bookmark URL. For\n\t * example, the 'file' type handler will be called when a user drops an image onto the canvas.\n\t *\n\t * The handler should extract any relevant metadata for the asset, upload it to blob storage\n\t * using {@link Editor.uploadAsset} if needed, and return the asset with the metadata & uploaded\n\t * URL.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalAssetHandler('file', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalAssetHandler<T extends TLExternalAsset['type']>(\n\t\ttype: T,\n\t\thandler: null | ((info: TLExternalAsset & { type: T }) => Promise<TLAsset>)\n\t): this {\n\t\tthis.externalAssetContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Register a temporary preview of an asset. This is useful for showing a ghost image of\n\t * something that is being uploaded. Retrieve the placeholder with\n\t * {@link Editor.getTemporaryAssetPreview}. Placeholders last for 3 minutes by default, but this\n\t * can be configured using\n\t *\n\t * @example\n\t * ```ts\n\t * editor.createTemporaryAssetPreview(assetId, file)\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t * @param file - The raw file.\n\t *\n\t * @public\n\t */\n\tcreateTemporaryAssetPreview(assetId: TLAssetId, file: File) {\n\t\tif (this.temporaryAssetPreview.has(assetId)) {\n\t\t\treturn this.temporaryAssetPreview.get(assetId)\n\t\t}\n\n\t\tconst objectUrl = URL.createObjectURL(file)\n\t\tthis.temporaryAssetPreview.set(assetId, objectUrl)\n\n\t\t// eslint-disable-next-line no-restricted-globals -- we always want to revoke the asset and object URL\n\t\tsetTimeout(() => {\n\t\t\tthis.temporaryAssetPreview.delete(assetId)\n\t\t\tURL.revokeObjectURL(objectUrl)\n\t\t}, this.options.temporaryAssetPreviewLifetimeMs)\n\n\t\treturn objectUrl\n\t}\n\n\t/**\n\t * Get temporary preview of an asset. This is useful for showing a ghost\n\t * image of something that is being uploaded.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.getTemporaryAssetPreview('someId')\n\t * ```\n\t *\n\t * @param assetId - The asset's id.\n\t *\n\t * @public\n\t */\n\tgetTemporaryAssetPreview(assetId: TLAssetId) {\n\t\treturn this.temporaryAssetPreview.get(assetId)\n\t}\n\n\t/**\n\t * Get an asset for an external asset content type.\n\t *\n\t * @example\n\t * ```ts\n\t * const asset = await editor.getAssetForExternalContent({ type: 'file', file: myFile })\n\t * const asset = await editor.getAssetForExternalContent({ type: 'url', url: myUrl })\n\t * ```\n\t *\n\t * @param info - Info about the external content.\n\t * @returns The asset.\n\t */\n\tasync getAssetForExternalContent(info: TLExternalAsset): Promise<TLAsset | undefined> {\n\t\treturn await this.externalAssetContentHandlers[info.type]?.(info as any)\n\t}\n\n\thasExternalAssetHandler(type: TLExternalAsset['type']): boolean {\n\t\treturn !!this.externalAssetContentHandlers[type]\n\t}\n\n\t/** @internal */\n\texternalContentHandlers: {\n\t\t[K in TLExternalContent<any>['type']]: {\n\t\t\t[Key in K]: null | ((info: Extract<TLExternalContent<any>, { type: Key }>) => void)\n\t\t}[K]\n\t} = {\n\t\ttext: null,\n\t\tfiles: null,\n\t\t'file-replace': null,\n\t\tembed: null,\n\t\t'svg-text': null,\n\t\turl: null,\n\t\ttldraw: null,\n\t\texcalidraw: null,\n\t}\n\n\t/**\n\t * Register an external content handler. This handler will be called when the editor receives\n\t * external content of the provided type. For example, the 'image' type handler will be called\n\t * when a user drops an image onto the canvas.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler('text', myHandler)\n\t * ```\n\t * @example\n\t * ```ts\n\t * editor.registerExternalContentHandler<'embed', MyEmbedType>('embed', myHandler)\n\t * ```\n\t *\n\t * @param type - The type of external content.\n\t * @param handler - The handler to use for this content type.\n\t *\n\t * @public\n\t */\n\tregisterExternalContentHandler<T extends TLExternalContent<E>['type'], E>(\n\t\ttype: T,\n\t\thandler:\n\t\t\t| null\n\t\t\t| ((\n\t\t\t\t\tinfo: T extends TLExternalContent<E>['type']\n\t\t\t\t\t\t? Extract<TLExternalContent<E>, { type: T }>\n\t\t\t\t\t\t: TLExternalContent<E>\n\t\t\t ) => void)\n\t): this {\n\t\tthis.externalContentHandlers[type] = handler as any\n\t\treturn this\n\t}\n\n\t/**\n\t * Handle external content, such as files, urls, embeds, or plain text which has been put into the app, for example by pasting external text or dropping external images onto canvas.\n\t *\n\t * @param info - Info about the external content.\n\t * @param opts - Options for handling external content, including force flag to bypass readonly checks.\n\t */\n\tasync putExternalContent<E>(\n\t\tinfo: TLExternalContent<E>,\n\t\topts = {} as { force?: boolean }\n\t): Promise<void> {\n\t\tif (!opts.force && this.getIsReadonly()) return\n\t\treturn this.externalContentHandlers[info.type]?.(info as any)\n\t}\n\n\t/**\n\t * Handle replacing external content.\n\t *\n\t * @param info - Info about the external content.\n\t * @param opts - Options for handling external content, including force flag to bypass readonly checks.\n\t */\n\tasync replaceExternalContent<E>(\n\t\tinfo: TLExternalContent<E>,\n\t\topts = {} as { force?: boolean }\n\t): Promise<void> {\n\t\tif (!opts.force && this.getIsReadonly()) return\n\t\treturn this.externalContentHandlers[info.type]?.(info as any)\n\t}\n\n\t/**\n\t * Get content that can be exported for the given shape ids.\n\t *\n\t * @param shapes - The shapes (or shape ids) to get content for.\n\t *\n\t * @returns The exported content.\n\t *\n\t * @public\n\t */\n\tgetContentFromCurrentPage(shapes: TLShapeId[] | TLShape[]): TLContent | undefined {\n\t\t// todo: make this work with any page, not just the current page\n\t\tconst ids =\n\t\t\ttypeof shapes[0] === 'string'\n\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (!ids) return\n\t\tif (ids.length === 0) return\n\n\t\tconst shapeIds = this.getShapeAndDescendantIds(ids)\n\n\t\treturn withIsolatedShapes(this, shapeIds, (bindingIdsToKeep) => {\n\t\t\tconst bindings: TLBinding[] = []\n\t\t\tfor (const id of bindingIdsToKeep) {\n\t\t\t\tconst binding = this.getBinding(id)\n\t\t\t\tif (!binding) continue\n\t\t\t\tbindings.push(binding)\n\t\t\t}\n\n\t\t\tconst rootShapeIds: TLShapeId[] = []\n\t\t\tconst shapes: TLShape[] = []\n\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\tconst shape = this.getShape(shapeId)\n\t\t\t\tif (!shape) continue\n\n\t\t\t\tconst isRootShape = !shapeIds.has(shape.parentId as TLShapeId)\n\t\t\t\tif (isRootShape) {\n\t\t\t\t\t// Need to get page point and rotation of the shape because shapes in\n\t\t\t\t\t// groups use local position/rotation\n\t\t\t\t\tconst pageTransform = this.getShapePageTransform(shape.id)!\n\t\t\t\t\tconst pagePoint = pageTransform.point()\n\t\t\t\t\tshapes.push({\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tx: pagePoint.x,\n\t\t\t\t\t\ty: pagePoint.y,\n\t\t\t\t\t\trotation: pageTransform.rotation(),\n\t\t\t\t\t\tparentId: this.getCurrentPageId(),\n\t\t\t\t\t})\n\t\t\t\t\trootShapeIds.push(shape.id)\n\t\t\t\t} else {\n\t\t\t\t\tshapes.push(shape)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst assets: TLAsset[] = []\n\t\t\tconst seenAssetIds = new Set<TLAssetId>()\n\t\t\tfor (const shape of shapes) {\n\t\t\t\tif (!('assetId' in shape.props)) continue\n\n\t\t\t\tconst assetId = shape.props.assetId\n\t\t\t\tif (!assetId || seenAssetIds.has(assetId)) continue\n\n\t\t\t\tseenAssetIds.add(assetId)\n\t\t\t\tconst asset = this.getAsset(assetId)\n\t\t\t\tif (!asset) continue\n\t\t\t\tassets.push(asset)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tschema: this.store.schema.serialize(),\n\t\t\t\tshapes,\n\t\t\t\trootShapeIds,\n\t\t\t\tbindings,\n\t\t\t\tassets,\n\t\t\t}\n\t\t})\n\t}\n\n\tasync resolveAssetsInContent(content: TLContent | undefined): Promise<TLContent | undefined> {\n\t\tif (!content) return undefined\n\n\t\tconst assets: TLAsset[] = []\n\t\tawait Promise.allSettled(\n\t\t\tcontent.assets.map(async (asset) => {\n\t\t\t\tif (\n\t\t\t\t\t(asset.type === 'image' || asset.type === 'video') &&\n\t\t\t\t\t!asset.props.src?.startsWith('data:image') &&\n\t\t\t\t\t!asset.props.src?.startsWith('data:video') &&\n\t\t\t\t\t!asset.props.src?.startsWith('http')\n\t\t\t\t) {\n\t\t\t\t\tconst assetWithDataUrl = structuredClone(asset as TLImageAsset | TLVideoAsset)\n\t\t\t\t\tconst objectUrl = await this.store.props.assets.resolve(asset, {\n\t\t\t\t\t\tscreenScale: 1,\n\t\t\t\t\t\tsteppedScreenScale: 1,\n\t\t\t\t\t\tdpr: 1,\n\t\t\t\t\t\tnetworkEffectiveType: null,\n\t\t\t\t\t\tshouldResolveToOriginal: true,\n\t\t\t\t\t})\n\t\t\t\t\tassetWithDataUrl.props.src = await FileHelpers.blobToDataUrl(\n\t\t\t\t\t\tawait fetch(objectUrl!).then((r) => r.blob())\n\t\t\t\t\t)\n\t\t\t\t\tassets.push(assetWithDataUrl)\n\t\t\t\t} else {\n\t\t\t\t\tassets.push(asset)\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t\tcontent.assets = assets\n\n\t\treturn content\n\t}\n\n\t/**\n\t * Place content into the editor.\n\t *\n\t * @param content - The content.\n\t * @param opts - Options for placing the content.\n\t *\n\t * @public\n\t */\n\tputContentOntoCurrentPage(\n\t\tcontent: TLContent,\n\t\topts: {\n\t\t\tpoint?: VecLike\n\t\t\tselect?: boolean\n\t\t\tpreservePosition?: boolean\n\t\t\tpreserveIds?: boolean\n\t\t} = {}\n\t): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\t// todo: make this able to support putting content onto any page, not just the current page\n\n\t\tif (!content.schema) {\n\t\t\tthrow Error('Could not put content:\\ncontent is missing a schema.')\n\t\t}\n\n\t\tconst { select = false, preserveIds = false, preservePosition = false } = opts\n\t\tlet { point = undefined } = opts\n\n\t\t// decide on a parent for the put shapes; if the parent is among the put shapes(?) then use its parent\n\n\t\tconst currentPageId = this.getCurrentPageId()\n\t\tconst { rootShapeIds } = content\n\n\t\t// We need to collect the migrated records\n\t\tconst assets: TLAsset[] = []\n\t\tconst shapes: TLShape[] = []\n\t\tconst bindings: TLBinding[] = []\n\n\t\t// Let's treat the content as a store, and then migrate that store.\n\t\tconst store: StoreSnapshot<TLRecord> = {\n\t\t\tstore: {\n\t\t\t\t...Object.fromEntries(content.assets.map((asset) => [asset.id, asset] as const)),\n\t\t\t\t...Object.fromEntries(content.shapes.map((shape) => [shape.id, shape] as const)),\n\t\t\t\t...Object.fromEntries(\n\t\t\t\t\tcontent.bindings?.map((bindings) => [bindings.id, bindings] as const) ?? []\n\t\t\t\t),\n\t\t\t},\n\t\t\tschema: content.schema,\n\t\t}\n\t\tconst result = this.store.schema.migrateStoreSnapshot(store)\n\t\tif (result.type === 'error') {\n\t\t\tthrow Error('Could not put content: could not migrate content')\n\t\t}\n\t\tfor (const record of Object.values(result.value)) {\n\t\t\tswitch (record.typeName) {\n\t\t\t\tcase 'asset': {\n\t\t\t\t\tassets.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'shape': {\n\t\t\t\t\tshapes.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'binding': {\n\t\t\t\t\tbindings.push(record)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Ok, we've got our migrated records, now we can continue!\n\t\tconst shapeIdMap = new Map<string, TLShapeId>(\n\t\t\tpreserveIds\n\t\t\t\t? shapes.map((shape) => [shape.id, shape.id])\n\t\t\t\t: shapes.map((shape) => [shape.id, createShapeId()])\n\t\t)\n\t\tconst bindingIdMap = new Map<string, TLBindingId>(\n\t\t\tpreserveIds\n\t\t\t\t? bindings.map((binding) => [binding.id, binding.id])\n\t\t\t\t: bindings.map((binding) => [binding.id, createBindingId()])\n\t\t)\n\n\t\t// By default, the paste parent will be the current page.\n\t\tlet pasteParentId = this.getCurrentPageId() as TLPageId | TLShapeId\n\t\tlet lowestDepth = Infinity\n\t\tlet lowestAncestors: TLShape[] = []\n\n\t\t// Among the selected shapes, find the shape with the fewest ancestors and use its first ancestor.\n\t\tfor (const shape of this.getSelectedShapes()) {\n\t\t\tif (lowestDepth === 0) break\n\n\t\t\tconst isFrame = this.isShapeOfType<TLFrameShape>(shape, 'frame')\n\t\t\tconst ancestors = this.getShapeAncestors(shape)\n\t\t\tif (isFrame) ancestors.push(shape)\n\n\t\t\tconst depth = isFrame ? ancestors.length + 1 : ancestors.length\n\n\t\t\tif (depth < lowestDepth) {\n\t\t\t\tlowestDepth = depth\n\t\t\t\tlowestAncestors = ancestors\n\t\t\t\tpasteParentId = isFrame ? shape.id : shape.parentId\n\t\t\t} else if (depth === lowestDepth) {\n\t\t\t\tif (lowestAncestors.length !== ancestors.length) {\n\t\t\t\t\tthrow Error(`Ancestors: ${lowestAncestors.length} !== ${ancestors.length}`)\n\t\t\t\t}\n\n\t\t\t\tif (lowestAncestors.length === 0) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tbreak\n\t\t\t\t} else {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t\tfor (let i = 0; i < lowestAncestors.length; i++) {\n\t\t\t\t\t\tif (ancestors[i] !== lowestAncestors[i]) break\n\t\t\t\t\t\tpasteParentId = ancestors[i].id\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlet isDuplicating = false\n\n\t\tif (!isPageId(pasteParentId)) {\n\t\t\tconst parent = this.getShape(pasteParentId)\n\t\t\tif (parent) {\n\t\t\t\tif (!this.getViewportPageBounds().includes(this.getShapePageBounds(parent)!)) {\n\t\t\t\t\tpasteParentId = currentPageId\n\t\t\t\t} else {\n\t\t\t\t\tif (rootShapeIds.length === 1) {\n\t\t\t\t\t\tconst rootShape = shapes.find((s) => s.id === rootShapeIds[0])!\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.isShapeOfType<TLFrameShape>(parent, 'frame') &&\n\t\t\t\t\t\t\tthis.isShapeOfType<TLFrameShape>(rootShape, 'frame') &&\n\t\t\t\t\t\t\trootShape.props.w === parent?.props.w &&\n\t\t\t\t\t\t\trootShape.props.h === parent?.props.h\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tisDuplicating = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpasteParentId = currentPageId\n\t\t\t}\n\t\t}\n\n\t\tif (!isDuplicating) {\n\t\t\tisDuplicating = shapeIdMap.has(pasteParentId)\n\t\t}\n\n\t\tif (isDuplicating) {\n\t\t\tpasteParentId = this.getShape(pasteParentId)!.parentId\n\t\t}\n\n\t\tlet index = this.getHighestIndexForParent(pasteParentId) // todo: requires that the putting page is the current page\n\n\t\tconst rootShapes: TLShape[] = []\n\n\t\tconst newShapes: TLShape[] = shapes.map((oldShape): TLShape => {\n\t\t\tconst newId = shapeIdMap.get(oldShape.id)!\n\n\t\t\t// Create the new shape (new except for the id)\n\t\t\tconst newShape = { ...oldShape, id: newId }\n\n\t\t\tif (rootShapeIds.includes(oldShape.id)) {\n\t\t\t\tnewShape.parentId = currentPageId\n\t\t\t\trootShapes.push(newShape)\n\t\t\t}\n\n\t\t\t// Assign the child to its new parent.\n\n\t\t\t// If the child's parent is among the putting shapes, then assign\n\t\t\t// it to the new parent's id.\n\t\t\tif (shapeIdMap.has(newShape.parentId)) {\n\t\t\t\tnewShape.parentId = shapeIdMap.get(oldShape.parentId)!\n\t\t\t} else {\n\t\t\t\trootShapeIds.push(newShape.id)\n\t\t\t\t// newShape.parentId = pasteParentId\n\t\t\t\tnewShape.index = index\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\n\t\t\treturn newShape\n\t\t})\n\n\t\tif (newShapes.length + this.getCurrentPageShapeIds().size > this.options.maxShapesPerPage) {\n\t\t\t// There's some complexity here involving children\n\t\t\t// that might be created without their parents, so\n\t\t\t// if we're going over the limit then just don't paste.\n\t\t\talertMaxShapes(this)\n\t\t\treturn this\n\t\t}\n\n\t\tconst newBindings = bindings.map(\n\t\t\t(oldBinding): TLBinding => ({\n\t\t\t\t...oldBinding,\n\t\t\t\tid: assertExists(bindingIdMap.get(oldBinding.id)),\n\t\t\t\tfromId: assertExists(shapeIdMap.get(oldBinding.fromId)),\n\t\t\t\ttoId: assertExists(shapeIdMap.get(oldBinding.toId)),\n\t\t\t})\n\t\t)\n\n\t\t// These are all the assets we need to create\n\t\tconst assetsToCreate: TLAsset[] = []\n\n\t\t// These assets have base64 data that may need to be hosted\n\t\tconst assetsToUpdate: (TLImageAsset | TLVideoAsset)[] = []\n\n\t\tfor (const asset of assets) {\n\t\t\tif (this.store.has(asset.id)) {\n\t\t\t\t// We already have this asset\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\t(asset.type === 'image' && asset.props.src?.startsWith('data:image')) ||\n\t\t\t\t(asset.type === 'video' && asset.props.src?.startsWith('data:video'))\n\t\t\t) {\n\t\t\t\t// it's src is a base64 image or video; we need to create a new asset without the src,\n\t\t\t\t// then create a new asset from the original src. So we save a copy of the original asset,\n\t\t\t\t// then delete the src from the original asset.\n\t\t\t\tassetsToUpdate.push(structuredClone(asset as TLImageAsset | TLVideoAsset))\n\t\t\t\tasset.props.src = null\n\t\t\t}\n\n\t\t\t// Add the asset to the list of assets to create\n\t\t\tassetsToCreate.push(asset)\n\t\t}\n\n\t\t// Start loading the new assets, order does not matter\n\t\tPromise.allSettled(\n\t\t\t(assetsToUpdate as (TLImageAsset | TLVideoAsset)[]).map(async (asset) => {\n\t\t\t\t// Turn the data url into a file\n\t\t\t\tconst file = await dataUrlToFile(\n\t\t\t\t\tasset.props.src!,\n\t\t\t\t\tasset.props.name,\n\t\t\t\t\tasset.props.mimeType ?? 'image/png'\n\t\t\t\t)\n\n\t\t\t\t// Get a new asset for the file\n\t\t\t\tconst newAsset = await this.getAssetForExternalContent({\n\t\t\t\t\ttype: 'file',\n\t\t\t\t\tfile,\n\t\t\t\t\tassetId: asset.id,\n\t\t\t\t})\n\n\t\t\t\tif (!newAsset) {\n\t\t\t\t\t// If we don't have a new asset, delete the old asset.\n\t\t\t\t\t// The shapes that reference this asset should break.\n\t\t\t\t\tthis.deleteAssets([asset.id])\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Save the new asset under the old asset's id\n\t\t\t\tthis.updateAssets([{ ...newAsset, id: asset.id }])\n\t\t\t})\n\t\t)\n\n\t\tthis.run(() => {\n\t\t\t// Create any assets that need to be created\n\t\t\tif (assetsToCreate.length > 0) {\n\t\t\t\tthis.createAssets(assetsToCreate)\n\t\t\t}\n\n\t\t\t// Create the shapes with root shapes as children of the page\n\t\t\tthis.createShapes(newShapes)\n\t\t\tthis.createBindings(newBindings)\n\n\t\t\tif (select) {\n\t\t\t\tthis.select(...rootShapes.map((s) => s.id))\n\t\t\t}\n\n\t\t\t// And then, if needed, reparent the root shapes to the paste parent\n\t\t\tif (pasteParentId !== currentPageId) {\n\t\t\t\tthis.reparentShapes(\n\t\t\t\t\trootShapes.map((s) => s.id),\n\t\t\t\t\tpasteParentId\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst newCreatedShapes = newShapes.map((s) => this.getShape(s.id)!)\n\t\t\tconst bounds = Box.Common(newCreatedShapes.map((s) => this.getShapePageBounds(s)!))\n\n\t\t\tif (point === undefined) {\n\t\t\t\tif (!isPageId(pasteParentId)) {\n\t\t\t\t\t// Put the shapes in the middle of the (on screen) parent\n\t\t\t\t\tconst shape = this.getShape(pasteParentId)!\n\t\t\t\t\tpoint = Mat.applyToPoint(\n\t\t\t\t\t\tthis.getShapePageTransform(shape),\n\t\t\t\t\t\tthis.getShapeGeometry(shape).bounds.center\n\t\t\t\t\t)\n\t\t\t\t} else {\n\t\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\t\tif (preservePosition || viewportPageBounds.includes(Box.From(bounds))) {\n\t\t\t\t\t\t// Otherwise, put shapes where they used to be\n\t\t\t\t\t\tpoint = bounds.center\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If the old bounds are outside of the viewport...\n\t\t\t\t\t\t// put the shapes in the middle of the viewport\n\t\t\t\t\t\tpoint = viewportPageBounds.center\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rootShapes.length === 1) {\n\t\t\t\tconst onlyRoot = rootShapes[0] as TLFrameShape\n\t\t\t\t// If the old bounds are in the viewport...\n\t\t\t\t// todo: replace frame references with shapes that can accept children\n\t\t\t\tif (this.isShapeOfType<TLFrameShape>(onlyRoot, 'frame')) {\n\t\t\t\t\twhile (\n\t\t\t\t\t\tthis.getShapesAtPoint(point).some(\n\t\t\t\t\t\t\t(shape) =>\n\t\t\t\t\t\t\t\tthis.isShapeOfType<TLFrameShape>(shape, 'frame') &&\n\t\t\t\t\t\t\t\tshape.props.w === onlyRoot.props.w &&\n\t\t\t\t\t\t\t\tshape.props.h === onlyRoot.props.h\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tpoint.x += bounds.w + 16\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst pageCenter = Box.Common(\n\t\t\t\tcompact(rootShapes.map(({ id }) => this.getShapePageBounds(id)))\n\t\t\t).center\n\n\t\t\tconst offset = Vec.Sub(point, pageCenter)\n\n\t\t\tthis.updateShapes(\n\t\t\t\trootShapes.map(({ id }) => {\n\t\t\t\t\tconst s = this.getShape(id)!\n\t\t\t\t\tconst localRotation = this.getShapeParentTransform(id).decompose().rotation\n\t\t\t\t\tconst localDelta = Vec.Rot(offset, -localRotation)\n\n\t\t\t\t\treturn { id: s.id, type: s.type, x: s.x + localDelta.x, y: s.y + localDelta.y }\n\t\t\t\t})\n\t\t\t)\n\t\t})\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Get an exported SVG element of the given shapes.\n\t *\n\t * @param shapes - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgElement(shapes: TLShapeId[] | TLShape[], opts: TLSvgExportOptions = {}) {\n\t\tconst ids =\n\t\t\tshapes.length === 0\n\t\t\t\t? this.getCurrentPageShapeIdsSorted()\n\t\t\t\t: typeof shapes[0] === 'string'\n\t\t\t\t\t? (shapes as TLShapeId[])\n\t\t\t\t\t: (shapes as TLShape[]).map((s) => s.id)\n\n\t\tif (ids.length === 0) return undefined\n\n\t\treturn exportToSvg(this, ids, opts)\n\t}\n\n\t/**\n\t * Get an exported SVG string of the given shapes.\n\t *\n\t * @param shapes - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns The SVG element.\n\t *\n\t * @public\n\t */\n\tasync getSvgString(shapes: TLShapeId[] | TLShape[], opts: TLSvgExportOptions = {}) {\n\t\tconst result = await this.getSvgElement(shapes, opts)\n\t\tif (!result) return undefined\n\n\t\tconst serializer = new XMLSerializer()\n\t\treturn {\n\t\t\tsvg: serializer.serializeToString(result.svg),\n\t\t\twidth: result.width,\n\t\t\theight: result.height,\n\t\t}\n\t}\n\n\t/**\n\t * Get an exported image of the given shapes.\n\t *\n\t * @param shapes - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns A blob of the image.\n\t * @public\n\t */\n\tasync toImage(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst withDefaults = {\n\t\t\tformat: 'png',\n\t\t\tscale: 1,\n\t\t\tpixelRatio: opts.format === 'svg' ? undefined : 2,\n\t\t\t...opts,\n\t\t} satisfies TLImageExportOptions\n\t\tconst result = await this.getSvgString(shapes, withDefaults)\n\t\tif (!result) throw new Error('Could not create SVG')\n\n\t\tswitch (withDefaults.format) {\n\t\t\tcase 'svg':\n\t\t\t\treturn {\n\t\t\t\t\tblob: new Blob([result.svg], { type: 'image/svg+xml' }),\n\t\t\t\t\twidth: result.width,\n\t\t\t\t\theight: result.height,\n\t\t\t\t}\n\t\t\tcase 'jpeg':\n\t\t\tcase 'png':\n\t\t\tcase 'webp': {\n\t\t\t\tconst blob = await getSvgAsImage(result.svg, {\n\t\t\t\t\ttype: withDefaults.format,\n\t\t\t\t\tquality: withDefaults.quality,\n\t\t\t\t\tpixelRatio: withDefaults.pixelRatio,\n\t\t\t\t\twidth: result.width,\n\t\t\t\t\theight: result.height,\n\t\t\t\t})\n\t\t\t\tif (!blob) {\n\t\t\t\t\tthrow new Error('Could not construct image.')\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tblob,\n\t\t\t\t\twidth: result.width,\n\t\t\t\t\theight: result.height,\n\t\t\t\t}\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\texhaustiveSwitchError(withDefaults.format)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get an exported image of the given shapes as a data URL.\n\t *\n\t * @param shapes - The shapes (or shape ids) to export.\n\t * @param opts - Options for the export.\n\t *\n\t * @returns A data URL of the image.\n\t * @public\n\t */\n\tasync toImageDataUrl(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {\n\t\tconst { blob, width, height } = await this.toImage(shapes, opts)\n\t\treturn {\n\t\t\turl: await FileHelpers.blobToDataUrl(blob),\n\t\t\twidth,\n\t\t\theight,\n\t\t}\n\t}\n\n\t/* --------------------- Events --------------------- */\n\n\t/**\n\t * The app's current input state.\n\t *\n\t * @public\n\t */\n\tinputs = {\n\t\t/** The most recent pointer down's position in the current page space. */\n\t\toriginPagePoint: new Vec(),\n\t\t/** The most recent pointer down's position in screen space. */\n\t\toriginScreenPoint: new Vec(),\n\t\t/** The previous pointer position in the current page space. */\n\t\tpreviousPagePoint: new Vec(),\n\t\t/** The previous pointer position in screen space. */\n\t\tpreviousScreenPoint: new Vec(),\n\t\t/** The most recent pointer position in the current page space. */\n\t\tcurrentPagePoint: new Vec(),\n\t\t/** The most recent pointer position in screen space. */\n\t\tcurrentScreenPoint: new Vec(),\n\t\t/** A set containing the currently pressed keys. */\n\t\tkeys: new Set<string>(),\n\t\t/** A set containing the currently pressed buttons. */\n\t\tbuttons: new Set<number>(),\n\t\t/** Whether the input is from a pe. */\n\t\tisPen: false,\n\t\t/** Whether the shift key is currently pressed. */\n\t\tshiftKey: false,\n\t\t/** Whether the meta key is currently pressed. */\n\t\tmetaKey: false,\n\t\t/** Whether the control or command key is currently pressed. */\n\t\tctrlKey: false,\n\t\t/** Whether the alt or option key is currently pressed. */\n\t\taltKey: false,\n\t\t/** Whether the user is dragging. */\n\t\tisDragging: false,\n\t\t/** Whether the user is pointing. */\n\t\tisPointing: false,\n\t\t/** Whether the user is pinching. */\n\t\tisPinching: false,\n\t\t/** Whether the user is editing. */\n\t\tisEditing: false,\n\t\t/** Whether the user is panning. */\n\t\tisPanning: false,\n\t\t/** Whether the user is spacebar panning. */\n\t\tisSpacebarPanning: false,\n\t\t/** Velocity of mouse pointer, in pixels per millisecond */\n\t\tpointerVelocity: new Vec(),\n\t}\n\n\t/**\n\t * Update the input points from a pointer, pinch, or wheel event.\n\t *\n\t * @param info - The event info.\n\t */\n\tprivate _updateInputsFromEvent(\n\t\tinfo: TLPointerEventInfo | TLPinchEventInfo | TLWheelEventInfo\n\t): void {\n\t\tconst {\n\t\t\tpointerVelocity,\n\t\t\tpreviousScreenPoint,\n\t\t\tpreviousPagePoint,\n\t\t\tcurrentScreenPoint,\n\t\t\tcurrentPagePoint,\n\t\t\toriginScreenPoint,\n\t\t\toriginPagePoint,\n\t\t} = this.inputs\n\n\t\tconst { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\tconst sx = info.point.x - screenBounds.x\n\t\tconst sy = info.point.y - screenBounds.y\n\t\tconst sz = info.point.z ?? 0.5\n\n\t\tpreviousScreenPoint.setTo(currentScreenPoint)\n\t\tpreviousPagePoint.setTo(currentPagePoint)\n\n\t\t// The \"screen bounds\" is relative to the user's actual screen.\n\t\t// The \"screen point\" is relative to the \"screen bounds\";\n\t\t// it will be 0,0 when its actual screen position is equal\n\t\t// to screenBounds.point. This is confusing!\n\t\tcurrentScreenPoint.set(sx, sy)\n\t\tconst nx = sx / cz - cx\n\t\tconst ny = sy / cz - cy\n\t\tif (isFinite(nx) && isFinite(ny)) {\n\t\t\tcurrentPagePoint.set(nx, ny, sz)\n\t\t}\n\n\t\tthis.inputs.isPen = info.type === 'pointer' && info.isPen\n\n\t\t// Reset velocity on pointer down, or when a pinch starts or ends\n\t\tif (info.name === 'pointer_down' || this.inputs.isPinching) {\n\t\t\tpointerVelocity.set(0, 0)\n\t\t\toriginScreenPoint.setTo(currentScreenPoint)\n\t\t\toriginPagePoint.setTo(currentPagePoint)\n\t\t}\n\n\t\t// todo: We only have to do this if there are multiple users in the document\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\tthis.store.put([\n\t\t\t\t\t{\n\t\t\t\t\t\tid: TLPOINTER_ID,\n\t\t\t\t\t\ttypeName: 'pointer',\n\t\t\t\t\t\tx: currentPagePoint.x,\n\t\t\t\t\t\ty: currentPagePoint.y,\n\t\t\t\t\t\tlastActivityTimestamp:\n\t\t\t\t\t\t\t// If our pointer moved only because we're following some other user, then don't\n\t\t\t\t\t\t\t// update our last activity timestamp; otherwise, update it to the current timestamp.\n\t\t\t\t\t\t\tinfo.type === 'pointer' && info.pointerId === INTERNAL_POINTER_IDS.CAMERA_MOVE\n\t\t\t\t\t\t\t\t? (this.store.unsafeGetWithoutCapture(TLPOINTER_ID)?.lastActivityTimestamp ??\n\t\t\t\t\t\t\t\t\tthis._tickManager.now)\n\t\t\t\t\t\t\t\t: this._tickManager.now,\n\t\t\t\t\t\tmeta: {},\n\t\t\t\t\t},\n\t\t\t\t])\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\t}\n\n\t/**\n\t * Dispatch a cancel event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.cancel()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcancel(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'cancel' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch an interrupt event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.interrupt()\n\t * ```\n\t *\n\t * @public\n\t */\n\tinterrupt(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'interrupt' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch a complete event.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.complete()\n\t * ```\n\t *\n\t * @public\n\t */\n\tcomplete(): this {\n\t\tthis.dispatch({ type: 'misc', name: 'complete' })\n\t\treturn this\n\t}\n\n\t/**\n\t * Dispatch a pointer move event in the current position of the pointer. This is useful when\n\t * external circumstances have changed (e.g. the camera moved or a shape was moved) and you want\n\t * the current interaction to respond to that change.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.updatePointer()\n\t * ```\n\t *\n\t * @param options - The options for updating the pointer.\n\t * @returns The editor instance.\n\t * @public\n\t */\n\tupdatePointer(options?: TLUpdatePointerOptions): this {\n\t\tconst event: TLPointerEventInfo = {\n\t\t\ttype: 'pointer',\n\t\t\ttarget: 'canvas',\n\t\t\tname: 'pointer_move',\n\t\t\tpoint:\n\t\t\t\toptions?.point ??\n\t\t\t\t// weird but true: what `inputs` calls screen-space is actually viewport space. so\n\t\t\t\t// we need to convert back into true screen space first. we should fix this...\n\t\t\t\tVec.Add(\n\t\t\t\t\tthis.inputs.currentScreenPoint,\n\t\t\t\t\tthis.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!.screenBounds\n\t\t\t\t),\n\t\t\tpointerId: options?.pointerId ?? 0,\n\t\t\tbutton: options?.button ?? 0,\n\t\t\tisPen: options?.isPen ?? this.inputs.isPen,\n\t\t\tshiftKey: options?.shiftKey ?? this.inputs.shiftKey,\n\t\t\taltKey: options?.altKey ?? this.inputs.altKey,\n\t\t\tctrlKey: options?.ctrlKey ?? this.inputs.ctrlKey,\n\t\t\tmetaKey: options?.metaKey ?? this.inputs.metaKey,\n\t\t\taccelKey: options?.accelKey ?? isAccelKey(this.inputs),\n\t\t}\n\n\t\tif (options?.immediate) {\n\t\t\tthis._flushEventForTick(event)\n\t\t} else {\n\t\t\tthis.dispatch(event)\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/**\n\t * Puts the editor into focused mode.\n\t *\n\t * This makes the editor eligible to receive keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus()\n\t * ```\n\t *\n\t * By default this also dispatches a 'focus' event to the container element. To prevent this, pass `focusContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.focus({ focusContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tfocus({ focusContainer = true } = {}): this {\n\t\tif (this.getIsFocused()) return this\n\t\tif (focusContainer) this.focusManager.focus()\n\t\tthis.updateInstanceState({ isFocused: true })\n\t\treturn this\n\t}\n\n\t/**\n\t * Switches off the editor's focused mode.\n\t *\n\t * This makes the editor ignore keyboard events and some pointer events (move, wheel).\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur()\n\t * ```\n\t * By default this also dispatches a 'blur' event to the container element. To prevent this, pass `blurContainer: false`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.blur({ blurContainer: false })\n\t * ```\n\t *\n\t * @public\n\t */\n\tblur({ blurContainer = true } = {}): this {\n\t\tif (!this.getIsFocused()) return this\n\t\tif (blurContainer) {\n\t\t\tthis.focusManager.blur()\n\t\t} else {\n\t\t\tthis.complete() // stop any interaction\n\t\t}\n\t\tthis.updateInstanceState({ isFocused: false })\n\t\treturn this\n\t}\n\n\t/**\n\t * @public\n\t * @returns true if the editor is focused\n\t */\n\t@computed getIsFocused() {\n\t\treturn this.getInstanceState().isFocused\n\t}\n\n\t/**\n\t * @public\n\t * @returns true if the editor is in readonly mode\n\t */\n\t@computed getIsReadonly() {\n\t\treturn this.getInstanceState().isReadonly\n\t}\n\n\t/**\n\t * @public\n\t * @returns a snapshot of the store's UI and document state\n\t */\n\tgetSnapshot() {\n\t\treturn getSnapshot(this.store)\n\t}\n\n\t/**\n\t * Loads a snapshot into the editor.\n\t * @param snapshot - The snapshot to load.\n\t * @param opts - The options for loading the snapshot.\n\t * @returns\n\t */\n\tloadSnapshot(\n\t\tsnapshot: Partial<TLEditorSnapshot> | TLStoreSnapshot,\n\t\topts?: TLLoadSnapshotOptions\n\t) {\n\t\tloadSnapshot(this.store, snapshot, opts)\n\t\treturn this\n\t}\n\n\tprivate _zoomToFitPageContentAt100Percent() {\n\t\tconst bounds = this.getCurrentPageBounds()\n\t\tif (bounds) {\n\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t}\n\t}\n\tprivate _navigateToDeepLink(deepLink: TLDeepLink) {\n\t\tthis.run(() => {\n\t\t\tswitch (deepLink.type) {\n\t\t\t\tcase 'page': {\n\t\t\t\t\tconst page = this.getPage(deepLink.pageId)\n\t\t\t\t\tif (page) {\n\t\t\t\t\t\tthis.setCurrentPage(page)\n\t\t\t\t\t}\n\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'shapes': {\n\t\t\t\t\tconst allShapes = compact(deepLink.shapeIds.map((id) => this.getShape(id)))\n\t\t\t\t\tconst byPage: { [pageId: string]: TLShape[] } = {}\n\t\t\t\t\tfor (const shape of allShapes) {\n\t\t\t\t\t\tconst pageId = this.getAncestorPageId(shape)\n\t\t\t\t\t\tif (!pageId) continue\n\t\t\t\t\t\tbyPage[pageId] ??= []\n\t\t\t\t\t\tbyPage[pageId].push(shape)\n\t\t\t\t\t}\n\t\t\t\t\tconst [pageId, shapes] = Object.entries(byPage).sort(\n\t\t\t\t\t\t([_, a], [__, b]) => b.length - a.length\n\t\t\t\t\t)[0] ?? ['', []]\n\n\t\t\t\t\tif (!pageId || !shapes.length) {\n\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.setCurrentPage(pageId as TLPageId)\n\t\t\t\t\t\tconst bounds = Box.Common(shapes.map((s) => this.getShapePageBounds(s)!))\n\t\t\t\t\t\tthis.zoomToBounds(bounds, { immediate: true, targetZoom: this.getBaseZoom() })\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcase 'viewport': {\n\t\t\t\t\tif (deepLink.pageId) {\n\t\t\t\t\t\tif (!this.getPage(deepLink.pageId)) {\n\t\t\t\t\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.setCurrentPage(deepLink.pageId)\n\t\t\t\t\t}\n\t\t\t\t\tthis.zoomToBounds(deepLink.bounds, { immediate: true, inset: 0 })\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(deepLink)\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Handles navigating to the content specified by the query param in the given URL.\n\t *\n\t * Use {@link Editor#createDeepLink} to create a URL with a deep link query param.\n\t *\n\t * If no URL is provided, it will look for the param in the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.navigateToDeepLink()\n\t * ```\n\t *\n\t * The default parameter name is 'd'. You can override this by providing the `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * // disable page parameter and change viewport parameter to 'c'\n\t * editor.navigateToDeepLink({\n\t * param: 'x',\n\t * url: 'https://my-app.com/my-document?x=200.12.454.23.xyz123',\n\t * })\n\t * ```\n\t *\n\t * @param opts - Options for loading the state from the URL.\n\t */\n\tnavigateToDeepLink(opts?: TLDeepLink | { url?: string | URL; param?: string }): Editor {\n\t\tif (opts && 'type' in opts) {\n\t\t\tthis._navigateToDeepLink(opts)\n\t\t\treturn this\n\t\t}\n\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\t\tconst deepLinkString = url.searchParams.get(opts?.param ?? 'd')\n\n\t\tif (!deepLinkString) {\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t\treturn this\n\t\t}\n\n\t\ttry {\n\t\t\tthis._navigateToDeepLink(parseDeepLinkString(deepLinkString))\n\t\t} catch (e) {\n\t\t\tconsole.warn(e)\n\t\t\tthis._zoomToFitPageContentAt100Percent()\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Turns the given URL into a deep link by adding a query parameter.\n\t *\n\t * e.g. `https://my-app.com/my-document?d=100.100.200.200.xyz123`\n\t *\n\t * If no URL is provided, it will use the current `window.location.href`.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the current page + viewport\n\t * navigator.clipboard.writeText(editor.createDeepLink())\n\t * ```\n\t *\n\t * You can link to a particular set of shapes by providing a `to` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // create a deep link to the set of currently selected shapes\n\t * navigator.clipboard.writeText(editor.createDeepLink({\n\t * to: { type: 'selection', shapeIds: editor.getSelectedShapeIds() }\n\t * }))\n\t * ```\n\t *\n\t * The default query param is 'd'. You can override this by providing a `param` parameter.\n\t *\n\t * @example\n\t * ```ts\n\t * // Use `x` as the param name instead\n\t * editor.createDeepLink({ param: 'x' })\n\t * ```\n\t *\n\t * @param opts - Options for adding the state to the URL.\n\t * @returns the updated URL\n\t */\n\tcreateDeepLink(opts?: { url?: string | URL; param?: string; to?: TLDeepLink }): URL {\n\t\tconst url = new URL(opts?.url ?? window.location.href)\n\n\t\turl.searchParams.set(\n\t\t\topts?.param ?? 'd',\n\t\t\tcreateDeepLinkString(\n\t\t\t\topts?.to ?? {\n\t\t\t\t\ttype: 'viewport',\n\t\t\t\t\tpageId: this.options.maxPages === 1 ? undefined : this.getCurrentPageId(),\n\t\t\t\t\tbounds: this.getViewportPageBounds(),\n\t\t\t\t}\n\t\t\t)\n\t\t)\n\n\t\treturn url\n\t}\n\n\t/**\n\t * Register a listener for changes to a deep link for the current document.\n\t *\n\t * You'll typically want to use this indirectly via the {@link TldrawEditorBaseProps.deepLinks} prop on the `<Tldraw />` component.\n\t *\n\t * By default this will update `window.location` in place, but you can provide a custom callback\n\t * to handle state changes on your own.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * onChange(url) {\n\t * window.history.replaceState({}, document.title, url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * You can also provide a custom URL to update, in which case you must also provide `onChange`.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({\n\t * getUrl: () => `https://my-app.com/my-document`,\n\t * onChange(url) {\n\t * setShareUrl(url.toString())\n\t * }\n\t * })\n\t * ```\n\t *\n\t * By default this will update with a debounce interval of 500ms, but you can provide a custom interval.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ debounceMs: 1000 })\n\t * ```\n\t * The default parameter name is `d`. You can override this by providing a `param` option.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.registerDeepLinkListener({ param: 'x' })\n\t * ```\n\t * @param opts - Options for setting up the listener.\n\t * @returns a function that will stop the listener.\n\t */\n\tregisterDeepLinkListener(opts?: TLDeepLinkOptions): () => void {\n\t\tif (opts?.getUrl && !opts?.onChange) {\n\t\t\tthrow Error(\n\t\t\t\t'[tldraw:urlStateSync] If you specify getUrl, you must also specify the onChange callback.'\n\t\t\t)\n\t\t}\n\n\t\tconst url$ = computed('url with state', () => {\n\t\t\tconst url = opts?.getUrl?.(this) ?? window.location.href\n\t\t\tconst urlWithState = this.createDeepLink({\n\t\t\t\tparam: opts?.param,\n\t\t\t\turl,\n\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t})\n\t\t\treturn urlWithState.toString()\n\t\t})\n\n\t\tconst announceChange =\n\t\t\topts?.onChange ??\n\t\t\t(() => {\n\t\t\t\tconst url = this.createDeepLink({\n\t\t\t\t\tparam: opts?.param,\n\t\t\t\t\tto: opts?.getTarget?.(this),\n\t\t\t\t})\n\n\t\t\t\twindow.history.replaceState({}, document.title, url.toString())\n\t\t\t})\n\n\t\tconst scheduleEffect = debounce((execute: () => void) => execute(), opts?.debounceMs ?? 500)\n\n\t\tconst unlisten = react(\n\t\t\t'update url on state change',\n\t\t\t() => announceChange(new URL(url$.get()), this),\n\t\t\t{ scheduleEffect }\n\t\t)\n\n\t\treturn () => {\n\t\t\tunlisten()\n\t\t\tscheduleEffect.cancel()\n\t\t}\n\t}\n\n\t/**\n\t * A manager for recording multiple click events.\n\t *\n\t * @internal\n\t */\n\tprotected _clickManager = new ClickManager(this)\n\n\t/**\n\t * Prevent a double click event from firing the next time the user clicks\n\t *\n\t * @public\n\t */\n\tcancelDoubleClick() {\n\t\tthis._clickManager.cancelDoubleClickTimeout()\n\t}\n\n\t/**\n\t * The previous cursor. Used for restoring the cursor after pan events.\n\t *\n\t * @internal\n\t */\n\tprivate _prevCursor: TLCursorType = 'default'\n\n\t/** @internal */\n\tprivate _shiftKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setShiftKeyTimeout() {\n\t\tthis.inputs.shiftKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Shift',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'ShiftLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _altKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setAltKeyTimeout() {\n\t\tthis.inputs.altKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Alt',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'AltLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _ctrlKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setCtrlKeyTimeout() {\n\t\tthis.inputs.ctrlKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Ctrl',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'ControlLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _metaKeyTimeout = -1 as any\n\n\t/** @internal */\n\t@bind\n\t_setMetaKeyTimeout() {\n\t\tthis.inputs.metaKey = false\n\t\tthis.dispatch({\n\t\t\ttype: 'keyboard',\n\t\t\tname: 'key_up',\n\t\t\tkey: 'Meta',\n\t\t\tshiftKey: this.inputs.shiftKey,\n\t\t\tctrlKey: this.inputs.ctrlKey,\n\t\t\taltKey: this.inputs.altKey,\n\t\t\tmetaKey: this.inputs.metaKey,\n\t\t\taccelKey: isAccelKey(this.inputs),\n\t\t\tcode: 'MetaLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _restoreToolId = 'select'\n\n\t/** @internal */\n\tprivate _pinchStart = 1\n\n\t/** @internal */\n\tprivate _didPinch = false\n\n\t/** @internal */\n\tprivate _selectedShapeIdsAtPointerDown: TLShapeId[] = []\n\n\t/** @internal */\n\tprivate _longPressTimeout = -1 as any\n\n\t/** @internal */\n\tcapturedPointerId: number | null = null\n\n\t/** @internal */\n\tprivate readonly performanceTracker: PerformanceTracker\n\n\t/** @internal */\n\tprivate performanceTrackerTimeout = -1 as any\n\n\t/** @internal */\n\tprivate handledEvents = new WeakSet<Event>()\n\n\t/**\n\t * In tldraw, events are sometimes handled by multiple components. For example, the shapes might\n\t * have events, but the canvas handles events too. The way that the canvas handles events can\n\t * interfere with the with the shapes event handlers - for example, it calls `.preventDefault()`\n\t * on `pointerDown`, which also prevents `click` events from firing on the shapes.\n\t *\n\t * You can use `.stopPropagation()` to prevent the event from propagating to the rest of the\n\t * DOM, but that can impact non-tldraw event handlers set up elsewhere. By using\n\t * `markEventAsHandled`, you'll stop other parts of tldraw from handling the event without\n\t * impacting other, non-tldraw event handlers. See also {@link Editor.wasEventAlreadyHandled}.\n\t *\n\t * @public\n\t */\n\tmarkEventAsHandled(e: Event | { nativeEvent: Event }) {\n\t\tconst nativeEvent = 'nativeEvent' in e ? e.nativeEvent : e\n\t\tthis.handledEvents.add(nativeEvent)\n\t}\n\n\t/**\n\t * Checks if an event has already been handled. See {@link Editor.markEventAsHandled}.\n\t *\n\t * @public\n\t */\n\twasEventAlreadyHandled(e: Event | { nativeEvent: Event }) {\n\t\tconst nativeEvent = 'nativeEvent' in e ? e.nativeEvent : e\n\t\treturn this.handledEvents.has(nativeEvent)\n\t}\n\n\t/**\n\t * Dispatch an event to the editor.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.dispatch(myPointerEvent)\n\t * ```\n\t *\n\t * @param info - The event info.\n\t *\n\t * @public\n\t */\n\tdispatch(info: TLEventInfo) {\n\t\tthis._pendingEventsForNextTick.push(info)\n\t\tif (\n\t\t\t!(\n\t\t\t\t(info.type === 'pointer' && info.name === 'pointer_move') ||\n\t\t\t\tinfo.type === 'wheel' ||\n\t\t\t\tinfo.type === 'pinch'\n\t\t\t)\n\t\t) {\n\t\t\tthis._flushEventsForTick(0)\n\t\t}\n\t\treturn this\n\t}\n\n\tprivate _pendingEventsForNextTick: TLEventInfo[] = []\n\n\tprivate _flushEventsForTick(elapsed: number) {\n\t\tthis.run(() => {\n\t\t\tif (this._pendingEventsForNextTick.length > 0) {\n\t\t\t\tconst events = [...this._pendingEventsForNextTick]\n\t\t\t\tthis._pendingEventsForNextTick.length = 0\n\t\t\t\tfor (const info of events) {\n\t\t\t\t\tthis._flushEventForTick(info)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (elapsed > 0) {\n\t\t\t\tthis.root.handleEvent({ type: 'misc', name: 'tick', elapsed })\n\t\t\t}\n\t\t\tthis.scribbles.tick(elapsed)\n\t\t})\n\t}\n\n\t_flushEventForTick(info: TLEventInfo) {\n\t\t// prevent us from spamming similar event errors if we're crashed.\n\t\t// todo: replace with new readonly mode?\n\t\tif (this.getCrashingError()) return this\n\n\t\tthis.emit('before-event', info)\n\n\t\tconst { inputs } = this\n\t\tconst { type } = info\n\n\t\tif (info.type === 'misc') {\n\t\t\t// stop panning if the interaction is cancelled or completed\n\t\t\tif (info.name === 'cancel' || info.name === 'complete') {\n\t\t\t\tthis.inputs.isDragging = false\n\n\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.root.handleEvent(info)\n\t\t\treturn\n\t\t}\n\n\t\tif (info.shiftKey) {\n\t\t\tclearTimeout(this._shiftKeyTimeout)\n\t\t\tthis._shiftKeyTimeout = -1\n\t\t\tinputs.shiftKey = true\n\t\t} else if (!info.shiftKey && inputs.shiftKey && this._shiftKeyTimeout === -1) {\n\t\t\tthis._shiftKeyTimeout = this.timers.setTimeout(this._setShiftKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.altKey) {\n\t\t\tclearTimeout(this._altKeyTimeout)\n\t\t\tthis._altKeyTimeout = -1\n\t\t\tinputs.altKey = true\n\t\t} else if (!info.altKey && inputs.altKey && this._altKeyTimeout === -1) {\n\t\t\tthis._altKeyTimeout = this.timers.setTimeout(this._setAltKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.ctrlKey) {\n\t\t\tclearTimeout(this._ctrlKeyTimeout)\n\t\t\tthis._ctrlKeyTimeout = -1\n\t\t\tinputs.ctrlKey = true\n\t\t} else if (!info.ctrlKey && inputs.ctrlKey && this._ctrlKeyTimeout === -1) {\n\t\t\tthis._ctrlKeyTimeout = this.timers.setTimeout(this._setCtrlKeyTimeout, 150)\n\t\t}\n\n\t\tif (info.metaKey) {\n\t\t\tclearTimeout(this._metaKeyTimeout)\n\t\t\tthis._metaKeyTimeout = -1\n\t\t\tinputs.metaKey = true\n\t\t} else if (!info.metaKey && inputs.metaKey && this._metaKeyTimeout === -1) {\n\t\t\tthis._metaKeyTimeout = this.timers.setTimeout(this._setMetaKeyTimeout, 150)\n\t\t}\n\n\t\tconst { originPagePoint, currentPagePoint } = inputs\n\n\t\tif (!inputs.isPointing) {\n\t\t\tinputs.isDragging = false\n\t\t}\n\n\t\tconst instanceState = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\tconst pageState = this.store.get(this._getCurrentPageStateId())!\n\t\tconst cameraOptions = this._cameraOptions.__unsafe__getWithoutCapture()!\n\n\t\tswitch (type) {\n\t\t\tcase 'pinch': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pinch_start': {\n\t\t\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\t\t\tif (!inputs.isEditing) {\n\t\t\t\t\t\t\tthis._pinchStart = this.getCamera().z\n\t\t\t\t\t\t\tif (!this._selectedShapeIdsAtPointerDown.length) {\n\t\t\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds]\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis._didPinch = true\n\n\t\t\t\t\t\t\tinputs.isPinching = true\n\n\t\t\t\t\t\t\tthis.interrupt()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch': {\n\t\t\t\t\t\tif (!inputs.isPinching) return\n\n\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\tpoint: { z = 1 },\n\t\t\t\t\t\t\tdelta: { x: dx, y: dy },\n\t\t\t\t\t\t} = info\n\n\t\t\t\t\t\t// The center of the pinch in screen space\n\t\t\t\t\t\tconst { x, y } = Vec.SubXY(\n\t\t\t\t\t\t\tinfo.point,\n\t\t\t\t\t\t\tinstanceState.screenBounds.x,\n\t\t\t\t\t\t\tinstanceState.screenBounds.y\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\tconst { panSpeed } = cameraOptions\n\t\t\t\t\t\tthis._setCamera(\n\t\t\t\t\t\t\tnew Vec(\n\t\t\t\t\t\t\t\tcx + (dx * panSpeed) / cz - x / cz + x / z,\n\t\t\t\t\t\t\t\tcy + (dy * panSpeed) / cz - y / cz + y / z,\n\t\t\t\t\t\t\t\tz\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t{ immediate: true }\n\t\t\t\t\t\t)\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pinch_end': {\n\t\t\t\t\t\tif (!inputs.isPinching) return this\n\n\t\t\t\t\t\t// Stop pinching\n\t\t\t\t\t\tinputs.isPinching = false\n\n\t\t\t\t\t\t// Stash and clear the shapes that were selected when the pinch started\n\t\t\t\t\t\tconst { _selectedShapeIdsAtPointerDown: shapesToReselect } = this\n\t\t\t\t\t\tthis.setSelectedShapes(this._selectedShapeIdsAtPointerDown)\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = []\n\n\t\t\t\t\t\tif (this._didPinch) {\n\t\t\t\t\t\t\tthis._didPinch = false\n\t\t\t\t\t\t\tif (shapesToReselect.length > 0) {\n\t\t\t\t\t\t\t\tthis.once('tick', () => {\n\t\t\t\t\t\t\t\t\tif (!this._didPinch) {\n\t\t\t\t\t\t\t\t\t\t// Unless we've started pinching again...\n\t\t\t\t\t\t\t\t\t\t// Reselect the shapes that were selected when the pinch started\n\t\t\t\t\t\t\t\t\t\tthis.setSelectedShapes(shapesToReselect)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn // Stop here!\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase 'wheel': {\n\t\t\t\tif (cameraOptions.isLocked) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\n\t\t\t\tconst { panSpeed, zoomSpeed } = cameraOptions\n\t\t\t\tlet wheelBehavior = cameraOptions.wheelBehavior\n\t\t\t\tconst inputMode = this.user.getUserPreferences().inputMode\n\n\t\t\t\t// If the user has set their input mode preference, then use that to determine the wheel behavior\n\t\t\t\tif (inputMode !== null) {\n\t\t\t\t\twheelBehavior = inputMode === 'trackpad' ? 'pan' : 'zoom'\n\t\t\t\t}\n\n\t\t\t\tif (wheelBehavior !== 'none') {\n\t\t\t\t\t// Stop any camera animation\n\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t// Stop following any following user\n\t\t\t\t\tif (instanceState.followingUserId) {\n\t\t\t\t\t\tthis.stopFollowingUser()\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\t\t\t\t\tconst { x: dx, y: dy, z: dz = 0 } = info.delta\n\n\t\t\t\t\tlet behavior = wheelBehavior\n\n\t\t\t\t\t// If the camera behavior is \"zoom\" and the ctrl key is pressed, then pan;\n\t\t\t\t\t// If the camera behavior is \"pan\" and the ctrl key is not pressed, then zoom\n\t\t\t\t\tif (info.ctrlKey) behavior = wheelBehavior === 'pan' ? 'zoom' : 'pan'\n\n\t\t\t\t\tswitch (behavior) {\n\t\t\t\t\t\tcase 'zoom': {\n\t\t\t\t\t\t\t// Zoom in on current screen point using the wheel delta\n\t\t\t\t\t\t\tconst { x, y } = this.inputs.currentScreenPoint\n\t\t\t\t\t\t\tlet delta = dz\n\n\t\t\t\t\t\t\t// If we're forcing zoom, then we need to do the wheel normalization math here\n\t\t\t\t\t\t\tif (wheelBehavior === 'zoom') {\n\t\t\t\t\t\t\t\tif (Math.abs(dy) > 10) {\n\t\t\t\t\t\t\t\t\tdelta = (10 * Math.sign(dy)) / 100\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tdelta = dy / 100\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst zoom = cz + (delta ?? 0) * zoomSpeed * cz\n\t\t\t\t\t\t\tthis._setCamera(new Vec(cx + x / zoom - x / cz, cy + y / zoom - y / cz, zoom), {\n\t\t\t\t\t\t\t\timmediate: true,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Zooming')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'pan': {\n\t\t\t\t\t\t\t// Pan the camera based on the wheel delta\n\t\t\t\t\t\t\tthis._setCamera(new Vec(cx + (dx * panSpeed) / cz, cy + (dy * panSpeed) / cz, cz), {\n\t\t\t\t\t\t\t\timmediate: true,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'pointer': {\n\t\t\t\t// Ignore pointer events while we're pinching\n\t\t\t\tif (inputs.isPinching) return\n\n\t\t\t\tthis._updateInputsFromEvent(info)\n\t\t\t\tconst { isPen } = info\n\t\t\t\tconst { isPenMode } = instanceState\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'pointer_down': {\n\t\t\t\t\t\t// If we're in pen mode and the input is not a pen type, then stop here\n\t\t\t\t\t\tif (isPenMode && !isPen) return\n\n\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t// Start a long press timeout\n\t\t\t\t\t\t\tthis._longPressTimeout = this.timers.setTimeout(() => {\n\t\t\t\t\t\t\t\tconst vsb = this.getViewportScreenBounds()\n\t\t\t\t\t\t\t\tthis.dispatch({\n\t\t\t\t\t\t\t\t\t...info,\n\t\t\t\t\t\t\t\t\t// important! non-obvious!! the screenpoint was adjusted using the\n\t\t\t\t\t\t\t\t\t// viewport bounds, and will be again when this event is handled...\n\t\t\t\t\t\t\t\t\t// so we need to counter-adjust from the stored value so that the\n\t\t\t\t\t\t\t\t\t// new value is set correctly.\n\t\t\t\t\t\t\t\t\tpoint: this.inputs.originScreenPoint.clone().addXY(vsb.x, vsb.y),\n\t\t\t\t\t\t\t\t\tname: 'long_press',\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}, this.options.longPressDurationMs)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Save the selected ids at pointer down\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds()\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's a left-mouse-click, we store the pointer id for later user\n\t\t\t\t\t\tif (info.button === LEFT_MOUSE_BUTTON) this.capturedPointerId = info.pointerId\n\n\t\t\t\t\t\t// Add the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.add(info.button)\n\n\t\t\t\t\t\t// Start pointing and stop dragging\n\t\t\t\t\t\tinputs.isPointing = true\n\t\t\t\t\t\tinputs.isDragging = false\n\n\t\t\t\t\t\t// If pen mode is off but we're not already in pen mode, turn that on\n\t\t\t\t\t\tif (!isPenMode && isPen) this.updateInstanceState({ isPenMode: true })\n\n\t\t\t\t\t\t// On devices with erasers (like the Surface Pen or Wacom Pen), button 5 is the eraser\n\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\tthis._restoreToolId = this.getCurrentToolId()\n\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\tthis.setCurrentTool('eraser')\n\t\t\t\t\t\t} else if (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\t\t\t\t// Middle mouse pan activates panning unless we're already panning (with spacebar)\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = this.getInstanceState().cursor.type\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// We might be panning because we did a middle mouse click, or because we're holding spacebar and started a regular click\n\t\t\t\t\t\t// Also stop here, we don't want the state chart to receive the event\n\t\t\t\t\t\tif (this.inputs.isPanning) {\n\t\t\t\t\t\t\tthis.stopCameraAnimation()\n\t\t\t\t\t\t\tthis.setCursor({ type: 'grabbing', rotation: 0 })\n\t\t\t\t\t\t\treturn this\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_move': {\n\t\t\t\t\t\t// If the user is in pen mode, but the pointer is not a pen, stop here.\n\t\t\t\t\t\tif (!isPen && isPenMode) return\n\n\t\t\t\t\t\tconst { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())\n\n\t\t\t\t\t\t// If we've started panning, then clear any long press timeout\n\t\t\t\t\t\tif (this.inputs.isPanning && this.inputs.isPointing) {\n\t\t\t\t\t\t\t// Handle spacebar / middle mouse button panning\n\t\t\t\t\t\t\tconst { currentScreenPoint, previousScreenPoint } = this.inputs\n\t\t\t\t\t\t\tconst offset = Vec.Sub(currentScreenPoint, previousScreenPoint)\n\t\t\t\t\t\t\tthis.setCamera(new Vec(cx + offset.x / cz, cy + offset.y / cz, cz), {\n\t\t\t\t\t\t\t\timmediate: true,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tthis.maybeTrackPerformance('Panning')\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinputs.isPointing &&\n\t\t\t\t\t\t\t!inputs.isDragging &&\n\t\t\t\t\t\t\tVec.Dist2(originPagePoint, currentPagePoint) * this.getZoomLevel() >\n\t\t\t\t\t\t\t\t(instanceState.isCoarsePointer\n\t\t\t\t\t\t\t\t\t? this.options.coarseDragDistanceSquared\n\t\t\t\t\t\t\t\t\t: this.options.dragDistanceSquared) /\n\t\t\t\t\t\t\t\t\tcz\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// Start dragging\n\t\t\t\t\t\t\tinputs.isDragging = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pointer_up': {\n\t\t\t\t\t\t// Stop dragging / pointing\n\t\t\t\t\t\tinputs.isDragging = false\n\t\t\t\t\t\tinputs.isPointing = false\n\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\n\t\t\t\t\t\t// Remove the button from the buttons set\n\t\t\t\t\t\tinputs.buttons.delete(info.button)\n\n\t\t\t\t\t\t// If we're in pen mode and we're not using a pen, stop here\n\t\t\t\t\t\tif (instanceState.isPenMode && !isPen) return\n\n\t\t\t\t\t\t// Firefox bug fix...\n\t\t\t\t\t\t// If it's the same pointer that we stored earlier...\n\t\t\t\t\t\t// ... then it's probably still a left-mouse-click!\n\t\t\t\t\t\tif (this.capturedPointerId === info.pointerId) {\n\t\t\t\t\t\t\tthis.capturedPointerId = null\n\t\t\t\t\t\t\tinfo.button = 0\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (inputs.isPanning) {\n\t\t\t\t\t\t\tif (!inputs.keys.has('Space')) {\n\t\t\t\t\t\t\t\tinputs.isPanning = false\n\t\t\t\t\t\t\t\tinputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst slideDirection = this.inputs.pointerVelocity\n\t\t\t\t\t\t\tconst slideSpeed = Math.min(2, slideDirection.len())\n\n\t\t\t\t\t\t\tswitch (info.button) {\n\t\t\t\t\t\t\t\tcase LEFT_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase MIDDLE_MOUSE_BUTTON: {\n\t\t\t\t\t\t\t\t\tif (this.inputs.keys.has(' ')) {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: 'grab', rotation: 0 })\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (slideSpeed > 0) {\n\t\t\t\t\t\t\t\tthis.slideCamera({ speed: slideSpeed, direction: slideDirection })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (info.button === STYLUS_ERASER_BUTTON) {\n\t\t\t\t\t\t\t\t// If we were erasing with a stylus button, restore the tool we were using before we started erasing\n\t\t\t\t\t\t\t\tthis.complete()\n\t\t\t\t\t\t\t\tthis.setCurrentTool(this._restoreToolId)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'keyboard': {\n\t\t\t\t// please, please\n\t\t\t\tif (info.key === 'ShiftRight') info.key = 'ShiftLeft'\n\t\t\t\tif (info.key === 'AltRight') info.key = 'AltLeft'\n\t\t\t\tif (info.code === 'ControlRight') info.code = 'ControlLeft'\n\t\t\t\tif (info.code === 'MetaRight') info.code = 'MetaLeft'\n\n\t\t\t\tswitch (info.name) {\n\t\t\t\t\tcase 'key_down': {\n\t\t\t\t\t\t// Add the key from the keys set\n\t\t\t\t\t\tinputs.keys.add(info.code)\n\n\t\t\t\t\t\t// If the space key is pressed (but meta / control isn't!) activate panning\n\t\t\t\t\t\tif (info.code === 'Space' && !info.ctrlKey) {\n\t\t\t\t\t\t\tif (!this.inputs.isPanning) {\n\t\t\t\t\t\t\t\tthis._prevCursor = instanceState.cursor.type\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis.inputs.isPanning = true\n\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = true\n\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t\tthis.setCursor({ type: this.inputs.isPointing ? 'grabbing' : 'grab', rotation: 0 })\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (this.inputs.isSpacebarPanning) {\n\t\t\t\t\t\t\tlet offset: Vec | undefined\n\t\t\t\t\t\t\tswitch (info.code) {\n\t\t\t\t\t\t\t\tcase 'ArrowUp': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, -1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowRight': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowDown': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(0, 1)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcase 'ArrowLeft': {\n\t\t\t\t\t\t\t\t\toffset = new Vec(-1, 0)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (offset) {\n\t\t\t\t\t\t\t\tconst bounds = this.getViewportPageBounds()\n\t\t\t\t\t\t\t\tconst next = bounds.clone().translate(offset.mulV({ x: bounds.w, y: bounds.h }))\n\t\t\t\t\t\t\t\tthis._animateToViewport(next, { animation: { duration: 320 } })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_up': {\n\t\t\t\t\t\t// Remove the key from the keys set\n\t\t\t\t\t\tinputs.keys.delete(info.code)\n\n\t\t\t\t\t\t// If we've lifted the space key,\n\t\t\t\t\t\tif (info.code === 'Space') {\n\t\t\t\t\t\t\tif (this.inputs.buttons.has(MIDDLE_MOUSE_BUTTON)) {\n\t\t\t\t\t\t\t\t// If we're still middle dragging, continue panning\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// otherwise, stop panning\n\t\t\t\t\t\t\t\tthis.inputs.isPanning = false\n\t\t\t\t\t\t\t\tthis.inputs.isSpacebarPanning = false\n\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase 'key_repeat': {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Correct the info name for right / middle clicks\n\t\tif (info.type === 'pointer') {\n\t\t\tif (info.button === MIDDLE_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'middle_click'\n\t\t\t} else if (info.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\tinfo.name = 'right_click'\n\t\t\t}\n\n\t\t\t// If a left click pointer event, send the event to the click manager.\n\t\t\tconst { isPenMode } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!\n\t\t\tif (info.isPen === isPenMode) {\n\t\t\t\t// The click manager may return a new event, i.e. a double click event\n\t\t\t\t// depending on the event coming in and its own state. If the event has\n\t\t\t\t// changed then hand both events to the statechart\n\t\t\t\tconst clickInfo = this._clickManager.handlePointerEvent(info)\n\t\t\t\tif (info.name !== clickInfo.name) {\n\t\t\t\t\tthis.root.handleEvent(info)\n\t\t\t\t\tthis.emit('event', info)\n\t\t\t\t\tthis.root.handleEvent(clickInfo)\n\t\t\t\t\tthis.emit('event', clickInfo)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Send the event to the statechart. It will be handled by all\n\t\t// active states, starting at the root.\n\t\tthis.root.handleEvent(info)\n\t\tthis.emit('event', info)\n\n\t\t// close open menus at the very end on pointer down! after everything else! \u03C3\u03C5\u03BD\u03C4\u03B5\u03BB\u03B5\u03AF\u03B1\u03C2 \u03C4\u03BF\u1FE6 \u03BA\u03CE\u03B4\u03B9\u03BA\u03B1!!\n\t\tif (info.type === 'pointer' && info.name === 'pointer_down') {\n\t\t\tthis.menus.clearOpenMenus()\n\t\t}\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\tprivate maybeTrackPerformance(name: string) {\n\t\tif (debugFlags.measurePerformance.get()) {\n\t\t\tif (this.performanceTracker.isStarted()) {\n\t\t\t\tclearTimeout(this.performanceTrackerTimeout)\n\t\t\t} else {\n\t\t\t\tthis.performanceTracker.start(name)\n\t\t\t}\n\t\t\tthis.performanceTrackerTimeout = this.timers.setTimeout(() => {\n\t\t\t\tthis.performanceTracker.stop()\n\t\t\t}, 50)\n\t\t}\n\t}\n}\n\nfunction alertMaxShapes(editor: Editor, pageId = editor.getCurrentPageId()) {\n\tconst name = editor.getPage(pageId)!.name\n\teditor.emit('max-shapes', { name, pageId, count: editor.options.maxShapesPerPage })\n}\n\nfunction applyPartialToRecordWithProps<\n\tT extends UnknownRecord & { type: string; props: object; meta: object },\n>(prev: T, partial?: Partial<T> & { props?: Partial<T['props']> }): T {\n\tif (!partial) return prev\n\tlet next = null as null | T\n\tconst entries = Object.entries(partial)\n\tfor (let i = 0, n = entries.length; i < n; i++) {\n\t\tconst [k, v] = entries[i]\n\t\tif (v === undefined) continue\n\n\t\t// Is the key a special key? We don't update those\n\t\tif (k === 'id' || k === 'type' || k === 'typeName') continue\n\n\t\t// Is the value the same as it was before?\n\t\tif (v === (prev as any)[k]) continue\n\n\t\t// There's a new value, so create the new shape if we haven't already (should we be cloning this?)\n\t\tif (!next) next = { ...prev }\n\n\t\t// for props / meta properties, we support updates with partials of this object\n\t\tif (k === 'props' || k === 'meta') {\n\t\t\tnext[k] = { ...prev[k] } as JsonObject\n\t\t\tfor (const [nextKey, nextValue] of Object.entries(v as object)) {\n\t\t\t\t;(next[k] as JsonObject)[nextKey] = nextValue\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// base property\n\t\t;(next as any)[k] = v\n\t}\n\tif (!next) return prev\n\treturn next\n}\n\nfunction pushShapeWithDescendants(editor: Editor, id: TLShapeId, result: TLShape[]): void {\n\tconst shape = editor.getShape(id)\n\tif (!shape) return\n\tresult.push(shape)\n\tconst childIds = editor.getSortedChildIdsForParent(id)\n\tfor (let i = 0, n = childIds.length; i < n; i++) {\n\t\tpushShapeWithDescendants(editor, childIds[i], result)\n\t}\n}\n\n/**\n * Run `callback` in a world where all bindings from the shapes in `shapeIds` to shapes not in\n * `shapeIds` are removed. This is useful when you want to duplicate/copy shapes without worrying\n * about bindings that might be pointing to shapes that are not being duplicated.\n *\n * The callback is given the set of bindings that should be maintained.\n */\nfunction withIsolatedShapes<T>(\n\teditor: Editor,\n\tshapeIds: Set<TLShapeId>,\n\tcallback: (bindingsWithBoth: Set<TLBindingId>) => T\n): T {\n\tlet result!: Result<T, unknown>\n\n\teditor.run(\n\t\t() => {\n\t\t\tconst changes = editor.store.extractingChanges(() => {\n\t\t\t\tconst bindingsWithBoth = new Set<TLBindingId>()\n\t\t\t\tconst bindingsToRemove = new Set<TLBindingId>()\n\n\t\t\t\tfor (const shapeId of shapeIds) {\n\t\t\t\t\tconst shape = editor.getShape(shapeId)\n\t\t\t\t\tif (!shape) continue\n\n\t\t\t\t\tfor (const binding of editor.getBindingsInvolvingShape(shapeId)) {\n\t\t\t\t\t\tconst hasFrom = shapeIds.has(binding.fromId)\n\t\t\t\t\t\tconst hasTo = shapeIds.has(binding.toId)\n\t\t\t\t\t\tif (hasFrom && hasTo) {\n\t\t\t\t\t\t\tbindingsWithBoth.add(binding.id)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!hasFrom || !hasTo) {\n\t\t\t\t\t\t\tbindingsToRemove.add(binding.id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\teditor.deleteBindings([...bindingsToRemove], { isolateShapes: true })\n\n\t\t\t\ttry {\n\t\t\t\t\tresult = Result.ok(callback(bindingsWithBoth))\n\t\t\t\t} catch (error) {\n\t\t\t\t\tresult = Result.err(error)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\teditor.store.applyDiff(reverseRecordsDiff(changes), { runCallbacks: false })\n\t\t},\n\t\t{ history: 'ignore' }\n\t)\n\n\tif (result.ok) {\n\t\treturn result.value\n\t} else {\n\t\tthrow result.error\n\t}\n}\n\nfunction getCameraFitXFitY(editor: Editor, cameraOptions: TLCameraOptions) {\n\tif (!cameraOptions.constraints) throw Error('Should have constraints here')\n\tconst {\n\t\tpadding: { x: px, y: py },\n\t} = cameraOptions.constraints\n\tconst vsb = editor.getViewportScreenBounds()\n\tconst bounds = Box.From(cameraOptions.constraints.bounds)\n\tconst zx = (vsb.w - px * 2) / bounds.w\n\tconst zy = (vsb.h - py * 2) / bounds.h\n\treturn { zx, zy }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_utils", "EventEmitter", "shape", "highlightedUserIds", "leaderPresence", "page", "notVisibleShapes", "distance", "ancestor", "bindingsToCreate", "shapesToCreateWithOriginals", "gap", "shapes", "last", "animatingShapes", "n", "group", "bindings", "pageId"]
7
7
  }