{
  "version": 3,
  "sources": ["../../../src/lib/editor/Editor.ts"],
  "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\tTLAsset,\n\tTLAssetId,\n\tTLAssetPartial,\n\tTLBinding,\n\tTLBindingCreate,\n\tTLBindingId,\n\tTLBindingUpdate,\n\tTLCamera,\n\tTLCreateShapePartial,\n\tTLCursor,\n\tTLCursorType,\n\tTLDOCUMENT_ID,\n\tTLDocument,\n\tTLGroupShape,\n\tTLHandle,\n\tTLINSTANCE_ID,\n\tTLImageAsset,\n\tTLInstance,\n\tTLInstancePageState,\n\tTLInstancePresence,\n\tTLPage,\n\tTLPageId,\n\tTLParentId,\n\tTLRecord,\n\tTLShape,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLStore,\n\tTLStoreSnapshot,\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} 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 { getReorderingShapesChanges } from '../utils/reorderShapes'\nimport { getDroppedShapesToNewParents, kickoutOccludedShapes } from '../utils/reparenting'\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 { InputsManager } from './managers/InputsManager/InputsManager'\nimport { ScribbleManager } from './managers/ScribbleManager/ScribbleManager'\nimport { SnapManager } from './managers/SnapManager/SnapManager'\nimport { SpatialIndexManager } from './managers/SpatialIndexManager/SpatialIndexManager'\nimport { TextManager } from './managers/TextManager/TextManager'\nimport { TickManager } from './managers/TickManager/TickManager'\nimport { UserPreferencesManager } from './managers/UserPreferencesManager/UserPreferencesManager'\nimport {\n\tShapeUtil,\n\tTLEditStartInfo,\n\tTLGeometryOpts,\n\tTLResizeMode,\n\tTLShapeUtilCanBeLaidOutOpts,\n\tTLShapeUtilCanBindOpts,\n} 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 { TLEventInfo, TLPointerEventInfo } 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 editor'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\t * @deprecated Use `options.cameraOptions` instead. This will be removed in a future release.\n\t */\n\tcameraOptions?: Partial<TLCameraOptions>\n\toptions?: Partial<TldrawOptions>\n\t/**\n\t * Text options for the editor.\n\t *\n\t * @deprecated Use `options.text` instead. This prop will be removed in a future release.\n\t */\n\ttextOptions?: TLTextOptions\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\t// needs to be here for backwards compatibility with TldrawEditor\n\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\tcameraOptions,\n\t\tinitialState,\n\t\tautoFocus,\n\t\tinferDarkMode,\n\t\toptions: _options,\n\t\t// needs to be here for backwards compatibility with TldrawEditor\n\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\ttextOptions: _textOptions,\n\t\tgetShapeVisibility,\n\t\tfontAssetUrls,\n\t}: TLEditorOptions) {\n\t\tsuper()\n\n\t\tthis._getShapeVisibility = getShapeVisibility\n\n\t\t// Merge deprecated textOptions prop with options.text\n\t\t// options.text takes precedence over the deprecated textOptions prop\n\t\tconst options = _textOptions ? { ..._options, text: _options?.text ?? _textOptions } : _options\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._spatialIndex = new SpatialIndexManager(this)\n\t\tthis.disposables.add(() => this._spatialIndex.dispose())\n\n\t\tthis.disposables.add(this.timers.dispose)\n\n\t\t// Merge camera options: options.cameraOptions takes precedence over deprecated cameraOptions prop\n\t\tthis._cameraOptions.set({\n\t\t\t...DEFAULT_CAMERA_OPTIONS,\n\t\t\t...cameraOptions,\n\t\t\t...options?.camera,\n\t\t})\n\n\t\tthis._textOptions = atom('text options', options?.text ?? 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\t\tthis.disposables.add(() => {\n\t\t\t// Reset camera state to 'idle' so the store isn't left stuck at 'moving'\n\t\t\t// when tick events stop (e.g. React strict mode disposes while camera is moving)\n\t\t\tthis.off('tick', this._decayCameraStateTimeout)\n\t\t\tthis._setCameraState('idle')\n\t\t})\n\n\t\tthis.inputs = new InputsManager(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<TLBinding['type']>()\n\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(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\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 * @param parent - The parent state node to set the tool on.\n\t *\n\t * @public\n\t */\n\tsetTool(Tool: TLStateNodeConstructor, parent?: StateNode) {\n\t\tparent ??= this.root\n\t\tif (hasOwnProperty(parent.children!, Tool.id)) {\n\t\t\tthrow Error(`Can't override tool with id \"${Tool.id}\"`)\n\t\t}\n\t\tparent.children![Tool.id] = new Tool(this, parent)\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 * @param parent - The parent state node to remove the tool from.\n\t *\n\t * @public\n\t */\n\tremoveTool(Tool: TLStateNodeConstructor, parent?: StateNode) {\n\t\tparent ??= this.root\n\t\tif (hasOwnProperty(parent.children!, Tool.id)) {\n\t\t\tdelete parent.children![Tool.id]\n\t\t}\n\t}\n\n\t/**\n\t * A set of functions to call when the editor 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/**\n\t * A manager for the editor's tick events.\n\t *\n\t * @internal */\n\tprivate readonly _tickManager: TickManager\n\n\t/**\n\t * A manager for the editor's input state.\n\t *\n\t * @public\n\t */\n\treadonly inputs: InputsManager\n\n\t/**\n\t * A manager for the editor's snapping feature.\n\t *\n\t * @public\n\t */\n\treadonly snaps: SnapManager\n\n\tprivate readonly _spatialIndex: SpatialIndexManager\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\tthis.emit('dispose')\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<TLShape> }\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<K extends TLShape['type']>(type: K): ShapeUtil<Extract<TLShape, { type: K }>>\n\tgetShapeUtil<S extends TLShape>(shape: S | TLShapePartial<S> | 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(shape: TLShape | TLShapePartial<TLShape>): boolean\n\thasShapeUtil(type: TLShape['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<TLBinding> }\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<K extends TLBinding['type']>(type: K): BindingUtil<Extract<TLBinding, { type: K }>>\n\tgetBindingUtil<S extends TLBinding>(binding: S | { 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 editor'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 editor can undo.\n\t *\n\t * @public\n\t */\n\t@computed canUndo(): boolean {\n\t\treturn this.history.getNumUndos() > 0\n\t}\n\n\tgetCanUndo() {\n\t\treturn this.canUndo()\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\t/**\n\t * Whether the editor can redo.\n\t *\n\t * @public\n\t */\n\t@computed canRedo(): boolean {\n\t\treturn this.history.getNumRedos() > 0\n\t}\n\n\tgetCanRedo() {\n\t\treturn this.canRedo()\n\t}\n\n\tclearHistory() {\n\t\tthis.history.clear()\n\t\treturn this\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.toJson(),\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 editor'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 editor'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 editor'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(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(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 * Whether the shape can be edited.\n\t *\n\t * @param shape - The shape (or shape id) to check if it can be edited.\n\t * @param info - The info about the edit start.\n\t *\n\t * @public\n\t * @returns true if the shape can be edited, false otherwise.\n\t */\n\tcanEditShape<T extends TLShape | TLShapeId>(shape: T | null, info?: TLEditStartInfo): shape is T {\n\t\tconst id = typeof shape === 'string' ? shape : (shape?.id ?? null)\n\t\tif (!id) return false // no shape\n\t\tif (id === this.getEditingShapeId()) return false // already editing this shape\n\t\tconst _shape = this.getShape(id)\n\t\tif (!_shape) return false // no shape\n\t\tconst util = this.getShapeUtil(_shape)\n\t\tconst _info: TLEditStartInfo = info ?? { type: 'unknown' }\n\t\tif (!util.canEdit(_shape, _info)) return false // shape is not editable\n\t\tif (this.getIsReadonly() && !util.canEditInReadonly(_shape)) return false // readonly and no exception\n\t\tif (this.isShapeOrAncestorLocked(_shape) && !util.canEditWhileLocked(_shape)) return false // locked and no exception. Note here: we're not distinguishing between a locked shape and a shape that is the descendant of a locked shape.\n\t\treturn true // shape is editable\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\n\t\tif (!id) {\n\t\t\t// setting the editing shape to null\n\t\t\tthis.run(\n\t\t\t\t() => {\n\t\t\t\t\t// Clean up the previous editing shape\n\t\t\t\t\tconst prevEditingShapeId = this.getEditingShapeId()\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\n\t\t\t\t\t// Clean up the editing shape state and rich text editor\n\t\t\t\t\tthis._updateCurrentPageState({ editingShapeId: null })\n\t\t\t\t\tthis._currentRichTextEditor.set(null)\n\t\t\t\t},\n\t\t\t\t{ history: 'ignore' }\n\t\t\t)\n\n\t\t\treturn this\n\t\t}\n\n\t\t// id was provided but the next editing shape was not editable or didn't exist, so do nothing\n\t\tif (!this.canEditShape(id)) return this\n\n\t\t// id was provided and the next editing shape is editable, so set the rich text editor to null\n\t\tthis.run(\n\t\t\t() => {\n\t\t\t\t// Clean up the previous editing shape\n\t\t\t\tconst prevEditingShapeId = this.getEditingShapeId()\n\t\t\t\tif (prevEditingShapeId) {\n\t\t\t\t\tconst prevEditingShape = this.getShape(prevEditingShapeId)\n\t\t\t\t\tif (prevEditingShape) {\n\t\t\t\t\t\tthis.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Clean up the editing shape state and rich text editor\n\t\t\t\tthis._updateCurrentPageState({ editingShapeId: null })\n\t\t\t\tthis._currentRichTextEditor.set(null)\n\n\t\t\t\t// Set the new editing shape\n\t\t\t\tthis.select(id)\n\t\t\t\tthis._updateCurrentPageState({ editingShapeId: id })\n\n\t\t\t\tconst nextEditingShape = this.getShape(id)! // shape should be there because canEditShape checked it. Possible small chance that onEditEnd deleted it?\n\t\t\t\tthis.getShapeUtil(nextEditingShape).onEditStart?.(nextEditingShape)\n\t\t\t},\n\t\t\t{ history: 'ignore' }\n\t\t)\n\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 * Whether the shape can be cropped.\n\t *\n\t * @param shape - The shape (or shape id) to check if it can be cropped.\n\t *\n\t * @public\n\t * @returns true if the shape can be cropped, false otherwise.\n\t */\n\tcanCropShape<T extends TLShape | TLShapeId>(shape: T | null): shape is T {\n\t\tif (!shape) return false\n\t\tconst id = typeof shape === 'string' ? shape : (shape?.id ?? null)\n\t\tif (!id) return false\n\t\tconst _shape = this.getShape(id)\n\t\tif (!_shape) return false\n\t\tconst util = this.getShapeUtil(_shape)\n\t\tif (!util.canCrop(_shape)) return false\n\t\tif (this.isShapeOrAncestorLocked(_shape)) return false\n\t\treturn true\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 if (this.canCropShape(id)) {\n\t\t\t\t\t\tthis.updateCurrentPageState({ croppingShapeId: id })\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 scale factor used when creating or resizing shapes in dynamic size mode.\n\t *\n\t * @public\n\t */\n\t@computed getResizeScaleFactor() {\n\t\treturn this.user.getIsDynamicResizeMode() ? 1 / this.getZoomLevel() : 1\n\t}\n\n\tprivate _debouncedZoomLevel = atom('debounced zoom level', 1)\n\n\t/**\n\t * Get the debounced zoom level. When the camera is moving, this returns the zoom level\n\t * from when the camera started moving rather than the current zoom level. This can be\n\t * used to avoid expensive re-renders during camera movements.\n\t *\n\t * This behavior is controlled by the `useDebouncedZoom` option. When `useDebouncedZoom`\n\t * is `false`, this method always returns the current zoom level.\n\t *\n\t * @public\n\t */\n\t@computed getDebouncedZoomLevel() {\n\t\tif (this.options.debouncedZoom) {\n\t\t\tif (this.getCameraState() === 'idle') {\n\t\t\t\treturn this.getZoomLevel()\n\t\t\t} else {\n\t\t\t\treturn this._debouncedZoomLevel.get()\n\t\t\t}\n\t\t}\n\n\t\treturn this.getZoomLevel()\n\t}\n\n\t@computed private _getAboveDebouncedZoomThreshold() {\n\t\treturn this.getCurrentPageShapeIds().size > this.options.debouncedZoomThreshold\n\t}\n\n\t/**\n\t * Get the efficient zoom level. This returns the current zoom level if there are less than a certain number of shapes on the page,\n\t * otherwise it returns the debounced zoom level. This can be used to avoid expensive re-renders during camera movements.\n\t *\n\t * @public\n\t * @example\n\t * ```ts\n\t * editor.getEfficientZoomLevel()\n\t * ```\n\t *\n\t * @public\n\t */\n\t@computed getEfficientZoomLevel() {\n\t\treturn this._getAboveDebouncedZoomThreshold()\n\t\t\t? this.getDebouncedZoomLevel()\n\t\t\t: this.getZoomLevel()\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 = this.inputs.getCurrentScreenPoint()\n\t\t\tconst currentPagePoint = this.inputs.getCurrentPagePoint()\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()].filter((id) => !this.isShapeHidden(id))\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.getCurrentScreenPoint(), { 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.getCurrentScreenPoint(), { 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\tconst currentZoom = this.getZoomLevel()\n\t\t\t// If already at 100%, zoom to fit the selection in the viewport\n\t\t\t// Otherwise, zoom to 100% centered on the selection\n\t\t\tif (Math.abs(currentZoom - 1) < 0.01) {\n\t\t\t\tthis.zoomToBounds(selectionPageBounds, opts)\n\t\t\t} else {\n\t\t\t\tthis.zoomToBounds(selectionPageBounds, {\n\t\t\t\t\ttargetZoom: 1,\n\t\t\t\t\t...opts,\n\t\t\t\t})\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 =\n\t\t\topts?.inset ?? Math.min(this.options.zoomToFitPadding, 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.emit('resize', screenBounds.toJson())\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.emit('resize', screenBounds.toJson())\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.emit('resize', screenBounds.toJson())\n\t\t\t\tthis._setCamera(Vec.From({ ...this.getCamera() }))\n\t\t\t}\n\t\t}\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 _cameraStateTimeoutRemaining = 0\n\tprivate _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._setCameraState('idle')\n\t}\n\tprivate _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.getInstanceState().cameraState !== 'idle') return\n\t\tthis._setCameraState('moving')\n\t\tthis._debouncedZoomLevel.set(unsafe__withoutCapture(() => this.getCamera().z))\n\t\tthis.on('tick', this._decayCameraStateTimeout)\n\t}\n\tprivate _setCameraState(cameraState: 'idle' | 'moving') {\n\t\tthis.updateInstanceState({ cameraState }, { history: 'ignore' })\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.getInstanceState().cameraState\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\tprivate _culledShapesCache: Set<TLShapeId> | null = null\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 nextValue = new Set<TLShapeId>(notVisibleShapes)\n\t\t// we don't cull the shape we are editing\n\t\tif (editingId) {\n\t\t\tnextValue.delete(editingId)\n\t\t}\n\t\t// we also don't cull selected shapes\n\t\tselectedShapeIds.forEach((id) => {\n\t\t\tnextValue.delete(id)\n\t\t})\n\n\t\t// Cache optimization: return same Set object if contents unchanged\n\t\t// This allows consumers to use === comparison and prevents unnecessary re-renders\n\t\tconst prevValue = this._culledShapesCache\n\t\tif (prevValue) {\n\t\t\t// If sizes differ, contents must differ\n\t\t\tif (prevValue.size !== nextValue.size) {\n\t\t\t\tthis._culledShapesCache = nextValue\n\t\t\t\treturn nextValue\n\t\t\t}\n\n\t\t\t// Check if all elements are the same\n\t\t\tfor (const id of prevValue) {\n\t\t\t\tif (!nextValue.has(id)) {\n\t\t\t\t\t// Found a difference, update cache and return new set\n\t\t\t\t\tthis._culledShapesCache = nextValue\n\t\t\t\t\treturn nextValue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Loop completed without finding differences - contents identical\n\t\t\treturn prevValue\n\t\t}\n\n\t\tthis._culledShapesCache = nextValue\n\t\treturn nextValue\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\tif (this.isShapeHidden(shapeId)) return\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\t// Use larger margin for spatial search to account for edge distance checks\n\t\tconst searchMargin = Math.max(innerMargin, outerMargin, this.options.hitTestMargin / zoomLevel)\n\t\tconst candidateIds = this._spatialIndex.getShapeIdsAtPoint(point, searchMargin)\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\t// Frames have labels positioned above the shape (outside bounds), so always include them\n\t\t\tif (!candidateIds.has(shape.id) && !this.isShapeOfType(shape, 'frame')) return false\n\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(shape, 'frame') ||\n\t\t\t\t((this.isShapeOfType(shape, 'note') ||\n\t\t\t\t\tthis.isShapeOfType(shape, 'arrow') ||\n\t\t\t\t\t(this.isShapeOfType(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(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 geometry rejects this hit (e.g. transparent image pixel),\n\t\t\t\t\t\t// skip this shape and check shapes behind it.\n\t\t\t\t\t\tif (geometry.ignoreHit(pointInShapeSpace)) {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\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\tconst margin = opts.margin ?? 0\n\t\tconst candidateIds = this._spatialIndex.getShapeIdsAtPoint(point, margin)\n\n\t\t// Get all page shapes in z-index order and filter to candidates that pass isPointInShape\n\t\t// Frames are always checked because their labels can be outside their bounds\n\t\treturn this.getCurrentPageShapesSorted()\n\t\t\t.filter((shape) => {\n\t\t\t\tif (this.isShapeHidden(shape)) return false\n\t\t\t\tif (!candidateIds.has(shape.id) && !this.isShapeOfType(shape, 'frame')) return false\n\t\t\t\treturn this.isPointInShape(shape, point, opts)\n\t\t\t})\n\t\t\t.reverse()\n\t}\n\n\t/**\n\t * Get shape IDs within the given bounds.\n\t *\n\t * Note: Uses shape page bounds only. Frames with labels outside their bounds\n\t * may not be included even if the label is within the search bounds.\n\t *\n\t * Note: Results are unordered. If you need z-order, combine with sorted shapes:\n\t * ```ts\n\t * const candidates = editor.getShapeIdsInsideBounds(bounds)\n\t * const sorted = editor.getCurrentPageShapesSorted().filter(s => candidates.has(s.id))\n\t * ```\n\t *\n\t * @param bounds - The bounds to search within.\n\t * @returns Unordered set of shape IDs within the given bounds.\n\t *\n\t * @public\n\t */\n\tgetShapeIdsInsideBounds(bounds: Box): Set<TLShapeId> {\n\t\treturn this._spatialIndex.getShapeIdsInsideBounds(bounds)\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(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<K extends TLShape['type']>(\n\t\tshape: TLShape,\n\t\ttype: K\n\t): shape is Extract<TLShape, { type: K }>\n\tisShapeOfType<T extends TLShape>(\n\t\tshape: TLShape,\n\t\ttype: T['type']\n\t): shape is Extract<TLShape, { type: T['type'] }>\n\tisShapeOfType<T extends TLShape = TLShape>(shapeId: TLShapeId, type: T['type']): boolean\n\tisShapeOfType(arg: TLShape | TLShapeId, type: TLShape['type']) {\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(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<K extends TLBinding['type']>(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: K\n\t): Extract<TLBinding, { type: K }>[]\n\tgetBindingsFromShape<Binding extends TLBinding = TLBinding>(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[]\n\tgetBindingsFromShape<Binding extends TLBinding = 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<K extends TLBinding['type']>(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: K\n\t): Extract<TLBinding, { type: K }>[]\n\tgetBindingsToShape<Binding extends TLBinding = TLBinding>(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: Binding['type']\n\t): Binding[]\n\tgetBindingsToShape<Binding extends TLBinding = 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<K extends TLBinding['type']>(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype: K\n\t): Extract<TLBinding, { type: K }>[]\n\tgetBindingsInvolvingShape<Binding extends TLBinding = TLBinding>(\n\t\tshape: TLShape | TLShapeId,\n\t\ttype?: Binding['type']\n\t): Binding[]\n\tgetBindingsInvolvingShape<Binding extends TLBinding = 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(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: TLShapeUtilCanBindOpts = {\n\t\t\tfromShape: typeof fromShape === 'string' ? { type: fromShape } : fromShape,\n\t\t\ttoShape: typeof toShape === 'string' ? { type: toShape } : toShape,\n\t\t\tbindingType,\n\t\t\tfromShapeType,\n\t\t\ttoShapeType,\n\t\t}\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 * Shared clustering logic for layout methods. Resolves shapes, optionally filters to\n\t * axis-aligned shapes, checks canBeLaidOut, and groups shapes into clusters via arrow bindings.\n\t *\n\t * @internal\n\t */\n\tprivate getShapeClusters(\n\t\tshapes: TLShapeId[] | TLShape[],\n\t\ttype: TLShapeUtilCanBeLaidOutOpts['type'],\n\t\topts?: { filterAxisAligned?: boolean }\n\t): { clusters: { shapes: TLShape[]; pageBounds: Box }[]; allBounds: Box[] } {\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\tlet freshShapes = compact(ids.map((id) => this.getShape(id)))\n\n\t\t// optionally filter to axis-aligned shapes (rotation is a multiple of 90 degrees)\n\t\tif (opts?.filterAxisAligned) {\n\t\t\tfreshShapes = freshShapes.filter(\n\t\t\t\t(s) => this.getShapePageTransform(s)?.rotation() % (PI / 2) === 0\n\t\t\t)\n\t\t}\n\n\t\tconst clusters: { shapes: TLShape[]; pageBounds: Box }[] = []\n\t\tconst allBounds: Box[] = []\n\t\tconst visited = new Set<TLShapeId>()\n\n\t\tfor (const shape of freshShapes) {\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,\n\t\t\t\t\tshapes: freshShapes,\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: freshShapes,\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\tclusters.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\treturn { clusters, allBounds }\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(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\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\tconst { clusters: shapeClustersToStack } = this.getShapeClusters(shapes, 'stack')\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 { clusters, allBounds } = this.getShapeClusters(shapes, 'pack')\n\n\t\tconst shapeClustersToPack = clusters.map((cluster) => ({\n\t\t\t...cluster,\n\t\t\tnextPageBounds: cluster.pageBounds.clone(),\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 { clusters: shapeClustersToAlign, allBounds } = this.getShapeClusters(shapes, 'align')\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 { clusters: shapeClustersToDistribute } = this.getShapeClusters(shapes, 'distribute')\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\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\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\tif (this.getIsReadonly()) return this\n\n\t\tconst { clusters: shapeClustersToStretch, allBounds } = this.getShapeClusters(\n\t\t\tshapes,\n\t\t\t'stretch',\n\t\t\t{ filterAxisAligned: true }\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) shapeLocalOffset.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 and reposition a set of shapes so that their combined page bounds matches the given\n\t * target bounds.\n\t *\n\t * @example\n\t * ```ts\n\t * editor.resizeToBounds([box1, box2], { x: 0, y: 0, w: 500, h: 500 })\n\t * editor.resizeToBounds(editor.getSelectedShapeIds(), new Box(0, 0, 500, 500))\n\t * ```\n\t *\n\t * @param shapes - The shapes (or shape ids) to resize.\n\t * @param bounds - The target bounding box.\n\t *\n\t * @public\n\t */\n\tresizeToBounds(shapes: TLShapeId[] | TLShape[], bounds: BoxLike): this {\n\t\tif (this.getIsReadonly()) return this\n\n\t\tconst targetBounds = Box.From(bounds)\n\n\t\tconst { clusters: shapeClusters, allBounds } = this.getShapeClusters(\n\t\t\tshapes,\n\t\t\t'resize_to_bounds',\n\t\t\t{ filterAxisAligned: true }\n\t\t)\n\n\t\tif (shapeClusters.length === 0) return this\n\n\t\tconst commonBounds = Box.Common(allBounds)\n\t\tif (!commonBounds) return this\n\t\tif (commonBounds.width === 0 || commonBounds.height === 0) return this\n\n\t\tconst scaleX = targetBounds.width / commonBounds.width\n\t\tconst scaleY = targetBounds.height / commonBounds.height\n\t\tconst scale = new Vec(scaleX, scaleY)\n\n\t\tshapeClusters.forEach(({ shapes, pageBounds }) => {\n\t\t\tconst localOffset = new Vec(\n\t\t\t\ttargetBounds.minX -\n\t\t\t\t\tcommonBounds.minX +\n\t\t\t\t\t(pageBounds.minX - commonBounds.minX) * (scaleX - 1),\n\t\t\t\ttargetBounds.minY - commonBounds.minY + (pageBounds.minY - commonBounds.minY) * (scaleY - 1)\n\t\t\t)\n\n\t\t\tconst scaleOrigin = new Vec(\n\t\t\t\ttargetBounds.minX + (pageBounds.minX - commonBounds.minX) * scaleX,\n\t\t\t\ttargetBounds.minY + (pageBounds.minY - commonBounds.minY) * scaleY\n\t\t\t)\n\n\t\t\tfor (const shape of shapes) {\n\t\t\t\t// First translate\n\t\t\t\tconst shapeLocalOffset = localOffset.clone()\n\t\t\t\tconst parentTransform = this.getShapeParentTransform(shape)\n\t\t\t\tif (parentTransform) shapeLocalOffset.rot(-parentTransform.rotation())\n\t\t\t\tshapeLocalOffset.add(shape)\n\t\t\t\tconst changes = this.getChangesToTranslateShape(shape, shapeLocalOffset)\n\t\t\t\tthis.updateShape(changes)\n\n\t\t\t\t// Then resize\n\t\t\t\tthis.resizeShape(shape.id, scale, {\n\t\t\t\t\tinitialBounds: this.getShapeGeometry(shape).bounds,\n\t\t\t\t\tscaleOrigin,\n\t\t\t\t\tisAspectRatioLocked: this.getShapeUtil(shape).isAspectRatioLocked(shape),\n\t\t\t\t\tscaleAxisRotation: 0,\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\tinitialPageTransform: options.initialPageTransform,\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\t// We need to compute the new local rotation that will result in the negated page rotation.\n\t\t\t// For a shape with local rotation `localRot` and parent page rotation `parentRot`:\n\t\t\t// - pageRot = parentRot + localRot\n\t\t\t// - newPageRot = -pageRot (we want to negate the page rotation)\n\t\t\t// - newPageRot = parentRot + newLocalRot (parent hasn't changed)\n\t\t\t// - Therefore: newLocalRot = -pageRot - parentRot = -(parentRot + localRot) - parentRot = -localRot - 2*parentRot\n\t\t\tconst parentRotation = this.getShapeParentTransform(id).rotation()\n\t\t\tconst rotation = -options.initialShape.rotation - 2 * parentRotation\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 pageTransform = this.getShapePageTransform(id)!\n\t\t// We need to use the local bounds center transformed to page space, not the axis-aligned\n\t\t// page bounds center. This is because the page bounds are axis-aligned and their center\n\t\t// changes when the rotation changes, but we want to use the same reference point as\n\t\t// preScaleShapePageCenter (which used initialBounds.center transformed by the page transform).\n\t\tconst currentLocalBounds = this.getShapeGeometry(id).bounds\n\t\tconst currentPageCenter = Mat.applyToPoint(pageTransform, currentLocalBounds.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(shape: OptionalKeys<TLShapePartial<TLShape>, 'id'> | TLShape['id']): 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(\n\t\tshapes: (TLShape['id'] | OptionalKeys<TLShapePartial<TLShape>, '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<TShape extends TLShape>(shape: TLCreateShapePartial<TShape>): 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<TShape extends TLShape = TLShape>(shapes: TLCreateShapePartial<TShape>[]): 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 childBounds = compact(shapesToGroup.map((shape) => this.getShapePageBounds(shape)))\n\t\tconst pageBounds = Box.Common(childBounds)\n\n\t\tif (!pageBounds.isValid()) {\n\t\t\tthrow Error(`Editor.groupShapes: group bounds are invalid (NaN).`)\n\t\t}\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([\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(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 TLShape = TLShape>(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 TLShape>(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(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(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(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(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\tlet pasteParentId: TLPageId | TLShapeId = currentPageId\n\n\t\tconst shapesById = new Map(shapes.map((s) => [s.id, s]))\n\t\tconst rootShapesFromContent = compact(rootShapeIds.map((id) => shapesById.get(id)))\n\n\t\tif (point) {\n\t\t\t// PASTE AT CURSOR: find the deepest accepts-children shape under the cursor\n\t\t\tif (rootShapesFromContent.length > 0) {\n\t\t\t\tconst targetParent = this.getShapeAtPoint(point, {\n\t\t\t\t\thitInside: true,\n\t\t\t\t\thitFrameInside: true,\n\t\t\t\t\thitLocked: true,\n\t\t\t\t\tfilter: (shape) => {\n\t\t\t\t\t\tconst util = this.getShapeUtil(shape)\n\t\t\t\t\t\treturn rootShapesFromContent.every((rootShape) =>\n\t\t\t\t\t\t\tutil.canReceiveNewChildrenOfType?.(shape, rootShape.type)\n\t\t\t\t\t\t)\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t\tpasteParentId = targetParent?.id ?? currentPageId\n\t\t\t}\n\t\t} else if (!preservePosition) {\n\t\t\t// STANDARD PASTE: check if a selected shape (or its ancestor) accepts children\n\t\t\tconst selectedShapes = this.getSelectedShapes()\n\t\t\tlet selectedParent: TLShape | null = null\n\n\t\t\tconst canAcceptAll = (candidate: TLShape) => {\n\t\t\t\tconst util = this.getShapeUtil(candidate)\n\t\t\t\treturn rootShapesFromContent.every((rs) =>\n\t\t\t\t\tutil.canReceiveNewChildrenOfType?.(candidate, rs.type)\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tfor (const shape of selectedShapes) {\n\t\t\t\t// Find the nearest container: the shape itself if it can accept,\n\t\t\t\t// an accepting ancestor, or fall back to the shape's parent\n\t\t\t\t// (handles groups and other non-frame containers)\n\t\t\t\tconst candidate = canAcceptAll(shape)\n\t\t\t\t\t? shape\n\t\t\t\t\t: (this.findShapeAncestor(shape, canAcceptAll) ??\n\t\t\t\t\t\t(isShapeId(shape.parentId) ? this.getShape(shape.parentId)! : null))\n\n\t\t\t\tif (!candidate) {\n\t\t\t\t\tselectedParent = null\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif (!selectedParent) {\n\t\t\t\t\tselectedParent = candidate\n\t\t\t\t} else if (selectedParent.id !== candidate.id) {\n\t\t\t\t\t// Different candidates \u2014 find the deepest common accepting ancestor\n\t\t\t\t\tconst spAncestors = this.getShapeAncestors(selectedParent)\n\t\t\t\t\tif (canAcceptAll(selectedParent)) spAncestors.push(selectedParent)\n\t\t\t\t\tconst acceptingAncestors = spAncestors.filter(canAcceptAll)\n\n\t\t\t\t\tconst candidateAncestorIds = new Set([\n\t\t\t\t\t\tcandidate.id,\n\t\t\t\t\t\t...this.getShapeAncestors(candidate).map((a) => a.id),\n\t\t\t\t\t])\n\n\t\t\t\t\tlet common: TLShape | null = null\n\t\t\t\t\tfor (let i = acceptingAncestors.length - 1; i >= 0; i--) {\n\t\t\t\t\t\tif (candidateAncestorIds.has(acceptingAncestors[i].id)) {\n\t\t\t\t\t\t\tcommon = acceptingAncestors[i]\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tselectedParent = common\n\t\t\t\t\tif (!selectedParent) break\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Don't paste a shape into itself (the duplicating-a-frame case)\n\t\t\tif (selectedParent && shapeIdMap.has(selectedParent.id)) {\n\t\t\t\tselectedParent = null\n\t\t\t}\n\n\t\t\tif (selectedParent) {\n\t\t\t\tpasteParentId = selectedParent.id\n\t\t\t}\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\tif (assetsToCreate.length > 0) this.createAssets(assetsToCreate)\n\t\t\tthis.createShapes(newShapes)\n\t\t\tthis.createBindings(newBindings)\n\t\t\tif (select) this.select(...rootShapes.map((s) => s.id))\n\n\t\t\t// Reparent root shapes to paste parent if not page\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\t// --- POSITIONING ---\n\t\t\tconst rootBounds = Box.Common(compact(rootShapes.map((s) => this.getShapePageBounds(s.id))))\n\n\t\t\tif (point === undefined) {\n\t\t\t\tif (!isPageId(pasteParentId)) {\n\t\t\t\t\t// Paste into selected parent \u2192 center in that shape\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 if (preservePosition) {\n\t\t\t\t\t// preservePosition (page duplication) \u2192 keep original coords\n\t\t\t\t\tpoint = rootBounds.center\n\t\t\t\t} else {\n\t\t\t\t\t// Standard paste to page: check viewport overlap\n\t\t\t\t\tconst viewportPageBounds = this.getViewportPageBounds()\n\t\t\t\t\tconst anyOverlap = rootShapes.some((s) => {\n\t\t\t\t\t\tconst b = this.getShapePageBounds(s.id)\n\t\t\t\t\t\treturn b && viewportPageBounds.collides(b)\n\t\t\t\t\t})\n\t\t\t\t\tpoint = anyOverlap ? rootBounds.center : viewportPageBounds.center\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply offset to move shapes to target point\n\t\t\tconst pageCenter = Box.Common(\n\t\t\t\tcompact(rootShapes.map(({ id }) => this.getShapePageBounds(id)))\n\t\t\t).center\n\t\t\tconst offset = Vec.Sub(point, pageCenter)\n\n\t\t\tif (offset.x !== 0 || offset.y !== 0) {\n\t\t\t\tthis.updateShapes(\n\t\t\t\t\trootShapes.map(({ id }) => {\n\t\t\t\t\t\tconst s = this.getShape(id)!\n\t\t\t\t\t\tconst localRotation = this.getShapeParentTransform(id).decompose().rotation\n\t\t\t\t\t\tconst localDelta = Vec.Rot(offset, -localRotation)\n\t\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\t})\n\t\t\t\t)\n\t\t\t}\n\n\t\t\t// Auto-reparent into frames when pasted to page level\n\t\t\tif (isPageId(pasteParentId)) {\n\t\t\t\tconst currentRootShapes = compact(rootShapes.map((s) => this.getShape(s.id)))\n\t\t\t\t// Don't reparent into source shapes (prevents a duplicate frame\n\t\t\t\t// from being swallowed by its original), and require the shape's\n\t\t\t\t// center to be inside the parent (filters out edge-only overlaps)\n\t\t\t\tconst { reparenting } = getDroppedShapesToNewParents(\n\t\t\t\t\tthis,\n\t\t\t\t\tcurrentRootShapes,\n\t\t\t\t\t(shape, parent) => {\n\t\t\t\t\t\tif (shapeIdMap.has(parent.id)) return false\n\t\t\t\t\t\tconst shapeBounds = this.getShapePageBounds(shape)\n\t\t\t\t\t\tconst parentBounds = this.getShapePageBounds(parent)\n\t\t\t\t\t\tif (!shapeBounds || !parentBounds) return false\n\t\t\t\t\t\treturn parentBounds.containsPoint(shapeBounds.center)\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t\treparenting.forEach((childrenToReparent, newParentId) => {\n\t\t\t\t\tif (childrenToReparent.length === 0) return\n\t\t\t\t\tthis.reparentShapes(\n\t\t\t\t\t\tchildrenToReparent.map((s) => s.id),\n\t\t\t\t\t\tnewParentId\n\t\t\t\t\t)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Kick out any pasted root shapes that ended up outside their parent container\n\t\t\tconst newShapeIdSet = new Set(newShapes.map((s) => s.id))\n\t\t\tconst shapesToKickout = rootShapes\n\t\t\t\t.map((s) => s.id)\n\t\t\t\t.filter((id) => {\n\t\t\t\t\tconst shape = this.getShape(id)\n\t\t\t\t\tif (!shape) return false\n\t\t\t\t\t// Only check shapes that are children of a shape (not page)\n\t\t\t\t\tif (isPageId(shape.parentId)) return false\n\t\t\t\t\t// Don't check containers with pasted children (preserves intentional\n\t\t\t\t\t// parent-child relationships from the copied content)\n\t\t\t\t\tconst children = this.getSortedChildIdsForParent(id)\n\t\t\t\t\treturn !children.some((childId) => newShapeIdSet.has(childId))\n\t\t\t\t})\n\n\t\t\tif (shapesToKickout.length > 0) {\n\t\t\t\tkickoutOccludedShapes(this, shapesToKickout)\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 * 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.getCurrentScreenPoint(),\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.getIsPen(),\n\t\t\tshiftKey: options?.shiftKey ?? this.inputs.getShiftKey(),\n\t\t\taltKey: options?.altKey ?? this.inputs.getAltKey(),\n\t\t\tctrlKey: options?.ctrlKey ?? this.inputs.getCtrlKey(),\n\t\t\tmetaKey: options?.metaKey ?? this.inputs.getMetaKey(),\n\t\t\taccelKey: false,\n\t\t}\n\n\t\t// needs to be calculated second\n\t\tevent.accelKey = options?.accelKey ?? this.inputs.getAccelKey()\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.setShiftKey(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.getShiftKey(),\n\t\t\tctrlKey: this.inputs.getCtrlKey(),\n\t\t\taltKey: this.inputs.getAltKey(),\n\t\t\tmetaKey: this.inputs.getMetaKey(),\n\t\t\taccelKey: this.inputs.getAccelKey(),\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.setAltKey(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.getShiftKey(),\n\t\t\tctrlKey: this.inputs.getCtrlKey(),\n\t\t\taltKey: this.inputs.getAltKey(),\n\t\t\tmetaKey: this.inputs.getMetaKey(),\n\t\t\taccelKey: this.inputs.getAccelKey(),\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.setCtrlKey(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.getShiftKey(),\n\t\t\tctrlKey: this.inputs.getCtrlKey(),\n\t\t\taltKey: this.inputs.getAltKey(),\n\t\t\tmetaKey: this.inputs.getMetaKey(),\n\t\t\taccelKey: this.inputs.getAccelKey(),\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.setMetaKey(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.getShiftKey(),\n\t\t\tctrlKey: this.inputs.getCtrlKey(),\n\t\t\taltKey: this.inputs.getAltKey(),\n\t\t\tmetaKey: this.inputs.getMetaKey(),\n\t\t\taccelKey: this.inputs.getAccelKey(),\n\t\t\tcode: 'MetaLeft',\n\t\t})\n\t}\n\n\t/** @internal */\n\tprivate _restoreToolId = 'select'\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.setIsDragging(false)\n\n\t\t\t\tif (this.inputs.getIsPanning()) {\n\t\t\t\t\tthis.inputs.setIsPanning(false)\n\t\t\t\t\tthis.inputs.setIsSpacebarPanning(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\tthis.emit('event', 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.setShiftKey(true)\n\t\t} else if (!info.shiftKey && inputs.getShiftKey() && 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.setAltKey(true)\n\t\t} else if (!info.altKey && inputs.getAltKey() && 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.setCtrlKey(true)\n\t\t} else if (!info.ctrlKey && inputs.getCtrlKey() && 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.setMetaKey(true)\n\t\t} else if (!info.metaKey && inputs.getMetaKey() && this._metaKeyTimeout === -1) {\n\t\t\tthis._metaKeyTimeout = this.timers.setTimeout(this._setMetaKeyTimeout, 150)\n\t\t}\n\n\t\tif (!inputs.getIsPointing()) {\n\t\t\tinputs.setIsDragging(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.inputs.updateFromEvent(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.getIsPinching()) return\n\n\t\t\t\t\t\tif (!inputs.getIsEditing()) {\n\t\t\t\t\t\t\t// Always capture the current selection when pinch starts.\n\t\t\t\t\t\t\t// This ensures Safari (which uses gesture events instead of wheel)\n\t\t\t\t\t\t\t// doesn't restore a stale selection from an earlier pointer_down.\n\t\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds]\n\n\t\t\t\t\t\t\tthis._didPinch = true\n\n\t\t\t\t\t\t\tinputs.setIsPinching(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\tthis.emit('event', info)\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.getIsPinching()) 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\tthis.emit('event', info)\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.getIsPinching()) return this\n\n\t\t\t\t\t\t// Stop pinching\n\t\t\t\t\t\tinputs.setIsPinching(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\tthis.emit('event', info)\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.inputs.updateFromEvent(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.getCurrentScreenPoint()\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\t// because we can't for sure detect whether a user is using a mouse or a trackpad,\n\t\t\t\t\t\t\t// we need to check the input mode preference, and only invert the zoom direction\n\t\t\t\t\t\t\t// if the user has specifically set it to a mouse.\n\t\t\t\t\t\t\tconst isZoomDirectionInverted =\n\t\t\t\t\t\t\t\t(this.user.getUserPreferences().isZoomDirectionInverted && inputMode === 'mouse') ??\n\t\t\t\t\t\t\t\tfalse\n\t\t\t\t\t\t\tconst deltaValue = delta ?? 0\n\t\t\t\t\t\t\tconst finalDelta = isZoomDirectionInverted ? -deltaValue : deltaValue\n\n\t\t\t\t\t\t\tconst zoom = cz + finalDelta * 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\tthis.root.handleEvent(info)\n\t\t\t\t\t\t\tthis.emit('event', info)\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\tthis.root.handleEvent(info)\n\t\t\t\t\t\t\tthis.emit('event', info)\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.getIsPinching()) return\n\n\t\t\t\tthis.inputs.updateFromEvent(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.getIsPanning()) {\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.getOriginScreenPoint().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.setIsPointing(true)\n\t\t\t\t\t\tinputs.setIsDragging(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.getIsPanning()) {\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.setIsPanning(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.getIsPanning()) {\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.getIsPanning() && this.inputs.getIsPointing()) {\n\t\t\t\t\t\t\t// Handle spacebar / middle mouse button panning\n\t\t\t\t\t\t\tconst currentScreenPoint = this.inputs.getCurrentScreenPoint()\n\t\t\t\t\t\t\tconst previousScreenPoint = this.inputs.getPreviousScreenPoint()\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.getIsPointing() &&\n\t\t\t\t\t\t\t!inputs.getIsDragging() &&\n\t\t\t\t\t\t\tVec.Dist2(inputs.getOriginPagePoint(), inputs.getCurrentPagePoint()) *\n\t\t\t\t\t\t\t\tthis.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.setIsDragging(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.setIsDragging(false)\n\t\t\t\t\t\tinputs.setIsPointing(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.getIsPanning()) {\n\t\t\t\t\t\t\tif (!inputs.keys.has('Space')) {\n\t\t\t\t\t\t\t\tinputs.setIsPanning(false)\n\t\t\t\t\t\t\t\tinputs.setIsSpacebarPanning(false)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst slideDirection = this.inputs.getPointerVelocity()\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\n\t\t\t\t\t\t// Clear the stashed selection so the next pinch captures fresh state.\n\t\t\t\t\t\t// This fixes Safari pinch zoom restoring outdated selections.\n\t\t\t\t\t\tthis._selectedShapeIdsAtPointerDown = []\n\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\tif (this.options.spacebarPanning) {\n\t\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\t\tif (info.code === 'Space' && !info.ctrlKey) {\n\t\t\t\t\t\t\t\tif (!this.inputs.getIsPanning()) {\n\t\t\t\t\t\t\t\t\tthis._prevCursor = instanceState.cursor.type\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tthis.inputs.setIsPanning(true)\n\t\t\t\t\t\t\t\tthis.inputs.setIsSpacebarPanning(true)\n\t\t\t\t\t\t\t\tclearTimeout(this._longPressTimeout)\n\t\t\t\t\t\t\t\tthis.setCursor({\n\t\t\t\t\t\t\t\t\ttype: this.inputs.getIsPointing() ? 'grabbing' : 'grab',\n\t\t\t\t\t\t\t\t\trotation: 0,\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 (this.inputs.getIsSpacebarPanning()) {\n\t\t\t\t\t\t\t\tlet offset: Vec | undefined\n\t\t\t\t\t\t\t\tswitch (info.code) {\n\t\t\t\t\t\t\t\t\tcase 'ArrowUp': {\n\t\t\t\t\t\t\t\t\t\toffset = new Vec(0, -1)\n\t\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tcase 'ArrowRight': {\n\t\t\t\t\t\t\t\t\t\toffset = new Vec(1, 0)\n\t\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tcase 'ArrowDown': {\n\t\t\t\t\t\t\t\t\t\toffset = new Vec(0, 1)\n\t\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tcase 'ArrowLeft': {\n\t\t\t\t\t\t\t\t\t\toffset = new Vec(-1, 0)\n\t\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (offset) {\n\t\t\t\t\t\t\t\t\tconst bounds = this.getViewportPageBounds()\n\t\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\t\tthis._animateToViewport(next, { animation: { duration: 320 } })\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\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\tif (this.options.spacebarPanning) {\n\t\t\t\t\t\t\t// If we've lifted the space key,\n\t\t\t\t\t\t\tif (info.code === 'Space') {\n\t\t\t\t\t\t\t\tif (this.inputs.buttons.has(MIDDLE_MOUSE_BUTTON)) {\n\t\t\t\t\t\t\t\t\t// If we're still middle dragging, continue panning\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t// otherwise, stop panning\n\t\t\t\t\t\t\t\t\tthis.inputs.setIsPanning(false)\n\t\t\t\t\t\t\t\t\tthis.inputs.setIsSpacebarPanning(false)\n\t\t\t\t\t\t\t\t\tthis.setCursor({ type: this._prevCursor, rotation: 0 })\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\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>(\n\tprev: T,\n\tpartial?: T extends T ? Omit<Partial<T>, 'props'> & { props?: Partial<T['props']> } : never\n): 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"],
  "mappings": "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",
  "names": ["shape", "highlightedUserIds", "leaderPresence", "page", "notVisibleShapes", "distance", "ancestor", "bindingsToCreate", "shapesToCreateWithOriginals", "gap", "shapes", "last", "animatingShapes", "n", "group", "bindings", "pageId"]
}
