anniedrawing 0.3.3 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +1 -1
- package/dist/agent/index.js +1 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/core/catalog.d.ts +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/textFit.d.ts +13 -0
- package/dist/docs/agents-repository.md +1 -1
- package/dist/docs/agents.md +2 -2
- package/dist/docs/api.md +3 -3
- package/dist/docs/board-js.md +16 -16
- package/dist/docs/decisions.md +15 -1
- package/dist/docs/format.md +2 -2
- package/dist/docs/index.html +15 -7
- package/dist/docs/llms-full.txt +16 -16
- package/dist/docs/llms.txt +10 -10
- package/dist/docs/mcp.md +1 -1
- package/dist/fellow.js +1 -1
- package/dist/index.js +1 -1
- package/dist/shared/board-OPwsZ2_V.js +2 -0
- package/dist/shared/board-OPwsZ2_V.js.map +1 -0
- package/dist/shared/{cards-DF0uI4-I.js → cards-D_9Lly1d.js} +2 -2
- package/dist/shared/{cards-DF0uI4-I.js.map → cards-D_9Lly1d.js.map} +1 -1
- package/dist/shared/defaults-DZEoAeRz.js +2 -0
- package/dist/shared/defaults-DZEoAeRz.js.map +1 -0
- package/dist/shared/describe-o3vER0cL.js +3 -0
- package/dist/shared/{describe-DaWyf3qV.js.map → describe-o3vER0cL.js.map} +1 -1
- package/dist/shared/{paste-B8nZA2Gh.js → paste-B4b0C9Jh.js} +2 -2
- package/dist/shared/{paste-B8nZA2Gh.js.map → paste-B4b0C9Jh.js.map} +1 -1
- package/dist/shared/picker-ciuPQvRn.js +2 -0
- package/dist/shared/picker-ciuPQvRn.js.map +1 -0
- package/dist/shared/textFit-BrGz6lhQ.js +2 -0
- package/dist/shared/textFit-BrGz6lhQ.js.map +1 -0
- package/dist/shared/ui-c98N8xEV.js +2 -0
- package/dist/shared/ui-c98N8xEV.js.map +1 -0
- package/dist/shared/{urlPaste-Oc4kZ0P7.js → urlPaste-BqcpeQ-c.js} +2 -2
- package/dist/shared/{urlPaste-Oc4kZ0P7.js.map → urlPaste-BqcpeQ-c.js.map} +1 -1
- package/dist/style.css +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/version.d.ts +1 -1
- package/llms-full.txt +16 -16
- package/llms.txt +10 -10
- package/package.json +1 -1
- package/dist/shared/board-p60lv7As.js +0 -2
- package/dist/shared/board-p60lv7As.js.map +0 -1
- package/dist/shared/defaults-C-aC_B4z.js +0 -2
- package/dist/shared/defaults-C-aC_B4z.js.map +0 -1
- package/dist/shared/describe-DaWyf3qV.js +0 -3
- package/dist/shared/picker-DZpEpkED.js +0 -2
- package/dist/shared/picker-DZpEpkED.js.map +0 -1
- package/dist/shared/ui-DWQtW0zJ.js +0 -2
- package/dist/shared/ui-DWQtW0zJ.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"board-p60lv7As.js","names":[],"sources":["../../src/core/locks.ts","../../src/kinds/registry.ts","../../src/stage/itemView.ts","../../src/stage/lens.ts","../../src/input/cursors.ts","../../src/stage/presence.ts","../../src/stage/stage.ts","../../src/porter/svg.ts","../../src/porter/indexedPng.ts","../../src/porter/png.ts","../../src/input/autosave.ts","../../src/input/measure.ts","../../src/board.ts"],"sourcesContent":["import type { Item } from './types';\n\n/** Moving a group must not move a locked descendant; locked groups protect their children. */\nexport function lockedItems(items: Item[]): Set<string> {\n const locked = new Set<string>();\n const visit = (item: Item, inherited = false): boolean => {\n const own = inherited || !!item.locked;\n let protectedChild = false;\n for (const child of item.children ?? []) protectedChild = visit(child, own) || protectedChild;\n if (own || protectedChild) locked.add(item.id);\n return own || protectedChild;\n };\n items.forEach((item) => visit(item));\n return locked;\n}\n","import { KIND_CATALOG } from '../core/catalog';\nimport type { AnnieDoc, Item, Outline, Point } from '../core/types';\n\nexport type { Outline };\nexport interface KindView {\n element: HTMLDivElement;\n shape: SVGSVGElement;\n text: HTMLDivElement;\n doc: AnnieDoc;\n}\nexport interface SVGContext {\n doc: AnnieDoc;\n theme: 'light' | 'dark';\n color: (value: string) => string;\n escape: (value: unknown) => string;\n}\nexport interface KindDef {\n kind: string;\n schema?: unknown;\n defaults?: Partial<Item>;\n outline?: (item: Item) => Outline | Outline[];\n /** Creates content once; optionally returns cleanup. The wrapper belongs to the stage. */\n mount?: (view: KindView) => void | (() => void);\n /** Updates custom content; changed contains transform, geometry, style, text, or content. */\n paint?: (view: KindView, item: Item, changed: Set<string>) => void;\n handles?: (item: Item) => { id: string; x: number; y: number; label?: string; cursor?: string }[];\n /** Handle points use unrotated local item coordinates. Return a draft patch. */\n dragHandle?: (\n item: Item,\n handleId: string,\n point: Point,\n modifiers: { shift: boolean; alt: boolean },\n ) => Partial<Item>;\n toSVG?: (item: Item, context: SVGContext) => SVGElement | string;\n summarize?: (item: Item) => string;\n}\nconst registry = new Map<string, KindDef>();\nfor (const { kind } of KIND_CATALOG) registry.set(kind, { kind });\n\n/** Declare a reusable kind; registration is scoped to each board's options. */\nexport function defineKind<T extends KindDef>(definition: T): T {\n if (!/^[a-z][a-z0-9_-]*$/i.test(definition.kind))\n throw new Error(\n 'Kind names must begin with a letter and contain only letters, digits, _ or -.',\n );\n return definition;\n}\n/** Register a default kind globally for boards created afterwards. */\nexport function registerKind(definition: KindDef): () => void {\n defineKind(definition);\n const previous = registry.get(definition.kind);\n registry.set(definition.kind, definition);\n return () => {\n if (previous) registry.set(definition.kind, previous);\n else registry.delete(definition.kind);\n };\n}\nexport function getKind(kind: string): KindDef | undefined {\n return registry.get(kind);\n}\nexport function getKinds(): KindDef[] {\n return [...registry.values()];\n}\nexport function createKindRegistry(extra: KindDef[] = []): Map<string, KindDef> {\n return new Map([...getKinds(), ...extra.map(defineKind)].map((kind) => [kind.kind, kind]));\n}\n","import type { AnnieDoc, Box, Item, Point } from '../core/types';\nimport type { KindDef, KindView } from '../kinds/registry';\nimport { routeConnector, type OutlineResolver } from '../geo/index';\nimport {\n color,\n esc,\n fontFamily,\n fontSize,\n headsMarkup,\n shapeMarkup,\n labelColor,\n SVG_NS,\n} from './paint';\n\nexport class ItemView implements KindView {\n readonly element = document.createElement('div');\n readonly shape = document.createElementNS(SVG_NS, 'svg');\n readonly text = document.createElement('div');\n private auxiliary = document.createElement('div');\n private previous = new Map<string, string>();\n private currentKind?: string;\n private currentDefinition?: KindDef;\n private unmount?: () => void;\n doc!: AnnieDoc;\n item!: Item;\n bounds!: Box;\n constructor(readonly id: string) {\n this.element.className = 'ad-item';\n this.element.style.display = 'none';\n this.element.dataset.adId = id;\n this.element.tabIndex = 0;\n this.element.setAttribute('role', 'img');\n this.shape.classList.add('ad-shape');\n this.shape.setAttribute('aria-hidden', 'true');\n this.shape.setAttribute('overflow', 'visible');\n this.text.className = 'ad-text';\n this.auxiliary.className = 'ad-auxiliary';\n this.element.append(this.shape, this.text, this.auxiliary);\n }\n private changed(key: string, value: string): boolean {\n if (this.previous.get(key) === value) return false;\n this.previous.set(key, value);\n return true;\n }\n paint(\n item: Item,\n doc: AnnieDoc,\n lookup: Map<string, Item>,\n theme: 'light' | 'dark',\n definition?: KindDef,\n sanitizeHTML?: (html: string) => string,\n outline?: OutlineResolver,\n ): void {\n this.doc = doc;\n this.item = item;\n const changed = new Set<string>();\n const custom = !!(definition?.mount || definition?.paint);\n let mount = false;\n if (this.currentKind !== item.kind || this.currentDefinition !== definition) {\n this.unmount?.();\n this.unmount = undefined;\n this.currentKind = item.kind;\n this.currentDefinition = definition;\n this.previous.clear();\n const display = this.element.style.display;\n this.element.removeAttribute('style');\n this.element.style.display = display;\n this.element.className = 'ad-item';\n delete this.element.dataset.adInteractive;\n this.shape.removeAttribute('style');\n this.text.removeAttribute('style');\n this.auxiliary.removeAttribute('style');\n this.element.replaceChildren(this.shape, this.text, this.auxiliary);\n this.shape.replaceChildren();\n this.text.replaceChildren();\n this.auxiliary.replaceChildren();\n this.auxiliary.className = 'ad-auxiliary';\n this.shape.style.display = '';\n this.element.dataset.adKind = item.kind;\n if (['image', 'video', 'link'].includes(item.kind)) this.auxiliary.classList.add('ad-card');\n mount = true;\n }\n const connector = item.kind === 'connector' ? routeConnector(item, lookup, outline) : undefined;\n const transform = connector\n ? ''\n : `translate3d(${item.x}px,${item.y}px,0) rotate(${item.rotation ?? 0}deg)`;\n if (this.changed('transform', transform)) {\n this.element.style.transform = transform;\n changed.add('transform');\n }\n const size = `${item.w}|${item.h}`;\n if (this.changed('size', size)) {\n this.element.style.width = `${connector ? 1 : item.w}px`;\n this.element.style.height = `${connector ? 1 : item.h}px`;\n this.shape.setAttribute('width', String(connector ? 1 : item.w));\n this.shape.setAttribute('height', String(connector ? 1 : item.h));\n changed.add('geometry');\n }\n const style = JSON.stringify([item.style, theme]);\n if (this.changed('style', style)) {\n this.element.style.opacity = String(item.style?.opacity ?? 1);\n this.element.style.color = color('ink', theme);\n this.text.style.color = labelColor(item, theme);\n changed.add('style');\n }\n const geometry = JSON.stringify([\n size,\n item.kind,\n item.points,\n item.closed,\n item.heads,\n connector?.d,\n style,\n ]);\n if (this.changed('geometry', geometry)) {\n changed.add('geometry');\n if (!custom) {\n const shapeKinds = ['rect', 'ellipse', 'diamond', 'note', 'line', 'path', 'connector'];\n this.shape.style.display = shapeKinds.includes(item.kind) ? '' : 'none';\n if (shapeKinds.includes(item.kind)) {\n const points: Point[] =\n connector?.points ??\n (\n item.points ?? [\n [0, 0],\n [item.w, item.h],\n ]\n ).map(([x, y]) => ({ x, y }));\n this.shape.innerHTML =\n shapeMarkup(item, theme, this.id, connector?.d) +\n (item.kind === 'line' || connector ? headsMarkup(points, item, theme) : '');\n }\n }\n }\n const textKey = JSON.stringify([item.text, item.kind, connector?.midpoint, theme]);\n if (this.changed('text', textKey)) {\n changed.add('text');\n if (!custom) {\n if (!this.text.isContentEditable) this.text.textContent = item.text?.value ?? '';\n this.text.style.fontSize = `${fontSize(item.text)}px`;\n this.text.style.fontFamily = fontFamily(item.text?.font);\n this.text.style.textAlign = item.text?.align ?? (item.kind === 'text' ? 'start' : 'center');\n this.text.style.justifyContent =\n item.text?.valign === 'top'\n ? 'flex-start'\n : item.text?.valign === 'bottom'\n ? 'flex-end'\n : 'center';\n this.text.style.alignItems =\n item.text?.align === 'start' || (item.kind === 'text' && !item.text?.align)\n ? 'flex-start'\n : item.text?.align === 'end'\n ? 'flex-end'\n : 'center';\n this.text.style.display = item.text || this.text.isContentEditable ? 'flex' : 'none';\n if (connector) {\n this.text.style.left = `${connector.midpoint.x}px`;\n this.text.style.top = `${connector.midpoint.y}px`;\n this.text.style.backgroundColor = color('paper', theme);\n } else {\n this.text.style.left = '';\n this.text.style.top = '';\n this.text.style.backgroundColor = '';\n }\n }\n }\n const auxiliary = JSON.stringify([\n item.kind,\n item.name,\n item.html,\n item.href,\n item.description,\n item.text?.value,\n item.media,\n item.media ? doc.media[item.media]?.src : undefined,\n theme,\n !!definition,\n item.crop,\n ]);\n if (this.changed('auxiliary', auxiliary)) {\n changed.add('content');\n if (!custom) {\n this.auxiliary.replaceChildren();\n if (item.kind === 'image') {\n const media = item.media ? doc.media[item.media] : undefined;\n if (media) {\n const img = document.createElement('img');\n img.draggable = false;\n img.alt = item.name ?? item.text?.value ?? 'Image';\n // Only images accepted by the model are ever assigned here.\n img.src = media.src;\n if (item.crop && item.crop.w > 0 && item.crop.h > 0) {\n img.style.width = `${(media.w / item.crop.w) * 100}%`;\n img.style.height = `${(media.h / item.crop.h) * 100}%`;\n img.style.left = `${(-item.crop.x / item.crop.w) * 100}%`;\n img.style.top = `${(-item.crop.y / item.crop.h) * 100}%`;\n }\n this.auxiliary.append(img);\n } else this.placeholder('Image unavailable');\n } else if (item.kind === 'video' || item.kind === 'link') {\n const stamp = auxiliary;\n void import('./cards').then(({ paintCard }) => {\n if (this.previous.get('auxiliary') === stamp) paintCard(this.auxiliary, item, this.doc);\n });\n } else if (item.kind === 'html') {\n this.auxiliary.classList.add('ad-html-content');\n if (sanitizeHTML) this.auxiliary.innerHTML = sanitizeHTML(item.html ?? '');\n else this.auxiliary.textContent = item.html ?? 'HTML content';\n } else if (!definition) this.placeholder(`Unknown kind: ${item.kind}`);\n }\n }\n if (this.changed('access', `${item.locked}|${item.hidden}`)) {\n this.element.classList.toggle('ad-locked', !!item.locked);\n this.element.tabIndex = item.hidden ? -1 : 0;\n }\n const label =\n definition?.summarize?.(item) ??\n `${item.kind === 'rect' ? 'Rectangle' : item.kind[0].toUpperCase() + item.kind.slice(1)}${item.text?.value || item.name || item.href ? `: ${item.text?.value ?? item.name ?? item.href}` : ''}`;\n if (this.changed('aria', label)) this.element.setAttribute('aria-label', label);\n if (\n custom &&\n this.changed(\n 'custom',\n JSON.stringify(\n Object.fromEntries(\n Object.entries(item).filter(\n ([key]) =>\n ![\n 'x',\n 'y',\n 'w',\n 'h',\n 'rotation',\n 'style',\n 'text',\n 'points',\n 'heads',\n 'closed',\n ].includes(key),\n ),\n ),\n ),\n )\n )\n changed.add('content');\n if (mount) {\n const cleanup = definition?.mount?.(this);\n if (typeof cleanup === 'function') this.unmount = cleanup;\n }\n definition?.paint?.(this, item, changed);\n }\n private placeholder(label: string): void {\n const placeholder = document.createElement('div');\n placeholder.className = 'ad-placeholder';\n placeholder.innerHTML = `<span aria-hidden=\"true\">◇</span><span>${esc(label)}</span>`;\n this.auxiliary.append(placeholder);\n }\n destroy(): void {\n this.unmount?.();\n this.unmount = undefined;\n this.element.remove();\n }\n}\n","import type { Box, LensState, Point } from '../core/types';\n\n/** Camera values are screen-pixel translation followed by page-space scaling. */\nexport class Lens {\n private value: LensState = { x: 0, y: 0, zoom: 1 };\n private listeners = new Set<(state: LensState) => void>();\n private observer?: ResizeObserver;\n private animation = 0;\n width: number;\n height: number;\n constructor(readonly host: HTMLElement) {\n this.width = host.clientWidth || 800;\n this.height = host.clientHeight || 600;\n if (typeof ResizeObserver !== 'undefined') {\n this.observer = new ResizeObserver((entries) => {\n const rect = entries[0]?.contentRect;\n if (!rect || (rect.width === this.width && rect.height === this.height)) return;\n this.width = rect.width;\n this.height = rect.height;\n this.emit();\n });\n this.observer.observe(host);\n }\n }\n get state(): LensState {\n return { ...this.value };\n }\n get zoom(): number {\n return this.value.zoom;\n }\n get center(): Point {\n return this.toPage({ x: this.width / 2, y: this.height / 2 });\n }\n set(patch: Partial<LensState>): void {\n this.stop();\n const next = { ...this.value, ...patch };\n if (![next.x, next.y, next.zoom].every(Number.isFinite)) return;\n next.zoom = Math.max(0.05, Math.min(8, next.zoom));\n if (next.x === this.value.x && next.y === this.value.y && next.zoom === this.value.zoom) return;\n this.value = next;\n this.emit();\n }\n private emit(): void {\n for (const callback of this.listeners) callback(this.state);\n }\n toPage(point: Point): Point {\n return {\n x: (point.x - this.value.x) / this.value.zoom,\n y: (point.y - this.value.y) / this.value.zoom,\n };\n }\n toScreen(point: Point): Point {\n return {\n x: point.x * this.value.zoom + this.value.x,\n y: point.y * this.value.zoom + this.value.y,\n };\n }\n viewport(margin = 0): Box {\n const p = this.toPage({ x: -margin, y: -margin });\n return {\n ...p,\n w: (this.width + margin * 2) / this.zoom,\n h: (this.height + margin * 2) / this.zoom,\n };\n }\n private fitState(box: Box, padding = 96): LensState {\n const usableW = Math.max(120, this.width - Math.min(padding * 2, this.width * 0.3));\n const usableH = Math.max(120, this.height - Math.min(padding * 2, this.height * 0.35));\n const zoom = Math.max(\n 0.05,\n Math.min(1.5, usableW / Math.max(1, box.w), usableH / Math.max(1, box.h)),\n );\n return {\n x: this.width / 2 - (box.x + box.w / 2) * zoom,\n y: this.height / 2 - (box.y + box.h / 2) * zoom,\n zoom,\n };\n }\n fit(box: Box, padding = 96): void {\n this.stop();\n this.set(this.fitState(box, padding));\n }\n flyTo(box: Box): void {\n this.stop();\n const target = this.fitState(box);\n if (\n typeof matchMedia === 'undefined' ||\n matchMedia('(prefers-reduced-motion: reduce)').matches\n ) {\n this.set(target);\n return;\n }\n const initial = this.state;\n const started = performance.now();\n const step = (now: number) => {\n const progress = Math.min(1, (now - started) / 280);\n const ease = 1 - (1 - progress) ** 3;\n this.set({\n x: initial.x + (target.x - initial.x) * ease,\n y: initial.y + (target.y - initial.y) * ease,\n zoom: initial.zoom + (target.zoom - initial.zoom) * ease,\n });\n if (progress < 1) this.animation = requestAnimationFrame(step);\n else this.animation = 0;\n };\n this.animation = requestAnimationFrame(step);\n }\n private stop(): void {\n if (this.animation) cancelAnimationFrame(this.animation);\n this.animation = 0;\n }\n onChange(callback: (state: LensState) => void): () => void {\n this.listeners.add(callback);\n return () => this.listeners.delete(callback);\n }\n destroy(): void {\n this.stop();\n this.observer?.disconnect();\n this.listeners.clear();\n }\n}\n","function svgCursor(markup: string, size: number, hotspot: number[], fallback: string) {\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\">${markup}</svg>`;\n return `url(\"data:image/svg+xml,${encodeURIComponent(svg)}\") ${hotspot.join(' ')}, ${fallback}`;\n}\n\nexport const cursorArrow =\n 'M8.5 6.5c-1.3-.5-2.5.7-2 2l6.1 19.4c.5 1.6 2.7 1.7 3.3.1l3.1-8a1.5 1.5 0 0 1 .9-.9l8-3.1c1.6-.6 1.5-2.8-.1-3.3Z';\n\n// Native cursor artwork stays outside the document and tracks the hardware pointer.\nexport const selectionCursor = svgCursor(\n `<defs><radialGradient id=\"a\"><stop stop-color=\"#c4b5fd\" stop-opacity=\".22\"/><stop offset=\"1\" stop-color=\"#c4b5fd\" stop-opacity=\"0\"/></radialGradient></defs><circle cx=\"17\" cy=\"18\" r=\"18\" fill=\"url(#a)\"/><path d=\"${cursorArrow}\" fill=\"none\" stroke=\"#b9a6e6\" stroke-width=\"5\" stroke-opacity=\".14\" stroke-linejoin=\"round\"/><path d=\"${cursorArrow}\" fill=\"#18252a\" stroke=\"#fff\" stroke-width=\"2\" stroke-linejoin=\"round\"/>`,\n 36,\n [7, 7],\n 'default',\n);\n\nconst cross = 'M14 4v6m0 8v6M4 14h6m8 0h6';\nexport const drawingCursor = svgCursor(\n `<circle cx=\"14\" cy=\"14\" r=\"10\" fill=\"#c4b5fd\" fill-opacity=\".06\"/><path d=\"${cross}\" stroke=\"#b9a6e6\" stroke-opacity=\".15\" stroke-width=\"6\" stroke-linecap=\"round\"/><path d=\"${cross}\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\"/><path d=\"${cross}\" stroke=\"#18252a\" stroke-width=\"1.7\" stroke-linecap=\"round\"/><circle cx=\"14\" cy=\"14\" r=\"1\" fill=\"#18252a\"/>`,\n 28,\n [14, 14],\n 'crosshair',\n);\n\nexport function cursorForTool(\n tool: string,\n state: { space?: boolean; readonly?: boolean; panning?: boolean } = {},\n) {\n if (state.panning) return 'grabbing';\n if (state.space || state.readonly || tool === 'hand') return 'grab';\n if (tool === 'text') return 'text';\n return tool === 'select' ? selectionCursor : drawingCursor;\n}\n","import type { AgentPresenceOptions, Box, Point } from '../core/types';\nimport { cursorArrow } from '../input/cursors';\nimport type { Lens } from './lens';\nimport { esc } from './paint';\n\ninterface Placement {\n box: Box;\n elements: HTMLElement[];\n}\n\n/** Presentation only: documents, exports and history commit before the cursor arrives. */\nexport class AgentPresence {\n private queue: Placement[] = [];\n private pending = new Set<HTMLElement>();\n private restore = new Map<HTMLElement, () => void>();\n private cursor?: HTMLElement;\n private name?: string;\n private frame = 0;\n private tick = 0;\n private generation = 0;\n private running = false;\n private motion = matchMedia('(prefers-reduced-motion: reduce)');\n private quiet = () => matchMedia('(prefers-reduced-motion: reduce)').matches || document.hidden;\n private preference = () => {\n if (this.quiet()) this.clear();\n };\n\n private maxStops: number;\n private durationScale: number;\n private idle = new Set<() => void>();\n\n constructor(\n private root: HTMLElement,\n private lens: Lens,\n options: AgentPresenceOptions = {},\n ) {\n this.maxStops = Math.max(1, options.maxStops ?? 8);\n this.durationScale = Math.min(2, Math.max(0.25, options.durationScale ?? 1));\n this.motion.addEventListener('change', this.preference);\n document.addEventListener('visibilitychange', this.preference);\n }\n\n holds(element: HTMLElement) {\n return this.pending.has(element);\n }\n\n busy() {\n return this.running || this.frame !== 0 || this.pending.size > 0;\n }\n\n whenIdle(callback: () => void) {\n if (!this.busy()) {\n callback();\n return;\n }\n this.idle.add(callback);\n }\n\n enqueue(placements: Placement[], name?: string) {\n if (this.quiet()) return;\n const label = name?.trim();\n if (label && !this.name) this.name = label;\n for (const placement of placements) {\n placement.elements = placement.elements.filter((element) => !this.pending.has(element));\n if (!placement.elements.length) continue;\n for (const element of placement.elements) {\n element.classList.add('ad-agent-pending');\n element.tabIndex = -1;\n this.pending.add(element);\n }\n this.queue.push(placement);\n }\n if (!this.running && !this.frame && this.queue.length)\n this.frame = requestAnimationFrame(() => {\n this.frame = 0;\n void this.run(this.generation).catch(() => this.clear());\n });\n }\n\n /** Drop items that left the document; keep the walk going for what remains. */\n prune() {\n let dropped = false;\n for (const element of [...this.pending]) {\n if (element.isConnected) continue;\n dropped = true;\n this.restore.get(element)?.();\n this.restore.delete(element);\n this.pending.delete(element);\n }\n const keep = (placement: Placement) => {\n placement.elements = placement.elements.filter((element) => this.pending.has(element));\n return placement.elements.length > 0;\n };\n this.queue = this.queue.filter(keep);\n if (!this.pending.size && (dropped || (!this.running && !this.frame))) this.clear();\n }\n\n clear() {\n this.generation++;\n cancelAnimationFrame(this.frame);\n cancelAnimationFrame(this.tick);\n this.frame = 0;\n this.tick = 0;\n for (const restore of this.restore.values()) restore();\n this.restore.clear();\n for (const element of this.pending) {\n element.classList.remove('ad-agent-pending');\n if (element.tabIndex < 0) element.tabIndex = 0;\n }\n this.pending.clear();\n this.queue = [];\n this.cursor?.remove();\n this.cursor = undefined;\n this.name = undefined;\n this.running = false;\n const callbacks = [...this.idle];\n this.idle.clear();\n for (const callback of callbacks) callback();\n }\n\n destroy() {\n this.clear();\n this.motion.removeEventListener('change', this.preference);\n document.removeEventListener('visibilitychange', this.preference);\n }\n\n private async play(generation: number, duration: number, frame: (t: number) => void) {\n if (generation !== this.generation) return;\n if (this.quiet() || duration <= 0) {\n frame(1);\n return;\n }\n let started = 0;\n await new Promise<void>((resolve) => {\n const step = (now: number) => {\n if (generation !== this.generation) {\n this.tick = 0;\n resolve();\n return;\n }\n if (!started) started = now;\n const t = Math.min(1, (now - started) / duration);\n frame(1 - (1 - t) ** 3);\n if (t < 1) this.tick = requestAnimationFrame(step);\n else {\n this.tick = 0;\n resolve();\n }\n };\n this.tick = requestAnimationFrame(step);\n });\n }\n\n private edge(point: Point): Point {\n const { width, height } = this.lens;\n return [\n { x: -70, y: point.y + 40 },\n { x: width + 70, y: point.y - 40 },\n { x: point.x - 40, y: -70 },\n { x: point.x + 40, y: height + 70 },\n ].sort(\n (a, b) => Math.hypot(a.x - point.x, a.y - point.y) - Math.hypot(b.x - point.x, b.y - point.y),\n )[0];\n }\n\n private transform(point: Point) {\n return `translate(${point.x - 7}px,${point.y - 7}px)`;\n }\n\n /** Screen-pixel hotspot. Some engines leave getBoundingClientRect at the start. */\n private put(cursor: HTMLElement, point: Point) {\n cursor.style.transform = this.transform(point);\n cursor.dataset.adAt = `${point.x},${point.y}`;\n }\n\n private center(box: Box): Point {\n return { x: box.x + box.w / 2, y: box.y + box.h / 2 };\n }\n\n private async move(generation: number, cursor: HTMLElement, fromPage: Point, toPage: Point) {\n const from0 = this.lens.toScreen(fromPage);\n const to0 = this.lens.toScreen(toPage);\n const distance = Math.hypot(to0.x - from0.x, to0.y - from0.y);\n await this.play(generation, Math.min(650, 320 + distance * 0.35) * this.durationScale, (t) => {\n const from = this.lens.toScreen(fromPage);\n const to = this.lens.toScreen(toPage);\n const bend = Math.min(36, Math.hypot(to.x - from.x, to.y - from.y) / 8);\n const s = 1 - t;\n this.put(cursor, {\n x: s * s * from.x + 2 * s * t * ((from.x + to.x) / 2 + bend) + t * t * to.x,\n y: s * s * from.y + 2 * s * t * ((from.y + to.y) / 2 - bend) + t * t * to.y,\n });\n });\n if (generation === this.generation) this.put(cursor, this.lens.toScreen(toPage));\n }\n\n private connector(placement: Placement) {\n return (\n placement.elements.length > 0 &&\n placement.elements.every((element) => element.dataset.adKind === 'connector')\n );\n }\n\n private onScreen(placement: Placement) {\n const corner = this.lens.toScreen(placement.box);\n const right = corner.x + placement.box.w * this.lens.zoom;\n const bottom = corner.y + placement.box.h * this.lens.zoom;\n const { width, height } = this.lens;\n return right >= 0 && bottom >= 0 && corner.x <= width && corner.y <= height;\n }\n\n private visitable(placement: Placement) {\n return (\n placement.elements.some((element) => element.isConnected) &&\n !this.connector(placement) &&\n this.onScreen(placement)\n );\n }\n\n private take(list: Placement[]) {\n return list.splice(0).flatMap((entry) => entry.elements);\n }\n\n private show(generation: number, element: HTMLElement) {\n if (!this.pending.has(element)) return;\n element.classList.remove('ad-agent-pending');\n element.tabIndex = 0;\n this.pending.delete(element);\n this.reveal(generation, element);\n }\n\n private reveal(generation: number, element: HTMLElement) {\n const opacity = element.style.opacity || '1';\n const transform = element.style.transform;\n const to = Number(opacity);\n const restore = () => {\n element.style.opacity = opacity;\n element.style.transform = transform;\n };\n this.restore.set(element, restore);\n void this.play(generation, 220 * this.durationScale, (t) => {\n element.style.opacity = String(to * t);\n if (element.dataset.adKind !== 'connector')\n element.style.transform = `${transform} scale(${0.97 + 0.03 * t})`;\n }).then(() => {\n if (generation !== this.generation) return;\n restore();\n this.restore.delete(element);\n });\n }\n\n private async run(generation: number): Promise<void> {\n this.running = true;\n let position: Point | undefined;\n let stops = 0;\n const deferred: Placement[] = [];\n while (this.queue.length && generation === this.generation) {\n if (this.quiet()) {\n this.clear();\n return;\n }\n this.prune();\n if (generation !== this.generation) return;\n const placement = this.queue.shift();\n if (!placement) break;\n if (!this.visitable(placement)) {\n deferred.push(placement);\n continue;\n }\n const last = ++stops >= this.maxStops || !this.queue.some((entry) => this.visitable(entry));\n if (last) placement.elements.push(...this.take(deferred), ...this.take(this.queue));\n const target = this.center(placement.box);\n if (!this.cursor) {\n this.cursor = document.createElement('div');\n this.cursor.className = 'ad-agent-cursor';\n this.cursor.setAttribute('aria-hidden', 'true');\n this.cursor.innerHTML = `<svg width=\"36\" height=\"36\" viewBox=\"0 0 36 36\"><path d=\"${cursorArrow}\"/></svg>${this.name ? `<span>${esc(this.name)}</span>` : ''}`;\n const edge = this.edge(this.lens.toScreen(target));\n position = this.lens.toPage(edge);\n this.put(this.cursor, edge);\n this.cursor.dataset.adFrom = `${edge.x},${edge.y}`;\n this.root.append(this.cursor);\n }\n const cursor = this.cursor;\n await this.move(generation, cursor, position!, target);\n if (generation !== this.generation) return;\n const landed = this.lens.toScreen(target);\n cursor.dataset.adLanded = `${landed.x},${landed.y}`;\n position = target;\n for (const element of placement.elements) this.show(generation, element);\n const svg = cursor.querySelector('svg');\n if (svg)\n await this.play(generation, 260 * this.durationScale, (t) => {\n svg.style.transform = `scale(${t < 0.35 ? 1 - (t / 0.35) * 0.1 : 0.9 + ((t - 0.35) / 0.65) * 0.1})`;\n });\n if (svg && generation === this.generation) svg.style.transform = '';\n }\n if (generation !== this.generation) return;\n if (deferred.length) {\n for (const element of this.take(deferred)) this.show(generation, element);\n }\n if (generation !== this.generation) return;\n if (this.cursor && position) {\n const leave = this.lens.toPage(this.edge(this.lens.toScreen(position)));\n await this.move(generation, this.cursor, position, leave);\n }\n if (generation !== this.generation) return;\n this.cursor?.remove();\n this.cursor = undefined;\n if (this.queue.length) return this.run(generation);\n this.clear();\n }\n}\n","import RBush from 'rbush';\nimport type { AgentPresenceOptions, AnnieDoc, Box, Item, Point } from '../core/types';\nimport { applyDraft } from '../core/item';\nimport { lockedItems } from '../core/locks';\nimport { boundsOf, boxCorners, flattenItems, itemBounds, type OutlineResolver } from '../geo/index';\nimport { createKindRegistry, type KindDef } from '../kinds/registry';\nimport { ItemView } from './itemView';\nimport { Lens } from './lens';\nimport { AgentPresence } from './presence';\nimport { color, esc, pathFromPoints, SVG_NS } from './paint';\n\nexport interface StageOptions {\n agentPresence?: boolean | AgentPresenceOptions;\n theme?: 'light' | 'dark' | 'auto';\n kinds?: KindDef[];\n sanitizeHTML?: (html: string) => string;\n}\ninterface Entry {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n id: string;\n}\ninterface RecordView {\n view: ItemView;\n entry: Entry;\n hidden: boolean;\n}\nexport class Stage {\n readonly root = document.createElement('div');\n readonly world = document.createElement('div');\n readonly overlay = document.createElementNS(SVG_NS, 'svg');\n readonly lens: Lens;\n readonly kinds: Map<string, KindDef>;\n readonly resolveOutline: OutlineResolver = (item) => this.kinds.get(item.kind)?.outline?.(item);\n private grid = document.createElement('div');\n private records = new Map<string, RecordView>();\n private lookup = new Map<string, Item>();\n private originals = new Map<string, Item>();\n private ancestors = new Map<string, string[]>();\n private locked = new Set<string>();\n private presence?: AgentPresence;\n private dependencies = new Map<string, Set<string>>();\n private previousDrafts = new Set<string>();\n private paintedTheme?: 'light' | 'dark';\n private index = new RBush<Entry>();\n private visible = new Set<string>();\n private selected: string[] = [];\n private marquee?: Box;\n private overlayMarkup = '';\n private theme: 'light' | 'dark' = 'light';\n private mediaQuery?: MediaQueryList;\n private mediaListener?: () => void;\n private settleTimer?: ReturnType<typeof setTimeout>;\n private cameraFrame = 0;\n private disposed = false;\n private doc?: AnnieDoc;\n private pageId?: string;\n private drafts?: Map<string, Partial<Item>>;\n constructor(\n readonly host: HTMLElement,\n readonly options: StageOptions = {},\n ) {\n this.kinds = createKindRegistry(options.kinds);\n this.root.className = 'ad-root';\n this.root.tabIndex = 0;\n this.root.setAttribute('role', 'application');\n this.root.setAttribute('aria-label', 'Drawing board');\n this.grid.className = 'ad-grid';\n this.world.className = 'ad-world';\n this.overlay.classList.add('ad-overlay');\n this.overlay.setAttribute('aria-label', 'Selection controls');\n this.root.append(this.grid, this.world, this.overlay);\n host.append(this.root);\n this.lens = new Lens(this.root);\n this.lens.onChange(() => {\n if (!this.cameraFrame)\n this.cameraFrame = requestAnimationFrame(() => {\n this.cameraFrame = 0;\n this.updateCamera();\n });\n });\n if (typeof matchMedia !== 'undefined') {\n this.mediaQuery = matchMedia('(prefers-color-scheme: dark)');\n this.mediaListener = () => {\n if (!options.theme || options.theme === 'auto') this.setTheme('auto');\n };\n this.mediaQuery.addEventListener('change', this.mediaListener);\n }\n this.setTheme(options.theme ?? 'light');\n this.updateCamera();\n }\n setTheme(theme: 'light' | 'dark' | 'auto'): void {\n this.options.theme = theme;\n this.theme = theme === 'auto' ? (this.mediaQuery?.matches ? 'dark' : 'light') : theme;\n this.root.dataset.theme = this.theme;\n if (this.doc && this.pageId) this.render(this.doc, this.pageId, this.drafts);\n }\n get resolvedTheme(): 'light' | 'dark' {\n return this.theme;\n }\n whenPresentationIdle(callback: () => void) {\n if (!this.presence) callback();\n else this.presence.whenIdle(callback);\n }\n present(ids: string[], name?: string) {\n if (this.options.agentPresence === false) return;\n const added = new Set(ids);\n const placements = ids\n .filter((id) => !this.ancestors.get(id)?.some((id) => added.has(id)))\n .flatMap((id) => {\n const record = this.records.get(id),\n item = this.lookup.get(id);\n if (!record || !item || record.hidden) return [];\n return [\n {\n box: record.view.bounds,\n elements: flattenItems([item]).flatMap((child) => {\n const record = this.records.get(child.id);\n return record && !record.hidden ? [record.view.element] : [];\n }),\n },\n ];\n });\n if (placements.length) {\n this.presence ??= new AgentPresence(\n this.root,\n this.lens,\n typeof this.options.agentPresence === 'object' ? this.options.agentPresence : undefined,\n );\n this.presence.enqueue(placements, name);\n }\n }\n finishPresentation() {\n this.presence?.clear();\n }\n prunePresentation() {\n this.presence?.prune();\n }\n isPending(id: string) {\n const element = this.records.get(id)?.view.element;\n return !!element && !!this.presence?.holds(element);\n }\n render(doc: AnnieDoc, pageId: string, drafts?: Map<string, Partial<Item>>): void {\n if (this.disposed) return;\n const incremental =\n this.doc === doc && this.pageId === pageId && this.paintedTheme === this.theme;\n this.doc = doc;\n this.pageId = pageId;\n this.drafts = drafts;\n if (incremental) {\n this.renderDrafts(drafts);\n return;\n }\n this.paintedTheme = this.theme;\n const page = doc.pages.find((candidate) => candidate.id === pageId);\n this.root.style.backgroundColor = color(\n page?.background ?? (this.theme === 'dark' ? '#122f32' : '#fbfcfa'),\n this.theme,\n );\n const entries: { item: Item; hidden: boolean }[] = [];\n this.lookup.clear();\n this.originals.clear();\n this.ancestors.clear();\n this.dependencies.clear();\n const walk = (items: Item[], parents: Item[], parentHidden: boolean) => {\n for (const original of items) {\n const item = applyDraft(original, drafts?.get(original.id));\n const hidden = parentHidden || !!item.hidden;\n this.lookup.set(item.id, item);\n this.originals.set(item.id, original);\n this.ancestors.set(\n item.id,\n parents.map((parent) => parent.id),\n );\n if (item.kind === 'connector')\n for (const endpoint of [item.from, item.to]) {\n if (!endpoint || !('item' in endpoint)) continue;\n const dependents = this.dependencies.get(endpoint.item) ?? new Set<string>();\n dependents.add(item.id);\n this.dependencies.set(endpoint.item, dependents);\n }\n entries.push({ item, hidden });\n if (item.children) walk(item.children, [...parents, item], hidden);\n }\n };\n walk(page?.items ?? [], [], false);\n this.locked = lockedItems(page?.items ?? []);\n const retained = new Set<string>();\n for (let order = 0; order < entries.length; order++) {\n const { item, hidden } = entries[order];\n retained.add(item.id);\n let record = this.records.get(item.id);\n const box = itemBounds(item, this.lookup, this.resolveOutline);\n const entry = {\n minX: box.x,\n minY: box.y,\n maxX: box.x + box.w,\n maxY: box.y + box.h,\n id: item.id,\n };\n if (!record) {\n const view = new ItemView(item.id);\n record = { view, entry, hidden };\n this.records.set(item.id, record);\n this.index.insert(entry);\n } else if (\n record.entry.minX !== entry.minX ||\n record.entry.minY !== entry.minY ||\n record.entry.maxX !== entry.maxX ||\n record.entry.maxY !== entry.maxY\n ) {\n this.index.remove(record.entry);\n record.entry = entry;\n this.index.insert(entry);\n }\n record.hidden = hidden;\n record.view.bounds = box;\n record.view.paint(\n item,\n doc,\n this.lookup,\n this.theme,\n this.kinds.get(item.kind),\n this.options.sanitizeHTML,\n this.resolveOutline,\n );\n if (record.view.element.style.zIndex !== String(order))\n record.view.element.style.zIndex = String(order);\n }\n for (const [id, record] of this.records) {\n if (retained.has(id)) continue;\n this.index.remove(record.entry);\n record.view.destroy();\n this.records.delete(id);\n this.visible.delete(id);\n }\n // DOM order follows reading order; explicit stacking preserves the document's paint order.\n const readingOrder = entries\n .map(({ item }) => this.records.get(item.id)!)\n .sort((a, b) => a.view.bounds.y - b.view.bounds.y || a.view.bounds.x - b.view.bounds.x);\n for (let position = 0; position < readingOrder.length; position++) {\n const element = readingOrder[position].view.element;\n if (this.world.children[position] !== element)\n this.world.insertBefore(element, this.world.children[position] ?? null);\n }\n this.previousDrafts = new Set(drafts?.keys());\n this.updateCulling();\n this.paintOverlay();\n this.presence?.prune();\n }\n private renderDrafts(drafts?: Map<string, Partial<Item>>): void {\n const dirty = new Set([...this.previousDrafts, ...(drafts?.keys() ?? [])]);\n for (const id of dirty) {\n const original = this.originals.get(id);\n if (!original) continue;\n const patch = drafts?.get(id);\n this.lookup.set(id, applyDraft(original, patch));\n for (const ancestor of this.ancestors.get(id) ?? []) dirty.add(ancestor);\n if (original.children)\n for (const child of flattenItems(original.children)) dirty.add(child.id);\n }\n for (const id of [...dirty])\n for (const dependent of this.dependencies.get(id) ?? []) dirty.add(dependent);\n for (const id of dirty) {\n const item = this.lookup.get(id),\n record = this.records.get(id);\n if (!item || !record) continue;\n const box = itemBounds(item, this.lookup, this.resolveOutline);\n const entry = { minX: box.x, minY: box.y, maxX: box.x + box.w, maxY: box.y + box.h, id };\n if (JSON.stringify(entry) !== JSON.stringify(record.entry)) {\n this.index.remove(record.entry);\n this.index.insert(entry);\n record.entry = entry;\n }\n record.view.bounds = box;\n const parents = (this.ancestors.get(id) ?? [])\n .map((parent) => this.lookup.get(parent)!)\n .filter(Boolean);\n record.hidden = !!item.hidden || parents.some((parent) => parent.hidden);\n record.view.paint(\n item,\n this.doc!,\n this.lookup,\n this.theme,\n this.kinds.get(item.kind),\n this.options.sanitizeHTML,\n this.resolveOutline,\n );\n }\n this.previousDrafts = new Set(drafts?.keys());\n if (dirty.size) {\n this.updateCulling();\n this.paintOverlay();\n }\n this.presence?.prune();\n }\n setSelection(ids: string[]): void {\n if (\n ids.length === this.selected.length &&\n ids.every((id, index) => id === this.selected[index])\n )\n return;\n const previous = new Set(this.selected);\n this.selected = [...ids];\n for (const id of previous)\n if (!ids.includes(id)) this.records.get(id)?.view.element.removeAttribute('data-ad-selected');\n for (const id of ids)\n this.records.get(id)?.view.element.setAttribute('data-ad-selected', 'true');\n this.paintOverlay();\n }\n setMarquee(box?: Box): void {\n this.marquee = box;\n this.paintOverlay();\n }\n private updateCamera(): void {\n const { x, y, zoom } = this.lens.state;\n this.world.style.transform = `translate3d(${x}px,${y}px,0) scale(${zoom})`;\n this.world.style.willChange = 'transform';\n clearTimeout(this.settleTimer);\n this.settleTimer = setTimeout(() => {\n this.world.style.willChange = '';\n }, 150);\n const gridSize = 24 * zoom * (zoom < 0.3 ? 4 : zoom < 0.6 ? 2 : 1);\n this.grid.style.backgroundSize = `${gridSize}px ${gridSize}px`;\n this.grid.style.backgroundPosition = `${x}px ${y}px`;\n this.updateCulling();\n this.paintOverlay();\n }\n private updateCulling(): void {\n const viewport = this.lens.viewport(200);\n const candidates = this.index.search({\n minX: viewport.x,\n minY: viewport.y,\n maxX: viewport.x + viewport.w,\n maxY: viewport.y + viewport.h,\n });\n const visible = new Set(\n candidates\n .filter((candidate) => !this.records.get(candidate.id)?.hidden)\n .map((candidate) => candidate.id),\n );\n for (const id of this.visible) {\n if (!visible.has(id)) {\n const record = this.records.get(id);\n if (record) record.view.element.style.display = 'none';\n }\n }\n for (const id of visible) {\n if (!this.visible.has(id)) {\n const record = this.records.get(id);\n if (record) record.view.element.style.display = '';\n }\n }\n this.visible = visible;\n }\n private paintOverlay(): void {\n const parts: string[] = [];\n const items = this.selected\n .map((id) => this.lookup.get(id))\n .filter((item): item is Item => !!item && !item.hidden);\n if (items.length) {\n const single =\n items.length === 1 && !['connector', 'line', 'path', 'group'].includes(items[0].kind);\n const box = single ? items[0] : boundsOf(items, this.lookup, this.resolveOutline);\n const rotation = single ? (items[0].rotation ?? 0) : 0;\n const points = boxCorners(box, rotation).map((point) => this.lens.toScreen(point));\n parts.push(`<path class=\"ad-selection-outline\" d=\"${pathFromPoints(points, true)}\"/>`);\n const positions: [string, Point, string][] = [\n ['nw', points[0], 'nwse-resize'],\n [\n 'n',\n { x: (points[0].x + points[1].x) / 2, y: (points[0].y + points[1].y) / 2 },\n 'ns-resize',\n ],\n ['ne', points[1], 'nesw-resize'],\n [\n 'e',\n { x: (points[1].x + points[2].x) / 2, y: (points[1].y + points[2].y) / 2 },\n 'ew-resize',\n ],\n ['se', points[2], 'nwse-resize'],\n [\n 's',\n { x: (points[2].x + points[3].x) / 2, y: (points[2].y + points[3].y) / 2 },\n 'ns-resize',\n ],\n ['sw', points[3], 'nesw-resize'],\n [\n 'w',\n { x: (points[3].x + points[0].x) / 2, y: (points[3].y + points[0].y) / 2 },\n 'ew-resize',\n ],\n ];\n if (!items.some((item) => this.locked.has(item.id))) {\n for (const [handle, point, cursor] of positions)\n parts.push(\n `<rect class=\"ad-selection-handle\" data-ad-handle=\"${handle}\" x=\"${point.x - 4}\" y=\"${point.y - 4}\" width=\"8\" height=\"8\" rx=\"2\" style=\"cursor:${cursor}\" aria-label=\"Resize ${handle}\"/>`,\n );\n {\n const top = positions[1][1];\n const theta = (rotation * Math.PI) / 180;\n const point = { x: top.x + Math.sin(theta) * 26, y: top.y - Math.cos(theta) * 26 };\n parts.push(\n `<path class=\"ad-selection-outline\" d=\"M${top.x},${top.y}L${point.x},${point.y}\"/><circle class=\"ad-selection-handle\" data-ad-handle=\"rotate\" cx=\"${point.x}\" cy=\"${point.y}\" r=\"4.5\" style=\"cursor:grab\" aria-label=\"Rotate\"/>`,\n );\n }\n }\n }\n if (items.length === 1 && !this.locked.has(items[0].id)) {\n const item = items[0],\n handles = this.kinds.get(item.kind)?.handles?.(item) ?? [];\n const angle = ((item.rotation ?? 0) * Math.PI) / 180;\n for (const handle of handles) {\n const dx = handle.x - item.w / 2,\n dy = handle.y - item.h / 2;\n const point = this.lens.toScreen({\n x: item.x + item.w / 2 + dx * Math.cos(angle) - dy * Math.sin(angle),\n y: item.y + item.h / 2 + dx * Math.sin(angle) + dy * Math.cos(angle),\n });\n parts.push(\n `<circle class=\"ad-selection-handle ad-custom-handle\" data-ad-custom-handle=\"${esc(handle.id)}\" data-ad-handle=\"custom:${esc(handle.id)}\" cx=\"${point.x}\" cy=\"${point.y}\" r=\"5\" style=\"cursor:${esc(handle.cursor ?? 'crosshair')}\" aria-label=\"${esc(handle.label ?? handle.id)}\"/>`,\n );\n }\n }\n if (this.marquee) {\n const p = this.lens.toScreen(this.marquee);\n parts.push(\n `<rect class=\"ad-marquee\" x=\"${p.x}\" y=\"${p.y}\" width=\"${Math.max(0, this.marquee.w * this.lens.zoom)}\" height=\"${Math.max(0, this.marquee.h * this.lens.zoom)}\"/>`,\n );\n }\n const markup = parts.join('');\n if (markup !== this.overlayMarkup) {\n this.overlayMarkup = markup;\n this.overlay.innerHTML = markup;\n }\n }\n destroy(): void {\n this.disposed = true;\n this.presence?.destroy();\n clearTimeout(this.settleTimer);\n cancelAnimationFrame(this.cameraFrame);\n if (this.mediaQuery && this.mediaListener)\n this.mediaQuery.removeEventListener('change', this.mediaListener);\n this.lens.destroy();\n for (const record of this.records.values()) record.view.destroy();\n this.records.clear();\n this.index.clear();\n this.root.remove();\n }\n}\n","import { CARD_CORNER } from '../core/defaults';\nimport { allItems } from '../core/item';\nimport { hostnameOf, normalizeHref, parseVideo } from '../core/links';\nimport type { AnnieDoc, Box, ExportOptions, Item } from '../core/types';\nimport { boundsOf, flattenItems, routeConnector } from '../geo/index';\nimport { createKindRegistry, type KindDef } from '../kinds/registry';\nimport {\n color,\n esc,\n fontFamily,\n fonts,\n fontSize,\n headsMarkup,\n shapeMarkup,\n labelColor,\n round,\n} from '../stage/paint';\n\nexport interface SVGExportOptions extends ExportOptions {\n theme?: 'light' | 'dark';\n bounds?: Box;\n kinds?: KindDef[];\n}\nfunction wrapText(value: string, width: number, size: number): string[] {\n const maxChars = Math.max(1, Math.floor(width / (size * 0.53)));\n const result: string[] = [];\n for (const paragraph of value.split('\\n')) {\n if (!paragraph) {\n result.push('');\n continue;\n }\n let line = '';\n for (const word of paragraph.split(/\\s+/)) {\n if (line && line.length + word.length + 1 > maxChars) {\n result.push(line);\n line = '';\n }\n let remaining = word;\n while (remaining.length > maxChars) {\n if (line) {\n result.push(line);\n line = '';\n }\n result.push(remaining.slice(0, maxChars));\n remaining = remaining.slice(maxChars);\n }\n line += `${line ? ' ' : ''}${remaining}`;\n }\n result.push(line);\n }\n return result;\n}\nfunction textMarkup(\n item: Item,\n theme: 'light' | 'dark',\n connectorPoint?: { x: number; y: number },\n): string {\n if (!item.text?.value) return '';\n const size = fontSize(item.text);\n const padding = item.kind === 'text' ? 0 : item.kind === 'note' ? 20 : 12;\n const width = connectorPoint\n ? 220\n : item.w * (item.kind === 'diamond' ? 0.6 : item.kind === 'ellipse' ? 0.75 : 1) - padding * 2;\n const lines = wrapText(item.text.value, width, size);\n const lineHeight = size * 1.35;\n const align = item.text.align ?? (item.kind === 'text' ? 'start' : 'center');\n const anchor = align === 'start' ? 'start' : align === 'end' ? 'end' : 'middle';\n const x =\n connectorPoint?.x ??\n (align === 'start' ? padding : align === 'end' ? item.w - padding : item.w / 2);\n const textHeight = lines.length * lineHeight;\n const y = connectorPoint\n ? connectorPoint.y - textHeight / 2 + size\n : item.text.valign === 'top'\n ? padding + size\n : item.text.valign === 'bottom'\n ? item.h - padding - textHeight + size\n : (item.h - textHeight) / 2 + size;\n const longest = Math.max(...lines.map((line) => line.length)) * size * 0.53;\n const label = connectorPoint\n ? `<rect x=\"${x - longest / 2 - 7}\" y=\"${connectorPoint.y - textHeight / 2 - 2}\" width=\"${longest + 14}\" height=\"${textHeight + 4}\" rx=\"4\" fill=\"${color('paper', theme)}\"/>`\n : '';\n return `${label}<text x=\"${x}\" y=\"${y}\" font-family=\"${esc(fontFamily(item.text.font))}\" font-size=\"${size}\" text-anchor=\"${connectorPoint ? 'middle' : anchor}\" fill=\"${esc(labelColor(item, theme))}\">${lines.map((line, index) => `<tspan x=\"${x}\" dy=\"${index ? lineHeight : 0}\">${esc(line) || ' '}</tspan>`).join('')}</text>`;\n}\n\nfunction fitLine(value: string, width: number, size: number): string {\n const max = Math.max(1, Math.floor(width / (size * 0.52)));\n const text = value.trim();\n return text.length <= max ? text : `${text.slice(0, Math.max(1, max - 1))}…`;\n}\n\nfunction hrefLine(href?: string): string {\n const url = normalizeHref(href);\n if (!url) return '';\n try {\n const parsed = new URL(url);\n const path = decodeURIComponent(parsed.pathname).replace(/\\/$/, '');\n const line = `${hostnameOf(url)}${path}`;\n return parsed.search && line.length < 36 ? `${line}${parsed.search}` : line;\n } catch {\n return url.replace(/^https?:\\/\\//, '').replace(/\\/$/, '');\n }\n}\n\nfunction cardTitle(item: Item, href?: string): string {\n const written = item.text?.value?.trim() || item.name?.trim();\n if (written && written.toLowerCase() !== item.kind) return written;\n if (href) {\n const name = hostnameOf(href).split('.')[0] ?? '';\n if (name) return name[0].toUpperCase() + name.slice(1);\n }\n return item.kind === 'video' ? 'Video' : 'Link';\n}\n\nfunction cardLink(href: string | undefined, inner: string): string {\n const url = normalizeHref(href);\n return url\n ? `<a href=\"${esc(url)}\" target=\"_blank\" rel=\"noopener noreferrer\" style=\"text-decoration:none\">${inner}</a>`\n : inner;\n}\n\nfunction cardExport(item: Item, theme: 'light' | 'dark', doc: AnnieDoc, index: number): string {\n const r = Math.min(item.style?.corner ?? CARD_CORNER, item.w / 2, item.h / 2);\n const w = item.w,\n h = item.h,\n uid = `adx${index}`,\n face = fonts.sans,\n href = item.href,\n title = cardTitle(item, href),\n url = hrefLine(href),\n pad = Math.max(10, Math.min(14, w * 0.04));\n const clip = `<defs><clipPath id=\"${uid}p\"><rect width=\"${w}\" height=\"${h}\" rx=\"${r}\"/></clipPath></defs>`;\n if (item.kind === 'video') {\n const video = parseVideo(href);\n const provider = video?.provider === 'vimeo' ? 'Vimeo' : video ? 'YouTube' : '';\n const play = Math.min(w, h) * 0.11,\n poster = h >= 96 ? h * 0.58 : h,\n cx = w / 2 + play * 0.06,\n cy = h / 2;\n const label = fitLine(title, w - pad * 2, 15);\n const source = fitLine(url, w - pad * 2, 12);\n return `${clip}<defs>\n <linearGradient id=\"${uid}g\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\"><stop offset=\"0\" stop-color=\"#16494c\"/><stop offset=\"1\" stop-color=\"#103639\"/></linearGradient>\n <radialGradient id=\"${uid}s\" cx=\"50%\" cy=\"50%\" r=\"58%\"><stop offset=\"0\" stop-color=\"#05D9AB\" stop-opacity=\".2\"/><stop offset=\"1\" stop-color=\"#103639\" stop-opacity=\"0\"/></radialGradient>\n <linearGradient id=\"${uid}c\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0\" stop-color=\"#103639\" stop-opacity=\"0\"/><stop offset=\"1\" stop-color=\"#103639\" stop-opacity=\".92\"/></linearGradient>\n </defs>${cardLink(\n href,\n `<g clip-path=\"url(#${uid}p)\">\n <rect width=\"${w}\" height=\"${h}\" fill=\"url(#${uid}g)\"/><rect width=\"${w}\" height=\"${h}\" fill=\"url(#${uid}s)\"/>\n <circle cx=\"${round(w / 2)}\" cy=\"${round(cy)}\" r=\"${round(play * 1.7)}\" fill=\"#fff\" fill-opacity=\".1\"/>\n <path d=\"M${round(cx - play * 0.36)} ${round(cy - play * 0.7)}L${round(cx + play * 0.7)} ${round(cy)}L${round(cx - play * 0.36)} ${round(cy + play * 0.7)}Z\" fill=\"#fff\"/>\n ${h >= 96 ? `<rect y=\"${round(poster)}\" width=\"${w}\" height=\"${round(h - poster)}\" fill=\"url(#${uid}c)\"/>` : ''}\n ${provider && h >= 120 ? `<text x=\"${pad}\" y=\"${pad + 10}\" fill=\"#05D9AB\" font-family=\"${esc(face)}\" font-size=\"11\" font-weight=\"700\">${provider}</text>` : ''}\n <text x=\"${pad}\" y=\"${h - (source ? 28 : 16)}\" fill=\"#fff\" font-family=\"${esc(face)}\" font-size=\"15\" font-weight=\"700\">${esc(label)}</text>\n ${source ? `<text x=\"${pad}\" y=\"${h - 12}\" fill=\"#B6C5C1\" font-family=\"${esc(face)}\" font-size=\"12\">${esc(source)}</text>` : ''}\n </g>`,\n )}`;\n }\n const mediaH = h >= 118 ? Math.min(h * 0.48, h - 62) : 0;\n const media = item.media ? doc.media[item.media] : undefined;\n const mark = title.trim().slice(0, 1).toUpperCase() || '•';\n const preview = !mediaH\n ? ''\n : media\n ? `<image width=\"${w}\" height=\"${mediaH}\" href=\"${esc(media.src)}\" preserveAspectRatio=\"xMidYMid slice\"/>`\n : `<rect width=\"${w}\" height=\"${mediaH}\" fill=\"#8F93F914\"/><text x=\"${w / 2}\" y=\"${mediaH / 2 + 11}\" text-anchor=\"middle\" fill=\"#8F93F9\" font-family=\"${esc(face)}\" font-size=\"${Math.min(34, mediaH * 0.28)}\" font-weight=\"700\">${esc(mark)}</text>`;\n const body = mediaH ? mediaH + 20 : 24;\n const label = fitLine(title, w - pad * 2, 15);\n const source = fitLine(url, w - pad * 2, 12);\n const note =\n item.description && h - mediaH > 78 ? fitLine(item.description, w - pad * 2, 12) : '';\n const edge = theme === 'dark' ? '#ffffff14' : '#10363914';\n return `${clip}${cardLink(\n href,\n `<g clip-path=\"url(#${uid}p)\">\n <rect width=\"${w}\" height=\"${h}\" fill=\"${color('paper', theme)}\"/>${preview}\n <text x=\"${pad}\" y=\"${body}\" fill=\"${color('ink', theme)}\" font-family=\"${esc(face)}\" font-size=\"15\" font-weight=\"700\">${esc(label)}</text>\n ${source ? `<text x=\"${pad}\" y=\"${body + 18}\" fill=\"${color('slate', theme)}\" font-family=\"${esc(face)}\" font-size=\"12\">${esc(source)}</text>` : ''}\n ${note ? `<text x=\"${pad}\" y=\"${body + 36}\" fill=\"${color('slate', theme)}\" font-family=\"${esc(face)}\" font-size=\"12\">${esc(note)}</text>` : ''}\n </g><rect width=\"${w}\" height=\"${h}\" rx=\"${r}\" fill=\"none\" stroke=\"${edge}\"/>`,\n )}`;\n}\n\n/** Create a portable SVG without scripts, foreignObject, or a DOM dependency. */\nexport function exportSVG(doc: AnnieDoc, items: Item[], options: SVGExportOptions = {}): string {\n const theme = options.theme ?? 'light';\n const all = allItems(doc);\n const lookup = new Map(all.map((item) => [item.id, item]));\n const kinds = createKindRegistry(options.kinds);\n const resolveOutline = (item: Item) => kinds.get(item.kind)?.outline?.(item);\n const hidden = new Set<string>();\n const walk = (nodes: Item[], inheritedHidden: boolean) => {\n for (const item of nodes) {\n if (inheritedHidden || item.hidden) hidden.add(item.id);\n if (item.children) walk(item.children, inheritedHidden || !!item.hidden);\n }\n };\n for (const page of doc.pages) walk(page.items, false);\n const seen = new Set<string>();\n const visible = flattenItems(items).filter((item) => {\n if (seen.has(item.id) || hidden.has(item.id) || item.hidden) return false;\n seen.add(item.id);\n return true;\n });\n const content =\n options.bounds ??\n (visible.length ? boundsOf(visible, lookup, resolveOutline) : { x: 0, y: 0, w: 800, h: 600 });\n const padding = Math.max(0, options.padding ?? 32);\n const box = {\n x: content.x - padding,\n y: content.y - padding - (options.labels ? 18 : 0),\n w: Math.max(1, content.w + padding * 2),\n h: Math.max(1, content.h + padding * 2 + (options.labels ? 18 : 0)),\n };\n const output: string[] = [];\n for (const [itemIndex, item] of visible.entries()) {\n let markup = '';\n const definition = kinds.get(item.kind);\n const connector =\n item.kind === 'connector' ? routeConnector(item, lookup, resolveOutline) : undefined;\n if (definition?.toSVG) {\n const custom = definition.toSVG(item, {\n doc,\n theme,\n color: (value) => color(value, theme),\n escape: esc,\n });\n markup = typeof custom === 'string' ? custom : new XMLSerializer().serializeToString(custom);\n } else if (\n ['rect', 'ellipse', 'diamond', 'note', 'line', 'path', 'connector'].includes(item.kind)\n ) {\n markup = shapeMarkup(item, theme, `export_${itemIndex}`, connector?.d);\n if (connector || item.kind === 'line')\n markup += headsMarkup(\n connector?.points ??\n (\n item.points ?? [\n [0, 0],\n [item.w, item.h],\n ]\n ).map(([x, y]) => ({ x, y })),\n item,\n theme,\n );\n } else if (item.kind === 'image') {\n const media = item.media ? doc.media[item.media] : undefined;\n const radius = Math.min(item.style?.corner ?? CARD_CORNER, item.w / 2, item.h / 2);\n const clip = `export_clip_${itemIndex}`;\n if (media) {\n const clipped =\n item.crop && item.crop.w > 0 && item.crop.h > 0\n ? `<svg width=\"${item.w}\" height=\"${item.h}\" viewBox=\"${item.crop.x} ${item.crop.y} ${item.crop.w} ${item.crop.h}\" preserveAspectRatio=\"none\" overflow=\"hidden\"><image width=\"${media.w}\" height=\"${media.h}\" href=\"${esc(media.src)}\" preserveAspectRatio=\"none\"/></svg>`\n : `<image width=\"${item.w}\" height=\"${item.h}\" href=\"${esc(media.src)}\" preserveAspectRatio=\"none\"/>`;\n markup = `<defs><clipPath id=\"${clip}\"><rect width=\"${item.w}\" height=\"${item.h}\" rx=\"${radius}\"/></clipPath></defs><g clip-path=\"url(#${clip})\">${clipped}</g>`;\n }\n } else if (item.kind === 'video' || item.kind === 'link') {\n markup = cardExport(item, theme, doc, itemIndex);\n } else if (!['text', 'group'].includes(item.kind)) {\n markup = `<rect width=\"${item.w}\" height=\"${item.h}\" rx=\"8\" fill=\"${color('paper', theme)}\" stroke=\"#8F93F9\" stroke-dasharray=\"5 4\"/><text x=\"12\" y=\"24\" fill=\"${color('ink', theme)}\" font-family=\"${esc(fonts.sans)}\" font-size=\"14\">${esc(item.kind === 'html' ? 'HTML content' : `Unknown kind: ${item.kind}`)}</text>`;\n }\n if (item.kind !== 'video' && item.kind !== 'link')\n markup += textMarkup(item, theme, connector?.midpoint);\n if (options.labels) {\n const x = connector ? connector.bounds.x : 0,\n y = connector ? connector.bounds.y - 22 : -22;\n markup += `<rect x=\"${x}\" y=\"${y}\" width=\"${item.id.length * 6.6 + 12}\" height=\"17\" rx=\"4\" fill=\"#103639\"/><text x=\"${x + 6}\" y=\"${y + 12}\" fill=\"#FFFFFF\" font-family=\"monospace\" font-size=\"10\">${esc(item.id)}</text>`;\n }\n const transform = connector\n ? ''\n : `translate(${item.x} ${item.y}) rotate(${item.rotation ?? 0} ${item.w / 2} ${item.h / 2})`;\n const group = `<g data-ad-id=\"${esc(item.id)}\" data-ad-kind=\"${esc(item.kind)}\"${transform ? ` transform=\"${transform}\"` : ''}${item.style?.opacity !== undefined ? ` opacity=\"${item.style.opacity}\"` : ''}><title>${esc(item.name ?? item.text?.value ?? item.kind)}</title>${markup}</g>`;\n output.push(group);\n }\n const background =\n options.background === false\n ? ''\n : color(typeof options.background === 'string' ? options.background : 'paper', theme);\n return `<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"${box.w}\" height=\"${box.h}\" viewBox=\"${box.x} ${box.y} ${box.w} ${box.h}\" role=\"img\" aria-label=\"${esc(doc.meta.title)}\"><title>${esc(doc.meta.title)}</title>${background ? `<rect x=\"${box.x}\" y=\"${box.y}\" width=\"${box.w}\" height=\"${box.h}\" fill=\"${esc(background)}\"/>` : ''}${output.join('')}</svg>`;\n}\n","/** Palette PNG for vision budgets. Browser `toBlob('image/png')` cannot write indexed files. */\nexport type PaletteColor = { r: number; g: number; b: number; a: number };\ntype Counted = PaletteColor & { n: number };\n\nconst CRC = new Uint32Array(256);\nfor (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n CRC[n] = c;\n}\n\nfunction crc32(parts: Uint8Array[]) {\n let c = ~0;\n for (const part of parts) for (const byte of part) c = CRC[(c ^ byte) & 255] ^ (c >>> 8);\n return ~c >>> 0;\n}\n\nfunction u32(value: number) {\n return Uint8Array.of(\n (value >>> 24) & 255,\n (value >>> 16) & 255,\n (value >>> 8) & 255,\n value & 255,\n );\n}\n\nfunction chunk(type: string, data: Uint8Array) {\n const name = Uint8Array.of(\n type.charCodeAt(0),\n type.charCodeAt(1),\n type.charCodeAt(2),\n type.charCodeAt(3),\n );\n const out = new Uint8Array(12 + data.length);\n out.set(u32(data.length));\n out.set(name, 4);\n out.set(data, 8);\n out.set(u32(crc32([name, data])), 8 + data.length);\n return out;\n}\n\nfunction rgbaKey(r: number, g: number, b: number, a: number) {\n return ((r << 24) | (g << 16) | (b << 8) | a) >>> 0;\n}\n\nfunction collect(data: Uint8ClampedArray): { colors: Counted[]; exact: boolean } {\n const map = new Map<number, Counted>();\n for (let i = 0; i < data.length; i += 4) {\n const key = rgbaKey(data[i], data[i + 1], data[i + 2], data[i + 3]);\n const hit = map.get(key);\n if (hit) hit.n++;\n else {\n if (map.size >= 4096) return { colors: collectWide(data), exact: false };\n map.set(key, { r: data[i], g: data[i + 1], b: data[i + 2], a: data[i + 3], n: 1 });\n }\n }\n return { colors: [...map.values()], exact: true };\n}\n\nfunction collectWide(data: Uint8ClampedArray): Counted[] {\n const counts = new Uint32Array(32768);\n let transparent = 0;\n for (let i = 0; i < data.length; i += 4) {\n if (data[i + 3] < 128) {\n transparent++;\n continue;\n }\n counts[((data[i] >> 3) << 10) | ((data[i + 1] >> 3) << 5) | (data[i + 2] >> 3)]++;\n }\n const colors: Counted[] = [];\n if (transparent) colors.push({ r: 0, g: 0, b: 0, a: 0, n: transparent });\n for (let key = 0; key < 32768; key++) {\n const n = counts[key];\n if (!n) continue;\n const r = (key >> 10) << 3,\n g = ((key >> 5) & 31) << 3,\n b = (key & 31) << 3;\n colors.push({ r: r | (r >> 5), g: g | (g >> 5), b: b | (b >> 5), a: 255, n });\n }\n return colors;\n}\n\nfunction channelOf(colors: Counted[]): 'r' | 'g' | 'b' | 'a' {\n let r0 = 255,\n r1 = 0,\n g0 = 255,\n g1 = 0,\n b0 = 255,\n b1 = 0,\n a0 = 255,\n a1 = 0;\n for (const color of colors) {\n if (color.r < r0) r0 = color.r;\n if (color.r > r1) r1 = color.r;\n if (color.g < g0) g0 = color.g;\n if (color.g > g1) g1 = color.g;\n if (color.b < b0) b0 = color.b;\n if (color.b > b1) b1 = color.b;\n if (color.a < a0) a0 = color.a;\n if (color.a > a1) a1 = color.a;\n }\n const r = r1 - r0,\n g = g1 - g0,\n b = b1 - b0,\n a = a1 - a0;\n if (r >= g && r >= b && r >= a) return 'r';\n if (g >= b && g >= a) return 'g';\n return b >= a ? 'b' : 'a';\n}\n\nfunction average(colors: Counted[]): PaletteColor {\n let r = 0,\n g = 0,\n b = 0,\n a = 0,\n n = 0;\n for (const color of colors) {\n r += color.r * color.n;\n g += color.g * color.n;\n b += color.b * color.n;\n a += color.a * color.n;\n n += color.n;\n }\n return {\n r: Math.round(r / n),\n g: Math.round(g / n),\n b: Math.round(b / n),\n a: Math.round(a / n),\n };\n}\n\nfunction medianCut(colors: Counted[], maxColors: number): PaletteColor[] {\n if (colors.length <= maxColors) return colors.map(({ r, g, b, a }) => ({ r, g, b, a }));\n const boxes = [colors];\n while (boxes.length < maxColors) {\n let best = -1,\n bestRange = -1;\n for (let i = 0; i < boxes.length; i++) {\n if (boxes[i].length < 2) continue;\n const channel = channelOf(boxes[i]);\n let min = 255,\n max = 0;\n for (const color of boxes[i]) {\n const value = color[channel];\n if (value < min) min = value;\n if (value > max) max = value;\n }\n const range = max - min;\n if (range > bestRange) {\n bestRange = range;\n best = i;\n }\n }\n if (best < 0) break;\n const box = boxes[best];\n const channel = channelOf(box);\n box.sort((left, right) => left[channel] - right[channel]);\n let total = 0;\n for (const color of box) total += color.n;\n let seen = 0,\n split = Math.max(1, box.length >> 1);\n for (let i = 0; i < box.length - 1; i++) {\n seen += box[i].n;\n if (seen >= total / 2) {\n split = i + 1;\n break;\n }\n }\n boxes[best] = box.slice(0, split);\n boxes.push(box.slice(split));\n }\n return boxes.map(average);\n}\n\nfunction nearest(palette: PaletteColor[], r: number, g: number, b: number, a: number) {\n let best = 0,\n bestDistance = Infinity;\n for (let i = 0; i < palette.length; i++) {\n const color = palette[i];\n const distance =\n (r - color.r) ** 2 + (g - color.g) ** 2 + (b - color.b) ** 2 + (a - color.a) ** 2;\n if (distance < bestDistance) {\n bestDistance = distance;\n best = i;\n }\n }\n return best;\n}\n\nexport function paintIndices(\n data: Uint8ClampedArray,\n palette: PaletteColor[],\n indices: Uint8Array,\n) {\n for (let i = 0, pixel = 0; i < indices.length; i++, pixel += 4) {\n const color = palette[indices[i]];\n data[pixel] = color.r;\n data[pixel + 1] = color.g;\n data[pixel + 2] = color.b;\n data[pixel + 3] = color.a;\n }\n}\n\nexport function quantizeRgba(data: Uint8ClampedArray, maxColors: number) {\n const limit = Math.min(256, Math.max(1, Math.trunc(maxColors)));\n const { colors, exact } = collect(data);\n const palette =\n exact && colors.length <= limit\n ? colors.map(({ r, g, b, a }) => ({ r, g, b, a }))\n : medianCut(colors, limit);\n const indices = new Uint8Array(data.length / 4);\n if (exact && colors.length <= limit) {\n const lookup = new Map<number, number>();\n for (let i = 0; i < palette.length; i++) {\n const color = palette[i];\n lookup.set(rgbaKey(color.r, color.g, color.b, color.a), i);\n }\n for (let i = 0, pixel = 0; i < indices.length; i++, pixel += 4)\n indices[i] = lookup.get(\n rgbaKey(data[pixel], data[pixel + 1], data[pixel + 2], data[pixel + 3]),\n )!;\n } else {\n const cache = new Map<number, number>();\n for (let i = 0, pixel = 0; i < indices.length; i++, pixel += 4) {\n const key = rgbaKey(data[pixel], data[pixel + 1], data[pixel + 2], data[pixel + 3]);\n let index = cache.get(key);\n if (index === undefined) {\n index = nearest(palette, data[pixel], data[pixel + 1], data[pixel + 2], data[pixel + 3]);\n cache.set(key, index);\n }\n indices[i] = index;\n }\n }\n return { palette, indices };\n}\n\nasync function zlib(bytes: Uint8Array) {\n if (typeof CompressionStream !== 'function') throw new Error('CompressionStream is unavailable.');\n const body = new Response(bytes as BodyInit).body;\n if (!body) throw new Error('CompressionStream is unavailable.');\n return new Uint8Array(\n await new Response(body.pipeThrough(new CompressionStream('deflate'))).arrayBuffer(),\n );\n}\n\nexport async function encodeIndexedPng(\n width: number,\n height: number,\n palette: PaletteColor[],\n indices: Uint8Array,\n): Promise<Blob> {\n if (width < 1 || height < 1 || palette.length < 1 || palette.length > 256)\n throw new Error('Indexed PNG dimensions or palette are invalid.');\n if (indices.length !== width * height) throw new Error('Indexed PNG indices do not match size.');\n const ihdr = new Uint8Array(13);\n ihdr.set(u32(width));\n ihdr.set(u32(height), 4);\n ihdr[8] = 8;\n ihdr[9] = 3;\n const plte = new Uint8Array(palette.length * 3);\n let lastAlpha = -1;\n for (let i = 0; i < palette.length; i++) {\n plte[i * 3] = palette[i].r;\n plte[i * 3 + 1] = palette[i].g;\n plte[i * 3 + 2] = palette[i].b;\n if (palette[i].a < 255) lastAlpha = i;\n }\n const rows = new Uint8Array((width + 1) * height);\n for (let y = 0; y < height; y++) {\n const row = y * (width + 1);\n rows[row] = 0;\n rows.set(indices.subarray(y * width, (y + 1) * width), row + 1);\n }\n const parts = [\n Uint8Array.of(137, 80, 78, 71, 13, 10, 26, 10),\n chunk('IHDR', ihdr),\n chunk('PLTE', plte),\n ];\n if (lastAlpha >= 0) {\n const trns = new Uint8Array(lastAlpha + 1);\n for (let i = 0; i <= lastAlpha; i++) trns[i] = palette[i].a;\n parts.push(chunk('tRNS', trns));\n }\n parts.push(chunk('IDAT', await zlib(rows)), chunk('IEND', new Uint8Array()));\n let total = 0;\n for (const part of parts) total += part.length;\n const out = new Uint8Array(total);\n let offset = 0;\n for (const part of parts) {\n out.set(part, offset);\n offset += part.length;\n }\n return new Blob([out], { type: 'image/png' });\n}\n","/** Rasterise a completed SVG; this is the library's only canvas use. */\nimport { VISION_PNG } from '../core/schema';\nimport { encodeIndexedPng, paintIndices, quantizeRgba } from './indexedPng';\nexport type RasterFormat = 'png' | 'jpeg' | 'webp';\nconst MIME: Record<RasterFormat, string> = {\n png: 'image/png',\n jpeg: 'image/jpeg',\n webp: 'image/webp',\n};\nconst QUALITY_STEPS = [0.85, 0.7, 0.55, 0.4];\nexport async function exportPNG(svg: string, scale = 2): Promise<Blob> {\n return exportRaster(svg, { format: 'png', scale });\n}\nexport async function exportRaster(\n svg: string,\n options: {\n format: RasterFormat;\n scale?: number;\n maxSide?: number;\n maxBytes?: number;\n quality?: number;\n colors?: number;\n },\n): Promise<Blob> {\n const format = options.format;\n if (typeof document === 'undefined')\n throw new Error(\n `${format.toUpperCase()} export requires a browser. Use SVG export in headless environments.`,\n );\n let scale = options.scale ?? 2;\n if (!Number.isFinite(scale) || scale <= 0 || scale > 8)\n throw new Error(\n `${format.toUpperCase()} scale must be greater than zero and no greater than 8.`,\n );\n const palette = format === 'png' && options.colors !== undefined ? options.colors : undefined;\n if (palette !== undefined && (!Number.isInteger(palette) || palette < 2 || palette > 256))\n throw new Error('PNG colors must be an integer from 2 to 256.');\n const url = URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml;charset=utf-8' }));\n try {\n const image = new Image();\n image.decoding = 'async';\n await new Promise<void>((resolve, reject) => {\n image.onload = () => resolve();\n image.onerror = () =>\n reject(\n new Error(\n 'This drawing could not be rasterised. Export SVG instead, or embed external images as data URLs.',\n ),\n );\n image.src = url;\n });\n const naturalWidth = Math.max(1, image.naturalWidth);\n const naturalHeight = Math.max(1, image.naturalHeight);\n if (options.maxSide && Number.isFinite(options.maxSide) && options.maxSide > 0) {\n const longest = Math.max(naturalWidth * scale, naturalHeight * scale);\n if (longest > options.maxSide) scale *= options.maxSide / longest;\n }\n const qualities =\n format === 'png'\n ? [1]\n : [\n Math.min(1, Math.max(0.1, options.quality ?? 0.85)),\n ...QUALITY_STEPS.filter((step) => step < (options.quality ?? 0.85)),\n ];\n const encode = async (nextScale: number, quality: number, colors?: number) => {\n const width = Math.max(1, Math.ceil(naturalWidth * nextScale));\n const height = Math.max(1, Math.ceil(naturalHeight * nextScale));\n if (width > 16384 || height > 16384 || width * height > 64_000_000)\n throw new Error(\n `${format.toUpperCase()} is too large. Export a smaller selection or reduce the scale.`,\n );\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const context = canvas.getContext('2d', colors ? { willReadFrequently: true } : undefined);\n if (!context)\n throw new Error(`This browser does not support ${format.toUpperCase()} export.`);\n context.drawImage(image, 0, 0, width, height);\n if (format === 'png' && colors) {\n const pixels = context.getImageData(0, 0, width, height);\n const quantized = quantizeRgba(pixels.data, colors);\n try {\n return await encodeIndexedPng(width, height, quantized.palette, quantized.indices);\n } catch {\n paintIndices(pixels.data, quantized.palette, quantized.indices);\n context.putImageData(pixels, 0, 0);\n }\n }\n return await new Promise<Blob>((resolve, reject) => {\n try {\n canvas.toBlob(\n (blob) =>\n blob\n ? resolve(blob)\n : reject(new Error(`The browser could not encode this ${format.toUpperCase()}.`)),\n MIME[format],\n format === 'png' ? undefined : quality,\n );\n } catch {\n reject(\n new Error(\n `An external image prevents ${format.toUpperCase()} export. Embed images as data URLs or export SVG.`,\n ),\n );\n }\n });\n };\n if (!options.maxBytes) return encode(scale, qualities[0], palette);\n let smallest: Blob | undefined;\n let nextScale = scale;\n const consider = (blob: Blob) => {\n if (!smallest || blob.size < smallest.size) smallest = blob;\n return blob.size <= options.maxBytes!;\n };\n while (nextScale >= 0.25 - 1e-9) {\n if (format === 'png') {\n if (palette === undefined && (await consider(await encode(nextScale, 1)))) return smallest!;\n if (await consider(await encode(nextScale, 1, palette ?? VISION_PNG.colors)))\n return smallest!;\n } else {\n for (const quality of qualities) {\n if (await consider(await encode(nextScale, quality))) return smallest!;\n }\n }\n const halved = nextScale / 2;\n if (halved < 0.25 - 1e-9) break;\n nextScale = halved;\n }\n return smallest ?? encode(scale, qualities[0], palette);\n } finally {\n URL.revokeObjectURL(url);\n }\n}\n","import type { Board } from '../board';\nimport type { AnnieDoc } from '../core/types';\nexport async function openAutosave(board: Board, key: string): Promise<void> {\n let db: IDBDatabase | undefined,\n timer: ReturnType<typeof setTimeout> | undefined,\n stopped = false;\n let unsubscribe = () => {};\n const initial = JSON.stringify(board.read());\n const report = (status: 'saving' | 'saved' | 'error', message?: string) => {\n if (!stopped) board.emit('save', { status, message });\n };\n const save = () => {\n if (stopped || !db) return;\n try {\n report('saving');\n const tx = db.transaction('boards', 'readwrite');\n tx.objectStore('boards').put(board.read(), key);\n tx.oncomplete = () => report('saved');\n tx.onerror = () => report('error', 'Could not save locally. Export your drawing to keep it.');\n } catch {\n report('error', 'Could not save locally. Export your drawing to keep it.');\n }\n };\n const flush = () => {\n if (timer) {\n clearTimeout(timer);\n timer = undefined;\n save();\n }\n };\n board.addCleanup(() => {\n flush();\n stopped = true;\n unsubscribe();\n window.removeEventListener('pagehide', flush);\n db?.close();\n });\n try {\n db = await new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open('anniedrawing', 1);\n request.onupgradeneeded = () => request.result.createObjectStore('boards');\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n if (stopped) {\n db.close();\n return;\n }\n const saved = await new Promise<AnnieDoc | undefined>((resolve, reject) => {\n const request = db!.transaction('boards', 'readonly').objectStore('boards').get(key);\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n if (stopped) {\n db.close();\n return;\n }\n if (saved && JSON.stringify(board.read()) === initial) board.load(saved);\n report('saved');\n } catch {\n report('error', 'Browser storage is unavailable. Export your drawing to keep it.');\n return;\n }\n unsubscribe = board.on('change', () => {\n report('saving');\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n timer = undefined;\n save();\n }, 300);\n });\n window.addEventListener('pagehide', flush);\n}\n","import type { ItemText } from '../core/types';\nimport { fontFamily, fontSize } from '../stage/paint';\nconst cache = new Map<string, { w: number; h: number }>();\n/** Measure only when text is committed; pointer movement never reads layout. */\nexport function measureText(owner: Document, text: ItemText) {\n const key = JSON.stringify(text),\n cached = cache.get(key);\n if (cached) {\n cache.delete(key);\n cache.set(key, cached);\n return cached;\n }\n const measure = owner.createElement('div');\n measure.style.cssText =\n 'position:fixed;left:-100000px;top:0;visibility:hidden;pointer-events:none;white-space:pre;line-height:1.35;width:max-content;max-width:none;padding:0;border:0;';\n measure.style.fontFamily = fontFamily(text.font);\n measure.style.fontSize = `${fontSize(text)}px`;\n measure.textContent = text.value || ' ';\n owner.body.append(measure);\n const rect = measure.getBoundingClientRect();\n const result = {\n w: Math.max(24, Math.ceil(rect.width + 4)),\n h: Math.max(fontSize(text) * 1.35, Math.ceil(rect.height)),\n };\n measure.remove();\n cache.set(key, result);\n if (cache.size > 256) cache.delete(cache.keys().next().value!);\n return result;\n}\n","import { signal } from '@preact/signals-core';\nimport { kindsSince } from './core/catalog';\nimport type { KindCatalogSnapshot } from './core/catalog';\nimport { CARD_CORNER, clone, sizeOf } from './core/defaults';\nimport { itemId, mediaId } from './core/ids';\nimport { LIMITS, VISION_PNG } from './core/schema';\nimport { createDoc } from './core/doc';\nimport type { LinkPreview } from './core/links';\nimport { lockedItems } from './core/locks';\nimport { clipboardText } from './core/clipboard';\nimport { applyDraft, copyItems, detachMissingEndpoints, translateItem } from './core/item';\nimport type {\n AgentPresenceOptions,\n AnnieDoc,\n ApplyIssue,\n ApplyOptions,\n ApplyResult,\n Box,\n BoardPointer,\n ChangeEvent,\n ChangeLog,\n DescribeOptions,\n DocModel,\n ExportFormat,\n ExportOptions,\n Item,\n LensState,\n Op,\n Point,\n Query,\n Scope,\n Style,\n} from './core/types';\nimport { Stage } from './stage/stage';\nimport {\n SpatialIndex,\n boundsOf as geometryBounds,\n flattenItems,\n itemBounds,\n rotatePoint,\n simplifyStroke,\n} from './geo/index';\nimport { getKinds, type KindDef } from './kinds/index';\nimport { exportSVG } from './porter/svg';\nimport { exportRaster } from './porter/png';\nimport { ANNIE_MIME, exportJSON } from './porter/json';\nimport { mountUI, type UiOptions } from './ui/index';\nexport type { UiOptions, UiExportFormat } from './ui/index';\nimport { openAutosave } from './input/autosave';\nimport { measureText } from './input/measure';\nimport { cursorForTool } from './input/cursors';\nimport type { PasteHost } from './input/urlPaste';\n\nexport interface BoardOptions {\n doc?: AnnieDoc;\n /** Used when origin starts with `agent:` and apply() omits agentName. */\n agentName?: string;\n /**\n * `shared` (default): undo/redo walk every origin.\n * `hidden`: default undo/redo skip origins that start with `agent:`.\n */\n agentHistory?: 'shared' | 'hidden';\n /** Default reveal for origins that start with `agent:`. Default `fit`. */\n agentReveal?: 'none' | 'fit';\n /** Used when origin starts with `agent:` and place.gap is omitted. Default 32. */\n agentPlaceGap?: number;\n agentPresence?: boolean | AgentPresenceOptions;\n readonly?: boolean;\n /** `'light'` when omitted, `'dark'`, or `'auto'` for `prefers-color-scheme`. */\n theme?: 'light' | 'dark' | 'auto';\n /** `false` omits chrome. An object keeps the tools and sets the header. Default `true`. */\n ui?: boolean | UiOptions;\n kinds?: KindDef[];\n autosaveKey?: string;\n /** Register on `window.__anniedrawing`. Default false. The local demo sets true. */\n exposeGlobal?: boolean;\n allowedImageOrigins?: string[];\n sanitizeHTML?: (html: string) => string;\n unfurl?: false | ((url: string) => Promise<LinkPreview | undefined>);\n}\ntype Events = {\n change: ChangeEvent;\n select: string[];\n view: LensState;\n tool: string;\n page: string;\n save: { status: 'saving' | 'saved' | 'error'; message?: string };\n};\ntype Drag = {\n kind: 'pan' | 'move' | 'resize' | 'rotate' | 'marquee' | 'draw' | 'erase';\n pointer: number;\n start: Point;\n screen: Point;\n last: Point;\n original: Item[];\n ids: string[];\n camera: LensState;\n handle?: string;\n item?: Item;\n points?: [number, number, number?][];\n moved: boolean;\n alt?: boolean;\n};\nconst shortcuts: Record<string, string> = {\n v: 'select',\n h: 'hand',\n r: 'rect',\n o: 'ellipse',\n d: 'diamond',\n l: 'line',\n a: 'connector',\n p: 'path',\n t: 'text',\n n: 'note',\n e: 'eraser',\n};\n\n/** Browser editor: document session, pointer input, and the public Board API. */\nexport class Board {\n readonly host: HTMLElement;\n /** @internal Renderer. Use `view` and documented Board methods. */\n readonly stage: Stage;\n readonly model: DocModel;\n readonly ready: Promise<void>;\n readonly readonly: boolean;\n readonly agentName?: string;\n readonly selectionSignal = signal<string[]>([]);\n readonly toolSignal = signal('select');\n readonly drafts = new Map<string, Partial<Item>>();\n /** Drawing tools fill paper; compact JSON omits fill and treats missing fill as none. */\n defaultStyle: Style = { stroke: 'ink', strokeWidth: 2, fill: 'paper', corner: CARD_CORNER };\n grid = true;\n pageId: string;\n private document: AnnieDoc;\n private spatial = new SpatialIndex();\n private geometryLookup = new Map<string, Item>();\n private hiddenGeometry = new Set<string>();\n private lockedGeometry = new Set<string>();\n private listeners = new Map<keyof Events, Set<(event: never) => void>>();\n private cleanup: (() => void)[] = [];\n private uiCleanup?: () => void;\n private frame = 0;\n private drag?: Drag;\n private rect: DOMRect;\n private space = false;\n private clipboard: Item[] = [];\n private pointers = new Map<number, Point>();\n private observedPointer?: {\n client: Point;\n page: Point;\n pageId: string;\n type: string;\n at: number;\n };\n private pointerInside = false;\n private pinch?: { distance: number; zoom: number; center: Point; anchor: Point };\n private editor?: HTMLElement;\n private finishEditor?: (save?: boolean) => void;\n private longPressTimer?: ReturnType<typeof setTimeout>;\n private lastTouchTap?: { at: number; screen: Point };\n private touchDoubleAt = 0;\n private enteredGroup?: string;\n private destroyed = false;\n private themeValue: 'light' | 'dark' | 'auto';\n private drawPreview?: Item;\n private previewDocument?: AnnieDoc;\n private previewBase?: AnnieDoc;\n private observer: ResizeObserver;\n private unfurl?: false | ((url: string) => Promise<LinkPreview | undefined>);\n private agentReveal: 'none' | 'fit';\n private pendingReveal?: string[];\n\n constructor(host: HTMLElement, options: BoardOptions = {}) {\n this.host = host;\n this.readonly = options.readonly ?? false;\n this.agentName = options.agentName?.trim() || undefined;\n this.agentReveal = options.agentReveal ?? 'fit';\n this.model = createDoc(options.doc, {\n readonly: this.readonly,\n allowedImageOrigins: options.allowedImageOrigins,\n kinds: [...getKinds(), ...(options.kinds ?? [])],\n sanitizeHTML: options.sanitizeHTML,\n agentHistory: options.agentHistory,\n agentPlaceGap: options.agentPlaceGap,\n });\n this.document = this.model.toJSON({ compact: false });\n this.pageId = this.document.pages[0].id;\n this.themeValue = options.theme ?? 'light';\n this.unfurl = options.unfurl;\n this.stage = new Stage(host, {\n agentPresence: options.agentPresence,\n theme: this.themeValue,\n kinds: options.kinds,\n sanitizeHTML: options.sanitizeHTML,\n });\n this.updateCursor();\n this.refreshGeometry();\n this.rect = this.stage.root.getBoundingClientRect();\n this.stage.root.dataset.adBoard = '';\n this.cleanup.push(\n this.model.on('change', (event) => {\n this.document = this.model.toJSON({ compact: false });\n if (!this.document.pages.some((page) => page.id === this.pageId))\n this.pageId = this.document.pages[0].id;\n this.refreshGeometry();\n if (\n (this.drag &&\n ['move', 'resize', 'rotate', 'erase'].includes(this.drag.kind) &&\n this.drag.ids.some((id) => this.isLocked(id))) ||\n (this.editor &&\n this.isLocked(this.editor.closest<HTMLElement>('[data-ad-id]')?.dataset.adId ?? ''))\n )\n this.cancel();\n this.select(this.selection.filter((id) => !!this.get(id)));\n this.schedule();\n this.emit('change', event);\n }),\n );\n this.cleanup.push(\n this.stage.lens.onChange((state) => {\n this.schedule();\n this.emit('view', state);\n }),\n );\n const bind = <K extends keyof HTMLElementEventMap>(\n name: K,\n handler: (event: HTMLElementEventMap[K]) => void,\n opts?: AddEventListenerOptions,\n ) => {\n this.stage.root.addEventListener(name, handler as EventListener, opts);\n this.cleanup.push(() =>\n this.stage.root.removeEventListener(name, handler as EventListener, opts),\n );\n };\n bind('pointerenter', this.observePointer);\n bind('pointerdown', this.observePointer);\n bind('pointermove', this.observePointer);\n bind('pointerleave', this.releasePointer);\n bind('pointercancel', this.releasePointer);\n bind('pointerup', (event) => {\n this.observePointer(event);\n if (event.pointerType !== 'mouse') this.releasePointer();\n });\n bind('pointerdown', this.pointerDown);\n bind('pointermove', this.pointerMove);\n bind('pointerup', this.pointerUp);\n bind('pointercancel', this.pointerCancel);\n bind('wheel', this.wheel, { passive: false });\n bind('keydown', this.keyDown);\n bind('keyup', (e) => {\n if (e.code === 'Space') {\n this.space = false;\n this.updateCursor();\n }\n });\n bind('dblclick', this.doubleClick);\n bind('contextmenu', (e) => {\n if (this.isUI(e.target)) return;\n e.preventDefault();\n const targetId = (e.target as Element).closest<HTMLElement>('[data-ad-id]')?.dataset.adId;\n this.openContext(this.point(e), targetId);\n });\n bind('copy', this.copyEvent);\n bind('cut', this.cutEvent);\n bind('paste', this.pasteEvent);\n bind('dragover', (e) => {\n if (!this.readonly) {\n e.preventDefault();\n if (e.dataTransfer) e.dataTransfer.dropEffect = 'copy';\n }\n });\n bind('drop', this.drop);\n bind('focusin', (e) => {\n const item = (e.target as HTMLElement).closest<HTMLElement>('[data-ad-id]');\n if (item && e.target === item && !this.drag) this.select([item.dataset.adId!]);\n });\n const release = () => {\n this.releasePointer();\n this.space = false;\n this.finishEditor?.(true);\n this.cancel();\n this.updateCursor();\n };\n window.addEventListener('blur', release);\n this.cleanup.push(() => window.removeEventListener('blur', release));\n const hidePointer = () => {\n if (this.host.ownerDocument.hidden) this.releasePointer();\n };\n this.host.ownerDocument.addEventListener('visibilitychange', hidePointer);\n this.cleanup.push(() =>\n this.host.ownerDocument.removeEventListener('visibilitychange', hidePointer),\n );\n this.observer = new ResizeObserver(() => {\n this.rect = this.stage.root.getBoundingClientRect();\n this.schedule();\n });\n this.observer.observe(this.stage.root);\n const scroll = () => {\n this.rect = this.stage.root.getBoundingClientRect();\n };\n window.addEventListener('scroll', scroll, true);\n this.cleanup.push(() => window.removeEventListener('scroll', scroll, true));\n if (options.ui !== false)\n this.uiCleanup = mountUI(this, typeof options.ui === 'object' ? options.ui : {});\n this.render();\n this.view.fit();\n if (options.exposeGlobal) {\n window.__anniedrawing ??= [];\n window.__anniedrawing.push(this);\n }\n this.ready =\n options.autosaveKey && !this.readonly\n ? openAutosave(this, options.autosaveKey)\n : Promise.resolve();\n }\n get selection() {\n return [...this.selectionSignal.value];\n }\n /** Read the human cursor, or the last point after leaving/touch release. */\n getPointer(): BoardPointer | null {\n const observed = this.observedPointer;\n if (this.destroyed || !observed || observed.pageId !== this.pageId) return null;\n const rect = this.stage.root.getBoundingClientRect();\n const inside =\n this.pointerInside &&\n rect.width > 0 &&\n rect.height > 0 &&\n observed.client.x >= rect.left &&\n observed.client.x < rect.right &&\n observed.client.y >= rect.top &&\n observed.client.y < rect.bottom;\n const point = inside\n ? this.stage.lens.toPage({\n x: observed.client.x - rect.left,\n y: observed.client.y - rect.top,\n })\n : observed.page;\n return {\n ...point,\n pageId: observed.pageId,\n inside,\n pointerType: observed.type,\n ageMs: Math.max(0, Date.now() - observed.at),\n itemId: inside ? (this.hit(point, true)?.id ?? null) : null,\n };\n }\n get tool() {\n return this.toolSignal.value;\n }\n get theme() {\n return this.themeValue;\n }\n get canUndo() {\n return this.model.canUndo;\n }\n get canRedo() {\n return this.model.canRedo;\n }\n get revision() {\n return this.model.revision;\n }\n changesSince(since: number, options?: { origin?: string | 'user' | 'agent' }): ChangeLog {\n return this.model.changesSince(since, options);\n }\n get items() {\n return flattenItems(this.pageItems());\n }\n get view() {\n const board = this;\n return {\n fit(ids?: string[]) {\n board.stage.lens.fit(board.boundsOf(ids));\n },\n flyTo(box: Box) {\n board.stage.lens.flyTo(box);\n },\n get zoom() {\n return board.stage.lens.state.zoom;\n },\n set zoom(zoom: number) {\n board.zoomAt(zoom, { x: board.rect.width / 2, y: board.rect.height / 2 });\n },\n get center() {\n return board.stage.lens.toPage({ x: board.rect.width / 2, y: board.rect.height / 2 });\n },\n set center(point: Point) {\n const zoom = board.view.zoom;\n board.stage.lens.set({\n x: board.rect.width / 2 - point.x * zoom,\n y: board.rect.height / 2 - point.y * zoom,\n });\n },\n };\n }\n read(scope: Scope | { scope?: Scope; includeDrafts?: boolean } = 'doc'): AnnieDoc {\n const options = typeof scope === 'string' ? { scope } : scope;\n const doc = this.model.toJSON();\n if (options.includeDrafts && this.drawPreview)\n doc.pages.find((page) => page.id === this.pageId)?.items.push(clone(this.drawPreview));\n if (options.scope && options.scope !== 'doc')\n doc.pages = doc.pages.filter((page) => page.id === this.pageId);\n if (options.scope === 'selection' || options.scope === 'viewport') {\n const ids =\n options.scope === 'selection'\n ? new Set(this.selection)\n : new Set(this.items.filter((i) => !i.hidden && this.visible(i)).map((i) => i.id));\n const filter = (items: Item[]): Item[] =>\n items.flatMap((item) => (ids.has(item.id) ? [item] : filter(item.children ?? [])));\n for (const page of doc.pages) page.items = filter(page.items);\n }\n if (options.includeDrafts)\n for (const item of doc.pages.flatMap((page) => flattenItems(page.items))) {\n const next = applyDraft(item, this.drafts.get(item.id));\n Object.assign(item, next);\n }\n if (options.scope && options.scope !== 'doc') {\n const media = new Set(\n doc.pages.flatMap((page) => flattenItems(page.items)).map((item) => item.media),\n );\n doc.media = Object.fromEntries(Object.entries(doc.media).filter(([id]) => media.has(id)));\n }\n return doc;\n }\n get(id: string) {\n return this.model.get(id);\n }\n isLocked(id: string) {\n return this.lockedGeometry.has(id);\n }\n private lockedResult(index = 0): ApplyResult {\n return {\n ok: false,\n created: [],\n errors: [{ index, code: 'LOCKED', message: 'Unlock the selection before editing it.' }],\n warnings: [],\n };\n }\n query(selector: Query = {}) {\n return this.model.query(selector);\n }\n describe(options: DescribeOptions = {}) {\n return this.model.describe({\n ...options,\n page: options.page ?? (options.scope === 'doc' || !options.scope ? undefined : this.pageId),\n selection: options.selection ?? this.selection,\n ...(options.scope === 'viewport'\n ? {\n ids: this.items\n .filter((item) => !item.hidden && this.visible(item))\n .map((item) => item.id),\n }\n : {}),\n });\n }\n /** Built-in kinds added or last changed after `since`. Omit or pass 0 for the full catalog. */\n kindsSince(since = 0): KindCatalogSnapshot {\n return kindsSince(since);\n }\n boundsOf(ids?: string[]): Box {\n const idsSet = ids ? new Set(ids) : undefined;\n const visible = this.spatial.search({ x: -1e7, y: -1e7, w: 2e7, h: 2e7 });\n const selection = idsSet ? visible.filter((item) => idsSet.has(item.id)) : visible;\n return geometryBounds(selection, this.geometryLookup, this.outline);\n }\n apply(ops: Op[], options: ApplyOptions = {}): ApplyResult {\n const lockedOp = (op: Op) => {\n if (!op || typeof op !== 'object') return false;\n if (op.op === 'set' && op.patch?.locked === false && Object.keys(op.patch).length === 1)\n return false;\n return (\n (['set', 'remove', 'order', 'reparent'].includes(op.op) &&\n 'id' in op &&\n this.isLocked(op.id)) ||\n ((op.op === 'add' || op.op === 'reparent') && !!op.parent && this.isLocked(op.parent))\n );\n };\n const origin = options.origin ?? 'api';\n let batch = Array.isArray(ops) ? ops : ops;\n const lockSkipped: ApplyIssue[] = [];\n if (origin === 'user' && Array.isArray(ops)) {\n const blocked = ops.flatMap((op, index) => (lockedOp(op) ? [index] : []));\n if (blocked.length && !options.lenient) return this.lockedResult(blocked[0]);\n if (blocked.length && options.lenient) {\n lockSkipped.push(\n ...blocked.map((index) => ({\n index,\n code: 'LOCKED',\n message: 'Unlock the selection before editing it.',\n })),\n );\n batch = ops.filter((_, index) => !blocked.includes(index));\n if (!batch.length)\n return { ok: false, created: [], errors: [], warnings: [], skipped: lockSkipped };\n }\n }\n const prepare = (op: Op): Op => {\n if (!op || typeof op !== 'object') return op;\n if (op.op === 'add' && op.item) {\n let item = op.item;\n if (\n item.kind === 'text' &&\n item.autoWidth &&\n typeof item.text?.value === 'string' &&\n item.text.value.length <= LIMITS.maxTextLength\n )\n item = { ...item, ...measureText(this.host.ownerDocument, item.text) };\n return { ...op, item, ...(!op.page && !op.parent ? { page: this.pageId } : {}) };\n }\n if (op.op === 'set' && op.patch) {\n const item = this.get(op.id);\n if (\n item?.kind === 'text' &&\n (op.patch.autoWidth ?? item.autoWidth) &&\n (op.patch.text || op.patch.autoWidth)\n ) {\n const text = { ...item.text, ...(op.patch.text as { value?: string } | undefined) };\n if (typeof text.value === 'string' && text.value.length <= LIMITS.maxTextLength)\n return {\n ...op,\n patch: {\n ...op.patch,\n ...measureText(this.host.ownerDocument, text as { value: string }),\n },\n };\n }\n }\n return op;\n };\n const sent = Array.isArray(batch) ? batch.map(prepare) : batch;\n const result = this.model.apply(sent, {\n origin: 'api',\n ...options,\n });\n if (lockSkipped.length && Array.isArray(ops)) {\n const blocked = new Set(lockSkipped.map((issue) => issue.index));\n const kept = ops.map((_, index) => index).filter((index) => !blocked.has(index));\n const remap = (issues?: ApplyIssue[]) =>\n issues?.map((issue) => ({ ...issue, index: kept[issue.index] ?? issue.index }));\n result.errors = remap(result.errors) ?? result.errors;\n result.warnings = remap(result.warnings) ?? result.warnings;\n result.skipped = [...lockSkipped, ...(remap(result.skipped) ?? [])].sort(\n (a, b) => a.index - b.index,\n );\n }\n if (result.ok && !options.dryRun && result.created.length) {\n if (origin.startsWith('agent:')) {\n this.render();\n const name = (options.agentName ?? this.agentName)?.trim() || undefined;\n this.stage.present(result.created, name);\n }\n const reveal = options.reveal ?? (origin.startsWith('agent:') ? this.agentReveal : 'none');\n if (reveal === 'fit') this.queueReveal(result.created);\n }\n return result;\n }\n private queueReveal(ids: string[]) {\n this.pendingReveal = [...new Set([...(this.pendingReveal ?? []), ...ids])];\n this.stage.whenPresentationIdle(() => this.flushReveal());\n }\n private flushReveal() {\n const ids = this.pendingReveal;\n this.pendingReveal = undefined;\n if (!ids?.length || this.destroyed) return;\n this.revealCreated(ids);\n }\n private revealCreated(ids: string[]) {\n const onPage = ids.filter((id) =>\n flattenItems(this.pageItems()).some((item) => item.id === id),\n );\n if (!onPage.length) return;\n if (\n onPage.every((id) => {\n const item = this.get(id);\n return !!item && this.visible(item);\n })\n )\n return;\n this.view.fit(onPage);\n }\n undo(options?: { origin?: string }) {\n this.cancel();\n return this.model.undo(options);\n }\n redo() {\n this.cancel();\n return this.model.redo();\n }\n load(doc: AnnieDoc) {\n this.cancel();\n this.pendingReveal = undefined;\n this.model.load(doc);\n this.document = this.model.toJSON({ compact: false });\n this.pageId = this.document.pages[0].id;\n this.refreshGeometry();\n this.select([]);\n this.render();\n this.view.fit();\n }\n clear() {\n this.cancel();\n this.pendingReveal = undefined;\n this.model.clear();\n this.document = this.model.toJSON({ compact: false });\n this.pageId = this.document.pages[0].id;\n this.refreshGeometry();\n this.select([]);\n this.render();\n this.view.fit();\n }\n select(ids: string[]) {\n const next = [...new Set(ids)].filter((id) => !!this.get(id));\n if (next.join(',') === this.selectionSignal.value.join(',')) return;\n this.selectionSignal.value = next;\n this.stage.setSelection(next);\n this.emit('select', next);\n }\n setTool(id: string) {\n this.cancel();\n this.toolSignal.value = id;\n this.updateCursor();\n this.emit('tool', id);\n }\n setTheme(theme: 'light' | 'dark' | 'auto') {\n this.themeValue = theme;\n this.stage.setTheme(theme);\n }\n setPage(id: string) {\n if (!this.document.pages.some((page) => page.id === id)) return;\n this.observedPointer = undefined;\n this.pointerInside = false;\n this.cancel();\n this.pendingReveal = undefined;\n this.pageId = id;\n this.refreshGeometry();\n this.enteredGroup = undefined;\n this.select([]);\n this.render();\n this.view.fit();\n this.emit('page', id);\n }\n setGrid(value: boolean) {\n this.grid = value;\n this.stage.root.classList.toggle('ad-no-grid', !value);\n }\n on<K extends keyof Events>(name: K, callback: (event: Events[K]) => void) {\n const set = this.listeners.get(name) ?? new Set();\n set.add(callback as (event: never) => void);\n this.listeners.set(name, set);\n return () => set.delete(callback as (event: never) => void);\n }\n emit<K extends keyof Events>(name: K, event: Events[K]) {\n this.listeners.get(name)?.forEach((fn) => fn(event as never));\n }\n async export(format: ExportFormat, options: ExportOptions = {}): Promise<string | Blob> {\n const doc = this.read(options.scope ?? 'page');\n if (format === 'json') {\n detachMissingEndpoints(\n doc.pages.flatMap((page) => page.items),\n this.geometryLookup,\n this.outline,\n );\n return exportJSON(doc);\n }\n const items = doc.pages.flatMap((page) => page.items).map((item) => this.get(item.id) ?? item);\n const svg = exportSVG(this.document, items, {\n ...options,\n theme: this.stage.resolvedTheme,\n kinds: [...this.stage.kinds.values()],\n ...(options.scope === 'viewport' ? { bounds: this.stage.lens.viewport(), padding: 0 } : {}),\n });\n if (format === 'svg') return svg;\n const vision = format === 'png' && options.labels === true;\n return exportRaster(svg, {\n format,\n scale: options.scale ?? 2,\n maxSide: options.maxSide,\n maxBytes: options.maxBytes ?? (vision ? VISION_PNG.maxBytes : undefined),\n quality: options.quality,\n colors: options.colors ?? (vision ? VISION_PNG.colors : undefined),\n });\n }\n destroy() {\n if (this.destroyed) return;\n this.destroyed = true;\n this.pendingReveal = undefined;\n this.cancel();\n cancelAnimationFrame(this.frame);\n this.observer.disconnect();\n this.cleanup.forEach((fn) => fn());\n this.uiCleanup?.();\n this.stage.destroy();\n this.listeners.clear();\n if (window.__anniedrawing)\n window.__anniedrawing = window.__anniedrawing.filter((b) => b !== this);\n }\n addCleanup(fn: () => void) {\n this.cleanup.push(fn);\n }\n focus() {\n this.stage.root.focus({ preventScroll: true });\n }\n add(kind: string, point?: Point) {\n const p = point ?? this.view.center;\n const [w, h] = sizeOf(kind);\n const result = this.apply(\n [\n {\n op: 'add',\n page: this.pageId,\n item: {\n kind,\n x: p.x - w / 2,\n y: p.y - h / 2,\n w,\n h,\n style: clone(this.defaultStyle),\n ...(kind === 'note'\n ? {\n style: {\n ...this.defaultStyle,\n fill: 'moss',\n stroke: 'none',\n corner: CARD_CORNER,\n },\n text: { value: 'A little idea', size: 'l' },\n }\n : {}),\n ...(kind === 'text'\n ? {\n autoWidth: true,\n text: { value: 'Type something…', size: 'l' },\n style: { fill: 'none', stroke: 'ink' },\n }\n : {}),\n },\n },\n ],\n { origin: 'user', label: `Add ${kind}` },\n );\n if (result.ok) {\n this.select(result.created);\n if (kind === 'text' || kind === 'note') this.editText(result.created[0]);\n }\n return result;\n }\n updateSelection(patch: Partial<Item>) {\n if (patch.locked === false && Object.keys(patch).length === 1) {\n const selected = new Set(this.selection),\n ids: string[] = [];\n const visit = (item: Item, inside = false): boolean => {\n inside ||= selected.has(item.id);\n let contains = false;\n for (const child of item.children ?? []) contains = visit(child, inside) || contains;\n if (item.locked && (inside || contains)) ids.push(item.id);\n return inside || contains;\n };\n this.document.pages.forEach((page) => page.items.forEach((item) => visit(item)));\n return this.apply(\n ids.map((id) => ({ op: 'set', id, patch })),\n {\n origin: 'user',\n label: 'Unlock selection',\n },\n );\n }\n return this.apply(\n this.selection.map((id) => ({ op: 'set', id, patch })),\n { origin: 'user', label: 'Change style' },\n );\n }\n deleteSelection() {\n if (this.selection.some((id) => this.isLocked(id))) return;\n const ids = this.topSelection();\n this.apply(\n ids.map((id) => ({ op: 'remove', id })),\n { origin: 'user', label: 'Delete' },\n );\n this.select([]);\n this.focus();\n }\n duplicate(offset = 24) {\n if (this.selection.some((id) => this.isLocked(id))) return this.lockedResult();\n const items = this.topSelection()\n .map((id) => this.get(id)!)\n .filter(Boolean);\n const copies = copyItems(items, offset);\n const result = this.apply(\n copies.map((item) => ({ op: 'add', item, page: this.pageId })),\n { origin: 'user', label: 'Duplicate' },\n );\n if (result.ok) this.select(copies.map((i) => i.id));\n return result;\n }\n group() {\n if (this.selection.length < 2 || this.selection.some((id) => this.isLocked(id))) return;\n const ids = this.topSelection(),\n box = this.boundsOf(ids),\n id = itemId();\n this.apply(\n [\n { op: 'add', page: this.pageId, item: { kind: 'group', id, ...box, children: [] } },\n ...ids.map((childId) => ({ op: 'reparent' as const, id: childId, parent: id })),\n ],\n { origin: 'user', label: 'Group' },\n );\n this.select([id]);\n }\n ungroup() {\n if (this.selection.some((id) => this.isLocked(id))) return;\n const ops: Op[] = [];\n for (const id of this.selection) {\n const item = this.get(id);\n if (item?.kind === 'group') {\n for (const child of item.children ?? [])\n ops.push({ op: 'reparent', id: child.id, parent: null });\n ops.push({ op: 'remove', id });\n }\n }\n this.apply(ops, { origin: 'user', label: 'Ungroup' });\n this.select([]);\n }\n align(\n mode: 'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom' | 'horizontal' | 'vertical',\n ) {\n if (this.selection.some((id) => this.isLocked(id))) return;\n const items = this.topSelection()\n .map((id) => this.get(id)!)\n .filter((i) => i && !i.locked && i.kind !== 'connector'),\n visual = (item: Item) => itemBounds(item, this.geometryLookup, this.outline),\n box = geometryBounds(items, this.geometryLookup, this.outline);\n const sorted = [...items].sort((a, b) =>\n mode === 'horizontal' ? visual(a).x - visual(b).x : visual(a).y - visual(b).y,\n );\n let cursor = mode === 'horizontal' ? box.x : box.y;\n const gap =\n items.length > 1\n ? ((mode === 'horizontal' ? box.w : box.h) -\n items.reduce((s, i) => s + (mode === 'horizontal' ? visual(i).w : visual(i).h), 0)) /\n (items.length - 1)\n : 0;\n const ops = sorted.flatMap((i) => {\n const b = visual(i);\n let dx = 0,\n dy = 0;\n if (mode === 'left') dx = box.x - b.x;\n if (mode === 'center') dx = box.x + (box.w - b.w) / 2 - b.x;\n if (mode === 'right') dx = box.x + box.w - b.w - b.x;\n if (mode === 'top') dy = box.y - b.y;\n if (mode === 'middle') dy = box.y + (box.h - b.h) / 2 - b.y;\n if (mode === 'bottom') dy = box.y + box.h - b.h - b.y;\n if (mode === 'horizontal') {\n dx = cursor - b.x;\n cursor += b.w + gap;\n }\n if (mode === 'vertical') {\n dy = cursor - b.y;\n cursor += b.h + gap;\n }\n return this.movable([i.id]).map((child) => ({\n op: 'set' as const,\n id: child.id,\n patch: translateItem(child, dx, dy),\n }));\n });\n this.apply(ops, { origin: 'user', label: 'Align selection' });\n }\n async addImage(file: File, point?: Point) {\n if (this.readonly) return;\n if (!/^image\\/(png|jpeg|gif|webp|avif)$/.test(file.type))\n throw new Error('Choose a PNG, JPEG, GIF, WebP or AVIF image.');\n if (file.size > 10 * 1024 * 1024) throw new Error('Images must be under 10 MB.');\n const src = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(file);\n });\n const image = new Image();\n image.src = src;\n await image.decode();\n const scale = Math.min(1, 480 / image.width, 360 / image.height),\n w = image.width * scale,\n h = image.height * scale,\n p = point ?? this.view.center,\n id = mediaId();\n const result = this.apply(\n [\n { op: 'media.set', id, media: { src, mime: file.type, w: image.width, h: image.height } },\n {\n op: 'add',\n page: this.pageId,\n item: { kind: 'image', x: p.x - w / 2, y: p.y - h / 2, w, h, media: id, name: file.name },\n },\n ],\n { origin: 'user', label: 'Add image' },\n );\n if (result.ok) this.select(result.created);\n }\n /** Replace a video or link href. Editor helper; agents should `apply` a `set`. */\n setHref(id: string, href: string): Promise<ApplyResult> {\n return import('./input/urlPaste').then(({ updateHref }) =>\n updateHref(this.pasteHost(), id, href),\n );\n }\n private pasteHost(): PasteHost {\n return {\n pageId: this.pageId,\n items: this.items,\n destroyed: this.destroyed,\n unfurl: this.unfurl,\n view: this.view,\n host: this.host,\n apply: (ops, options) => this.apply(ops, options),\n select: (ids) => this.select(ids),\n get: (id) => this.get(id),\n };\n }\n editText(id: string) {\n if (this.readonly || this.editor) return;\n this.render();\n const item = this.get(id);\n if (!item || this.isLocked(id)) return;\n const view = this.stage.world.querySelector<HTMLElement>(`[data-ad-id=\"${CSS.escape(id)}\"]`);\n if (!view) return;\n let text = view.querySelector<HTMLElement>('.ad-text');\n if (!text) {\n text = document.createElement('div');\n text.className = 'ad-text';\n view.append(text);\n }\n text.contentEditable = 'plaintext-only';\n text.setAttribute('role', 'textbox');\n text.setAttribute('aria-label', 'Edit text');\n text.style.pointerEvents = 'auto';\n text.style.display = 'flex';\n text.classList.add('ad-editing');\n this.editor = text;\n const before = item.text?.value ?? '';\n text.textContent = before;\n text.focus();\n const range = document.createRange();\n range.selectNodeContents(text);\n const selection = window.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(range);\n const finish = (save = true) => {\n if (this.editor !== text) return;\n this.editor = undefined;\n this.finishEditor = undefined;\n const value = text!.innerText;\n text!.contentEditable = 'false';\n text!.classList.remove('ad-editing');\n text!.removeAttribute('role');\n text!.removeAttribute('aria-label');\n text!.removeEventListener('blur', blur);\n text!.removeEventListener('keydown', key);\n if (save && value !== before) {\n const updatedText = { ...this.get(id)?.text, value };\n const dimensions =\n item.kind === 'text' && item.autoWidth\n ? measureText(this.host.ownerDocument, updatedText)\n : {};\n this.apply([{ op: 'set', id, patch: { ...dimensions, text: { value } } }], {\n origin: 'user',\n label: 'Edit text',\n });\n }\n const saved = this.get(id);\n text!.textContent = saved?.text?.value ?? before;\n text!.style.display = saved?.text ? 'flex' : 'none';\n this.render();\n this.focus();\n };\n this.finishEditor = finish;\n const blur = () => finish();\n const key = (e: KeyboardEvent) => {\n e.stopPropagation();\n if (e.key === 'Escape') {\n e.preventDefault();\n finish(false);\n }\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n finish();\n }\n };\n text.addEventListener('blur', blur);\n text.addEventListener('keydown', key);\n }\n cancel() {\n this.clearInteractive();\n clearTimeout(this.longPressTimer);\n this.lastTouchTap = undefined;\n this.finishEditor?.(false);\n if (this.drag) {\n this.drag = undefined;\n this.drafts.clear();\n this.drawPreview = undefined;\n this.stage.setMarquee(undefined);\n this.render();\n }\n this.pointers.clear();\n this.pinch = undefined;\n this.updateCursor();\n }\n private schedule() {\n if (!this.frame && !this.destroyed)\n this.frame = requestAnimationFrame(() => {\n this.frame = 0;\n this.render();\n });\n }\n private render() {\n if (this.destroyed) return;\n let doc = this.document;\n if (this.drawPreview) {\n if (!this.previewDocument || this.previewBase !== doc) {\n this.previewBase = doc;\n this.previewDocument = {\n ...doc,\n pages: doc.pages.map((page) =>\n page.id === this.pageId ? { ...page, items: [...page.items, this.drawPreview!] } : page,\n ),\n };\n }\n doc = this.previewDocument;\n this.drafts.set(this.drawPreview.id, { ...this.drawPreview });\n } else {\n this.previewDocument = undefined;\n this.previewBase = undefined;\n }\n this.stage.render(doc, this.pageId, this.drafts);\n this.stage.setSelection(this.selection);\n }\n private visible(item: Item) {\n if (this.hiddenGeometry.has(item.id)) return false;\n const viewport = this.stage.lens.viewport(),\n box = itemBounds(item, this.geometryLookup, this.outline);\n return (\n box.x + box.w >= viewport.x &&\n box.y + box.h >= viewport.y &&\n box.x <= viewport.x + viewport.w &&\n box.y <= viewport.y + viewport.h\n );\n }\n private isUI(target: EventTarget | null) {\n return (\n target instanceof Element &&\n !!target.closest(\n '.ad-ui, .ad-dialog, input, textarea, select, button, [contenteditable=\"plaintext-only\"], [data-ad-interactive=\"true\"], a',\n )\n );\n }\n private point(e: { clientX: number; clientY: number }) {\n return { x: e.clientX - this.rect.left, y: e.clientY - this.rect.top };\n }\n private updateCursor() {\n this.stage.root.style.cursor = cursorForTool(this.tool, {\n space: this.space,\n readonly: this.readonly,\n panning: this.drag?.kind === 'pan',\n });\n }\n private topSelection() {\n const selected = new Set(this.selection),\n result: string[] = [];\n const visit = (items: Item[], ancestorSelected = false) => {\n for (const item of items) {\n const included = selected.has(item.id);\n if (included && !ancestorSelected) result.push(item.id);\n if (item.children) visit(item.children, ancestorSelected || included);\n }\n };\n visit(this.pageItems());\n return result;\n }\n private pageItems() {\n return this.document.pages.find((page) => page.id === this.pageId)?.items ?? [];\n }\n private movable(ids: string[]) {\n if (ids.some((id) => this.isLocked(id))) return [];\n const all = new Map<string, Item>();\n for (const id of ids) {\n const item = this.get(id);\n if (item && !item.locked)\n for (const child of [item, ...flattenItems(item.children ?? [])]) all.set(child.id, child);\n }\n return [...all.values()];\n }\n private outline = (item: Item) => this.stage.kinds.get(item.kind)?.outline?.(item);\n /** Hit-testing uses committed geometry; drafts do not update this index. */\n private refreshGeometry() {\n const items = this.pageItems();\n this.geometryLookup = new Map(flattenItems(items).map((item) => [item.id, item]));\n this.lockedGeometry = lockedItems(this.document.pages.flatMap((page) => page.items));\n this.hiddenGeometry.clear();\n const walk = (nodes: Item[], hidden = false) => {\n for (const item of nodes) {\n const inherited = hidden || !!item.hidden;\n if (inherited) this.hiddenGeometry.add(item.id);\n if (item.children) walk(item.children, inherited);\n }\n };\n walk(items);\n this.spatial.set(items, this.outline);\n }\n private hit(point: Point, includeLocked = false): Item | undefined {\n const item = this.spatial.pick(point, {\n includeLocked: true,\n tolerance: 6 / this.view.zoom,\n enteredGroup: this.enteredGroup,\n outline: this.outline,\n ignore: (candidate) => this.stage.isPending(candidate.id),\n });\n if (!item || item.id === this.enteredGroup || (!includeLocked && this.isLocked(item.id)))\n return undefined;\n return item;\n }\n private zoomAt(zoom: number, screen: Point) {\n zoom = Math.max(0.05, Math.min(8, zoom));\n const p = this.stage.lens.toPage(screen);\n this.stage.lens.set({ zoom, x: screen.x - p.x * zoom, y: screen.y - p.y * zoom });\n }\n private releasePointer = () => {\n const point = this.getPointer();\n if (point && this.observedPointer) this.observedPointer.page = { x: point.x, y: point.y };\n this.pointerInside = false;\n };\n private observePointer = (event: PointerEvent) => {\n const rect = this.stage.root.getBoundingClientRect();\n const inside =\n !this.isUI(event.target) &&\n rect.width > 0 &&\n rect.height > 0 &&\n event.clientX >= rect.left &&\n event.clientX < rect.right &&\n event.clientY >= rect.top &&\n event.clientY < rect.bottom;\n if (!inside) {\n this.releasePointer();\n return;\n }\n this.pointerInside = true;\n this.observedPointer = {\n client: { x: event.clientX, y: event.clientY },\n page: this.stage.lens.toPage({ x: event.clientX - rect.left, y: event.clientY - rect.top }),\n pageId: this.pageId,\n type: event.pointerType || 'mouse',\n at: Date.now(),\n };\n };\n private pointerDown = (e: PointerEvent) => {\n if (this.isUI(e.target) || e.button > 1) return;\n this.clearInteractive(e.target);\n clearTimeout(this.longPressTimer);\n if (e.pointerType !== 'touch') this.lastTouchTap = undefined;\n const screen = this.point(e);\n this.pointers.set(e.pointerId, screen);\n if (this.pointers.size === 2) {\n this.lastTouchTap = undefined;\n this.drag = undefined;\n this.updateCursor();\n this.drafts.clear();\n this.drawPreview = undefined;\n const [a, b] = [...this.pointers.values()],\n center = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };\n this.pinch = {\n distance: Math.hypot(a.x - b.x, a.y - b.y),\n zoom: this.view.zoom,\n center,\n anchor: this.stage.lens.toPage(center),\n };\n return;\n }\n e.preventDefault();\n try {\n this.stage.root.setPointerCapture(e.pointerId);\n } catch {\n /* Synthetic and already-ended pointers cannot be captured. */\n }\n this.focus();\n const start = this.stage.lens.toPage(screen),\n camera = { ...this.stage.lens.state };\n const handle = (e.target as Element).closest<HTMLElement>('[data-ad-handle]')?.dataset.adHandle;\n if (this.space || this.tool === 'hand' || e.button === 1 || this.readonly) {\n this.drag = {\n kind: 'pan',\n pointer: e.pointerId,\n start,\n screen,\n last: screen,\n original: [],\n ids: [],\n camera,\n moved: false,\n };\n this.updateCursor();\n return;\n }\n if (handle && this.selection.length) {\n if (this.selection.some((id) => this.isLocked(id))) return;\n this.drag = {\n kind: handle === 'rotate' ? 'rotate' : 'resize',\n pointer: e.pointerId,\n start,\n screen,\n last: start,\n original: this.movable(this.topSelection()),\n ids: this.topSelection(),\n camera,\n handle,\n moved: false,\n };\n return;\n }\n if (this.tool === 'select') {\n const targetId = (e.target as Element).closest<HTMLElement>('[data-ad-id]')?.dataset.adId;\n const fromDom = targetId && !this.stage.isPending(targetId) ? this.get(targetId) : undefined;\n const item =\n this.hit(start, true) ?? (fromDom && !this.outline(fromDom) ? fromDom : undefined);\n if (item) {\n if (e.shiftKey) {\n this.select(\n this.selection.includes(item.id)\n ? this.selection.filter((id) => id !== item.id)\n : [...this.selection, item.id],\n );\n } else if (!this.selection.includes(item.id)) this.select([item.id]);\n const ids = this.topSelection();\n this.drag = {\n kind: 'move',\n pointer: e.pointerId,\n start,\n screen,\n last: start,\n original: this.movable(ids),\n ids,\n camera,\n moved: false,\n alt: e.altKey,\n };\n } else {\n if (!e.shiftKey) this.select([]);\n this.drag = {\n kind: 'marquee',\n pointer: e.pointerId,\n start,\n screen,\n last: start,\n original: [],\n ids: this.selection,\n camera,\n moved: false,\n };\n }\n if (e.pointerType === 'touch') {\n const drag = this.drag;\n this.longPressTimer = setTimeout(() => {\n if (this.drag !== drag || drag.moved || this.pointers.size !== 1) return;\n this.cancel();\n const targetId = (e.target as Element).closest<HTMLElement>('[data-ad-id]')?.dataset.adId;\n this.openContext(screen, targetId);\n }, 500);\n }\n return;\n }\n if (this.tool === 'eraser') {\n const item = this.hit(start);\n this.drag = {\n kind: 'erase',\n pointer: e.pointerId,\n start,\n screen,\n last: start,\n original: [],\n ids: item ? [item.id] : [],\n camera,\n moved: false,\n };\n if (item) this.drafts.set(item.id, { hidden: true });\n this.schedule();\n return;\n }\n const kind = this.tool;\n const from = this.hit(start);\n const item = {\n id: itemId(),\n kind,\n x: start.x,\n y: start.y,\n w: 0,\n h: 0,\n style: clone(this.defaultStyle),\n ...(kind === 'path' ? { points: [[0, 0, e.pressure || 0.5]] } : {}),\n ...(kind === 'connector'\n ? {\n from: from ? { item: from.id, side: 'auto' } : start,\n to: start,\n route: 'elbow',\n heads: { end: 'arrow' },\n }\n : {}),\n ...(kind === 'note'\n ? {\n style: { ...this.defaultStyle, fill: 'moss', stroke: 'none', corner: CARD_CORNER },\n text: { value: '', size: 'l' },\n }\n : {}),\n ...(kind === 'text' ? { autoWidth: true, text: { value: '', size: 'l' } } : {}),\n } as Item;\n this.drag = {\n kind: 'draw',\n pointer: e.pointerId,\n start,\n screen,\n last: start,\n original: [],\n ids: [],\n camera,\n item,\n points: kind === 'path' ? [[0, 0, e.pressure || 0.5]] : undefined,\n moved: false,\n };\n this.drawPreview = item;\n this.select([]);\n this.schedule();\n };\n private pointerMove = (e: PointerEvent) => {\n const screen = this.point(e);\n if (this.pointers.has(e.pointerId)) this.pointers.set(e.pointerId, screen);\n if (this.pinch && this.pointers.size >= 2) {\n e.preventDefault();\n const [a, b] = [...this.pointers.values()],\n center = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 },\n zoom = Math.max(\n 0.05,\n Math.min(\n 8,\n (this.pinch.zoom * Math.hypot(a.x - b.x, a.y - b.y)) / Math.max(1, this.pinch.distance),\n ),\n );\n this.stage.lens.set({\n zoom,\n x: center.x - this.pinch.anchor.x * zoom,\n y: center.y - this.pinch.anchor.y * zoom,\n });\n return;\n }\n const drag = this.drag;\n if (!drag || drag.pointer !== e.pointerId) return;\n const p = this.stage.lens.toPage(screen);\n const distance = Math.hypot(screen.x - drag.screen.x, screen.y - drag.screen.y);\n if (!drag.moved && distance < (e.pointerType === 'touch' ? 8 : 4)) return;\n clearTimeout(this.longPressTimer);\n this.lastTouchTap = undefined;\n drag.moved = true;\n drag.last = p;\n if (drag.kind === 'pan') {\n this.stage.lens.set({\n x: drag.camera.x + screen.x - drag.screen.x,\n y: drag.camera.y + screen.y - drag.screen.y,\n });\n return;\n }\n if (drag.kind === 'move') {\n let dx = p.x - drag.start.x,\n dy = p.y - drag.start.y;\n if (e.shiftKey) {\n if (Math.abs(dx) > Math.abs(dy)) dy = 0;\n else dx = 0;\n }\n for (const item of drag.original) {\n this.drafts.set(item.id, translateItem(item, dx, dy));\n }\n this.schedule();\n return;\n }\n if (drag.kind === 'resize') {\n if (drag.handle?.startsWith('custom:')) {\n const item =\n drag.ids.length === 1 ? drag.original.find((item) => item.id === drag.ids[0]) : undefined;\n const callback = item ? this.stage.kinds.get(item.kind)?.dragHandle : undefined;\n if (item && callback) {\n const point = rotatePoint(\n p,\n { x: item.x + item.w / 2, y: item.y + item.h / 2 },\n -(item.rotation ?? 0),\n );\n try {\n this.drafts.set(\n item.id,\n callback(\n clone(item),\n drag.handle.slice(7),\n { x: point.x - item.x, y: point.y - item.y },\n { shift: e.shiftKey, alt: e.altKey },\n ),\n );\n this.schedule();\n } catch (error) {\n this.cancel();\n this.host.dispatchEvent(\n new CustomEvent('ad-error', {\n detail: error instanceof Error ? error.message : String(error),\n }),\n );\n }\n }\n return;\n }\n const selected = drag.original.filter((item) => drag.ids.includes(item.id));\n const oriented =\n selected.length === 1 && !['connector', 'line', 'path', 'group'].includes(selected[0].kind);\n const box = oriented\n ? selected[0]\n : geometryBounds(selected, this.geometryLookup, this.outline),\n handle = drag.handle ?? 'se',\n angle = oriented ? (selected[0].rotation ?? 0) : 0;\n const center = { x: box.x + box.w / 2, y: box.y + box.h / 2 };\n const localStart = rotatePoint(drag.start, center, -angle);\n const localPointer = rotatePoint(p, center, -angle);\n const dx = localPointer.x - localStart.x,\n dy = localPointer.y - localStart.y;\n const horizontal = handle.includes('e') ? 1 : handle.includes('w') ? -1 : 0,\n vertical = handle.includes('s') ? 1 : handle.includes('n') ? -1 : 0;\n let width = box.w + horizontal * dx * (e.altKey ? 2 : 1),\n height = box.h + vertical * dy * (e.altKey ? 2 : 1);\n if (e.shiftKey) {\n const sx = width / Math.max(1, box.w),\n sy = height / Math.max(1, box.h);\n const scale = Math.max(\n 12 / Math.max(1, box.w),\n 12 / Math.max(1, box.h),\n !horizontal ? sy : !vertical ? sx : Math.abs(sx - 1) >= Math.abs(sy - 1) ? sx : sy,\n );\n width = box.w * scale;\n height = box.h * scale;\n } else {\n width = Math.max(12, width);\n height = Math.max(12, height);\n }\n const localCenter = {\n x: center.x + (e.altKey ? 0 : (horizontal * (width - box.w)) / 2),\n y: center.y + (e.altKey ? 0 : (vertical * (height - box.h)) / 2),\n };\n const x = localCenter.x - width / 2,\n y = localCenter.y - height / 2,\n sx = width / Math.max(1, box.w),\n sy = height / Math.max(1, box.h);\n const transformPoint = (point: Point) => {\n const local = rotatePoint(point, center, -angle);\n return rotatePoint(\n { x: x + (local.x - box.x) * sx, y: y + (local.y - box.y) * sy },\n center,\n angle,\n );\n };\n for (const item of drag.original) {\n const nextCenter = transformPoint({ x: item.x + item.w / 2, y: item.y + item.h / 2 });\n const w = Math.max(1, item.w * sx),\n h = Math.max(1, item.h * sy);\n const patch: Partial<Item> = { x: nextCenter.x - w / 2, y: nextCenter.y - h / 2, w, h };\n if (item.points)\n patch.points = item.points.map((point) =>\n point.length > 2\n ? [point[0] * sx, point[1] * sy, point[2]]\n : [point[0] * sx, point[1] * sy],\n );\n if (item.kind === 'connector') {\n for (const key of ['from', 'to'] as const) {\n const endpoint = item[key];\n if (endpoint && !('item' in endpoint)) patch[key] = transformPoint(endpoint);\n }\n if (item.waypoints)\n patch.waypoints = item.waypoints.map(([x, y]) => {\n const point = transformPoint({ x, y });\n return [point.x, point.y];\n });\n }\n this.drafts.set(item.id, patch);\n }\n this.schedule();\n return;\n }\n if (drag.kind === 'rotate') {\n const selected = drag.original.filter((item) => drag.ids.includes(item.id)),\n box = geometryBounds(selected, this.geometryLookup, this.outline),\n center = { x: box.x + box.w / 2, y: box.y + box.h / 2 };\n const delta =\n ((Math.atan2(p.y - center.y, p.x - center.x) -\n Math.atan2(drag.start.y - center.y, drag.start.x - center.x)) *\n 180) /\n Math.PI;\n for (const item of drag.original) {\n const nextCenter = rotatePoint(\n { x: item.x + item.w / 2, y: item.y + item.h / 2 },\n center,\n delta,\n );\n const patch: Partial<Item> = {\n x: nextCenter.x - item.w / 2,\n y: nextCenter.y - item.h / 2,\n rotation: (item.rotation ?? 0) + delta,\n };\n if (item.kind === 'connector') {\n patch.rotation = 0;\n for (const key of ['from', 'to'] as const) {\n const endpoint = item[key];\n if (endpoint && !('item' in endpoint))\n patch[key] = rotatePoint(endpoint, center, delta);\n }\n if (item.waypoints)\n patch.waypoints = item.waypoints.map(([x, y]) => {\n const point = rotatePoint({ x, y }, center, delta);\n return [point.x, point.y];\n });\n }\n this.drafts.set(item.id, patch);\n }\n this.schedule();\n return;\n }\n if (drag.kind === 'marquee') {\n this.stage.setMarquee({\n x: Math.min(p.x, drag.start.x),\n y: Math.min(p.y, drag.start.y),\n w: Math.abs(p.x - drag.start.x),\n h: Math.abs(p.y - drag.start.y),\n });\n return;\n }\n if (drag.kind === 'erase') {\n const item = this.hit(p);\n if (item && !drag.ids.includes(item.id)) {\n drag.ids.push(item.id);\n this.drafts.set(item.id, { hidden: true });\n this.schedule();\n }\n return;\n }\n if (drag.item) {\n const item = drag.item;\n if (item.kind === 'path') {\n const coalesced = e.getCoalescedEvents?.();\n const events = coalesced?.length ? coalesced : [e];\n for (const point of events) {\n const p = this.stage.lens.toPage(this.point(point));\n drag.points!.push([p.x - drag.start.x, p.y - drag.start.y, point.pressure || 0.5]);\n }\n item.points = drag.points;\n item.w = Math.max(1, ...drag.points!.map((v) => v[0]));\n item.h = Math.max(1, ...drag.points!.map((v) => v[1]));\n } else if (item.kind === 'connector') {\n const target = this.hit(p);\n item.to = target ? { item: target.id, side: 'auto' } : p;\n } else {\n let w = Math.abs(p.x - drag.start.x),\n h = Math.abs(p.y - drag.start.y);\n if (e.shiftKey) w = h = Math.max(w, h);\n item.x = p.x < drag.start.x ? drag.start.x - w : drag.start.x;\n item.y = p.y < drag.start.y ? drag.start.y - h : drag.start.y;\n item.w = w;\n item.h = h;\n if (item.kind === 'line') {\n item.points = [\n [drag.start.x - item.x, drag.start.y - item.y],\n [p.x - item.x, p.y - item.y],\n ];\n }\n }\n this.drawPreview = item;\n this.schedule();\n }\n };\n private pointerUp = (e: PointerEvent) => {\n clearTimeout(this.longPressTimer);\n this.pointers.delete(e.pointerId);\n if (this.pinch) {\n if (this.pointers.size < 2) this.pinch = undefined;\n return;\n }\n const drag = this.drag;\n if (!drag || drag.pointer !== e.pointerId) return;\n this.drag = undefined;\n this.updateCursor();\n const touchTap =\n e.pointerType === 'touch' && !drag.moved && ['move', 'marquee'].includes(drag.kind);\n const ops: Op[] = [];\n if (drag.kind === 'move' || drag.kind === 'resize' || drag.kind === 'rotate') {\n if (drag.moved && drag.original.length) {\n if (drag.kind === 'move' && drag.alt) {\n const originals = drag.ids\n .map((id) => drag.original.find((i) => i.id === id)!)\n .filter(Boolean);\n const changed = originals.map((item) => this.withDrafts(item));\n const copies = copyItems(changed, 0);\n ops.push(...copies.map((item) => ({ op: 'add' as const, item, page: this.pageId })));\n this.selectionSignal.value = copies.map((i) => i.id);\n } else for (const [id, patch] of this.drafts) ops.push({ op: 'set', id, patch });\n }\n }\n if (drag.kind === 'marquee' && drag.moved) {\n const p = drag.last,\n b = {\n x: Math.min(p.x, drag.start.x),\n y: Math.min(p.y, drag.start.y),\n w: Math.abs(p.x - drag.start.x),\n h: Math.abs(p.y - drag.start.y),\n };\n this.select([\n ...drag.ids,\n ...this.spatial\n .enclosed(b, {\n enteredGroup: this.enteredGroup,\n ignore: (candidate) => this.stage.isPending(candidate.id),\n })\n .map((i) => i.id),\n ]);\n }\n if (drag.kind === 'erase') ops.push(...drag.ids.map((id) => ({ op: 'remove' as const, id })));\n if (drag.kind === 'draw' && drag.item) {\n const item = drag.item;\n if (!drag.moved) {\n const [w, h] = sizeOf(item.kind);\n item.w = item.kind === 'path' ? 1 : w;\n item.h = item.kind === 'path' ? 1 : h;\n if (item.kind === 'connector') {\n item.to = { x: item.x + 160, y: item.y };\n }\n if (item.kind === 'line')\n item.points = [\n [0, 0],\n [w, 0],\n ];\n if (item.kind === 'path') {\n item.points = [\n [0, 0, 0.5],\n [0.1, 0.1, 0.5],\n ];\n }\n }\n if (item.kind === 'path' && item.points?.length) {\n const minX = Math.min(...item.points.map((p) => p[0])),\n minY = Math.min(...item.points.map((p) => p[1])),\n maxX = Math.max(...item.points.map((p) => p[0])),\n maxY = Math.max(...item.points.map((p) => p[1]));\n item.x += minX;\n item.y += minY;\n item.w = Math.max(1, maxX - minX);\n item.h = Math.max(1, maxY - minY);\n item.points = simplifyStroke(\n item.points.map((p) => [p[0] - minX, p[1] - minY, p[2]]),\n 0.5 / this.view.zoom,\n );\n }\n if (item.kind === 'note' && !item.text?.value)\n item.text = { value: 'A little idea', size: 'l' };\n if (item.kind === 'text' && !item.text?.value)\n item.text = { value: 'Type something…', size: 'l' };\n ops.push({ op: 'add', item, page: this.pageId });\n }\n this.drafts.clear();\n this.drawPreview = undefined;\n this.stage.setMarquee(undefined);\n if (ops.length) {\n const result = this.apply(ops, {\n origin: 'user',\n label:\n drag.kind === 'draw'\n ? `Draw ${drag.item!.kind}`\n : drag.kind === 'move'\n ? 'Move'\n : drag.kind === 'resize'\n ? 'Resize'\n : drag.kind === 'rotate'\n ? 'Rotate'\n : 'Erase',\n });\n if (result.ok && result.created.length) {\n this.select(\n drag.alt\n ? result.created.filter(\n (id) =>\n !this.items.some((p) => flattenItems(p.children ?? []).some((c) => c.id === id)),\n )\n : [result.created[0]],\n );\n }\n if (!result.ok)\n this.host.dispatchEvent(new CustomEvent('ad-error', { detail: result.errors[0]?.message }));\n }\n this.render();\n if (drag.kind === 'draw' && drag.item) {\n const kind = drag.item.kind;\n if (kind !== 'path') this.setTool('select');\n if (kind === 'text' || kind === 'note') this.editText(drag.item.id);\n }\n this.emit('select', this.selection);\n if (touchTap) {\n const screen = this.point(e),\n at = Date.now(),\n previous = this.lastTouchTap;\n this.lastTouchTap = { at, screen };\n if (\n previous &&\n at - previous.at < 350 &&\n Math.hypot(screen.x - previous.screen.x, screen.y - previous.screen.y) < 24\n ) {\n this.lastTouchTap = undefined;\n this.touchDoubleAt = at;\n this.activateAt(screen);\n }\n }\n };\n private pointerCancel = () => this.cancel();\n private wheel = (e: WheelEvent) => {\n if (this.isUI(e.target)) return;\n e.preventDefault();\n if (e.ctrlKey || e.metaKey)\n this.zoomAt(this.view.zoom * Math.exp(-e.deltaY * 0.008), this.point(e));\n else\n this.stage.lens.set({\n x: this.stage.lens.state.x - e.deltaX,\n y: this.stage.lens.state.y - e.deltaY,\n });\n };\n private doubleClick = (e: MouseEvent) => {\n if (this.isUI(e.target) || Date.now() - this.touchDoubleAt < 500) return;\n const target = e.target instanceof Element ? e.target : undefined;\n const targetId = target?.closest<HTMLElement>('[data-ad-id]')?.dataset.adId;\n this.activateAt(this.point(e), targetId);\n };\n private openContext(screen: Point, targetId?: string) {\n const item =\n this.spatial.pick(this.stage.lens.toPage(screen), {\n tolerance: 6 / this.view.zoom,\n includeLocked: true,\n enteredGroup: this.enteredGroup,\n outline: this.outline,\n ignore: (candidate) => this.stage.isPending(candidate.id),\n }) ?? (targetId && !this.stage.isPending(targetId) ? this.get(targetId) : undefined);\n if (item) {\n this.setTool('select');\n this.select([item.id]);\n }\n this.host.dispatchEvent(new CustomEvent('ad-context', { detail: { ...screen, id: item?.id } }));\n }\n private activateAt(screen: Point, targetId?: string) {\n const fromDom = targetId ? this.get(targetId) : undefined;\n const item =\n (fromDom && (fromDom.kind === 'html' || fromDom.kind === 'video') ? fromDom : undefined) ??\n this.hit(this.stage.lens.toPage(screen), true) ??\n fromDom;\n if (item && this.isLocked(item.id)) {\n this.select([item.id]);\n return;\n }\n if (item?.kind === 'group') {\n this.enteredGroup = item.id;\n this.select([]);\n return;\n }\n if (item?.kind === 'html' || item?.kind === 'video') {\n this.activateEmbedded(item);\n return;\n }\n if (item && !['image', 'path', 'line', 'link'].includes(item.kind)) this.editText(item.id);\n else if (!item && !this.readonly) this.add('text', this.stage.lens.toPage(screen));\n }\n private activateEmbedded(item: Item) {\n const view = this.stage.world.querySelector<HTMLElement>(\n `[data-ad-id=\"${CSS.escape(item.id)}\"]`,\n );\n if (!view) return;\n this.clearInteractive();\n view.dataset.adInteractive = 'true';\n if (item.kind !== 'html') return;\n const content = view.querySelector<HTMLElement>('.ad-html-content');\n if (!content) return;\n content.tabIndex = 0;\n content.focus();\n const close = (event: FocusEvent) => {\n if (event.relatedTarget instanceof Node && content.contains(event.relatedTarget)) return;\n delete view.dataset.adInteractive;\n content.tabIndex = -1;\n content.removeEventListener('focusout', close);\n };\n content.addEventListener('focusout', close);\n }\n private clearInteractive(inside?: EventTarget | null) {\n for (const node of this.stage.world.querySelectorAll<HTMLElement>('[data-ad-interactive]')) {\n if (inside instanceof Node && node.contains(inside)) continue;\n delete node.dataset.adInteractive;\n }\n }\n private keyDown = (e: KeyboardEvent) => {\n if (this.isUI(e.target)) return;\n const mod = e.metaKey || e.ctrlKey,\n key = e.key.toLowerCase();\n if (key === 'contextmenu' || (key === 'f10' && e.shiftKey)) {\n e.preventDefault();\n const item = this.selection.length === 1 ? this.get(this.selection[0]) : undefined;\n if (item) {\n const box = itemBounds(item, this.geometryLookup, this.outline);\n const screen = this.stage.lens.toScreen({ x: box.x + box.w / 2, y: box.y + box.h / 2 });\n this.host.dispatchEvent(\n new CustomEvent('ad-context', { detail: { ...screen, id: item.id } }),\n );\n }\n return;\n }\n if (e.code === 'Space') {\n e.preventDefault();\n this.space = true;\n this.updateCursor();\n return;\n }\n if (key === 'escape') {\n this.cancel();\n this.enteredGroup = undefined;\n this.select([]);\n this.setTool('select');\n return;\n }\n if (mod && key === 'a') {\n e.preventDefault();\n this.select(\n this.items\n .filter((i) => !i.hidden && !i.locked && !this.stage.isPending(i.id))\n .map((i) => i.id),\n );\n return;\n }\n if (key === '1' && !mod) {\n this.view.zoom = 1;\n return;\n }\n if (key === '2' && !mod) {\n this.view.fit();\n return;\n }\n if (key === '+' || key === '=') {\n this.view.zoom *= 1.2;\n return;\n }\n if (key === '-') {\n this.view.zoom /= 1.2;\n return;\n }\n if (this.readonly) return;\n if (mod && key === 'z') {\n e.preventDefault();\n if (e.shiftKey) this.redo();\n else this.undo();\n return;\n }\n if (mod && key === 'y') {\n e.preventDefault();\n this.redo();\n return;\n }\n if (mod && key === 'd') {\n e.preventDefault();\n this.duplicate();\n return;\n }\n if (mod && key === 'g') {\n e.preventDefault();\n if (e.shiftKey) this.ungroup();\n else this.group();\n return;\n }\n if (key === 'delete' || key === 'backspace') {\n e.preventDefault();\n this.deleteSelection();\n return;\n }\n if (key === 'enter' && this.selection.length === 1) {\n e.preventDefault();\n const selected = this.get(this.selection[0]);\n if (selected?.kind === 'html' || selected?.kind === 'video') this.activateEmbedded(selected);\n else if (selected && !['image', 'path', 'line', 'link'].includes(selected.kind))\n this.editText(selected.id);\n return;\n }\n if (key === '[' || key === ']') {\n e.preventDefault();\n this.apply(\n this.selection.map((id) => ({\n op: 'order',\n id,\n to: key === ']' ? (e.shiftKey ? 'front' : 'forward') : e.shiftKey ? 'back' : 'backward',\n })),\n { origin: 'user', label: 'Reorder' },\n );\n return;\n }\n if (key.startsWith('arrow')) {\n e.preventDefault();\n const delta = e.shiftKey ? 10 : 1,\n dx = key === 'arrowleft' ? -delta : key === 'arrowright' ? delta : 0,\n dy = key === 'arrowup' ? -delta : key === 'arrowdown' ? delta : 0;\n this.apply(\n this.movable(this.topSelection()).map((i) => ({\n op: 'set',\n id: i.id,\n patch: translateItem(i, dx, dy),\n })),\n { origin: 'user', label: 'Nudge' },\n );\n return;\n }\n if (!mod && shortcuts[key]) {\n e.preventDefault();\n this.setTool(shortcuts[key]);\n }\n };\n private withDrafts(item: Item): Item {\n const next = applyDraft(item, this.drafts.get(item.id));\n return next.children\n ? { ...next, children: next.children.map((child) => this.withDrafts(child)) }\n : next;\n }\n private copyEvent = (e: ClipboardEvent) => {\n if (this.isUI(e.target) || !this.selection.length) return;\n e.preventDefault();\n this.clipboard = this.topSelection()\n .map((id) => this.get(id)!)\n .filter(Boolean);\n const media: AnnieDoc['media'] = {};\n for (const item of flattenItems(this.clipboard))\n if (item.media && this.document.media[item.media])\n media[item.media] = clone(this.document.media[item.media]);\n detachMissingEndpoints(this.clipboard, this.geometryLookup, this.outline);\n const value = JSON.stringify({\n format: 'anniedrawing-clipboard',\n items: this.clipboard,\n media,\n });\n e.clipboardData?.setData(ANNIE_MIME, value);\n e.clipboardData?.setData('text/plain', value);\n };\n private cutEvent = (e: ClipboardEvent) => {\n if (this.readonly || this.isUI(e.target)) return;\n this.copyEvent(e);\n this.deleteSelection();\n };\n private pasteEvent = (e: ClipboardEvent) => {\n if (this.readonly || this.isUI(e.target)) return;\n const files = [...(e.clipboardData?.files ?? [])];\n if (files.length) {\n e.preventDefault();\n files.forEach(\n (file) =>\n void this.addImage(file).catch((error) =>\n this.host.dispatchEvent(new CustomEvent('ad-error', { detail: String(error) })),\n ),\n );\n return;\n }\n if (!e.clipboardData) return;\n e.preventDefault();\n void this.pasteFrom(e.clipboardData);\n };\n private pasteFrom(data: DataTransfer | null, point?: Point) {\n const text =\n data?.getData(ANNIE_MIME) || clipboardText(data) || data?.getData('text/html') || '';\n if (!text) return;\n try {\n const parsed = JSON.parse(text);\n if (!parsed || typeof parsed !== 'object' || !Array.isArray(parsed.items))\n throw new Error('not clipboard json');\n const copies = copyItems(parsed.items, 24),\n mediaIds = new Map(Object.keys(parsed.media ?? {}).map((id) => [id, mediaId()])),\n ops: Op[] = Object.entries(parsed.media ?? {}).map(([id, media]) => ({\n op: 'media.set',\n id: mediaIds.get(id)!,\n media: media as AnnieDoc['media'][string],\n }));\n for (const item of flattenItems(copies))\n if (item.media && mediaIds.has(item.media)) item.media = mediaIds.get(item.media);\n ops.push(...copies.map((item) => ({ op: 'add' as const, item, page: this.pageId })));\n const result = this.apply(ops, { origin: 'user', label: 'Paste' });\n if (result.ok) this.select(copies.map((i) => i.id));\n else\n this.host.dispatchEvent(new CustomEvent('ad-error', { detail: result.errors[0]?.message }));\n } catch {\n void import('./input/urlPaste').then(({ pastePlain }) =>\n pastePlain(this.pasteHost(), text, point),\n );\n }\n }\n private drop = (e: DragEvent) => {\n if (this.readonly) return;\n e.preventDefault();\n const p = this.stage.lens.toPage(this.point(e));\n const files = [...(e.dataTransfer?.files ?? [])];\n if (files.length) {\n for (const file of files)\n void (async () => {\n try {\n if (file.name.endsWith('.annie') || file.type === 'application/json')\n this.load(JSON.parse(await file.text()));\n else await this.addImage(file, p);\n } catch (error) {\n this.host.dispatchEvent(new CustomEvent('ad-error', { detail: String(error) }));\n }\n })();\n return;\n }\n if (e.dataTransfer) void this.pasteFrom(e.dataTransfer, p);\n };\n}\n/** Mount a board in `host`. See `BoardOptions` for theme, chrome, and export. */\nexport function createBoard(host: HTMLElement, options?: BoardOptions) {\n return new Board(host, options);\n}\ndeclare global {\n interface Window {\n __anniedrawing?: Board[];\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var e=1,t=[{kind:"rect",since:1,w:180,h:110,note:"Rounded rectangle. Nodes, cards, boxes."},{kind:"ellipse",since:1,w:180,h:110,note:"Ellipse or circle."},{kind:"diamond",since:1,w:160,h:140,note:"Diamond. Decisions or highlights."},{kind:"line",since:1,w:180,h:0,note:"Straight segment. Optional points are relative to x/y."},{kind:"connector",since:1,w:0,h:0,note:"Bound or free link. Requires from and to. Compact JSON omits x/y/w/h."},{kind:"path",since:1,w:0,h:0,note:"Freehand or polyline. points relative to x/y; closed optional."},{kind:"text",since:1,w:200,h:48,note:"Plain text. Browser autoWidth measures and stores width and height."},{kind:"note",since:1,w:200,h:180,note:"Sticky note. Default moss fill and 12px corner."},{kind:"image",since:1,w:240,h:180,note:"References a media table key. Raster or SVG; remote URLs need allowed origins."},{kind:"video",since:1,w:480,h:270,note:"YouTube or Vimeo href. Stores the watch URL, not iframe markup."},{kind:"link",since:1,w:220,h:200,note:"Website card. href plus optional title, description, and preview media."},{kind:"group",since:1,w:0,h:0,note:"Only kind that contains children. Child positions stay in page coordinates."},{kind:"html",since:1,w:240,h:160,note:"Markup. Renders only when the host passed a sanitizer."}];function n(e=0){const n=e||0;return{version:1,since:n,kinds:t.filter(e=>e.since>n).map(e=>({...e}))}}var i=e=>crypto.getRandomValues(new Uint8Array(e)),r=((e,t=21)=>((e,t,n)=>{let i=256-256%e.length;if(256===i){let i=e.length-1;return(r=t)=>{if(!r)return"";let o="";for(;;){let t=n(r),s=r;for(;s--;)if(o+=e[t[s]&i],o.length>=r)return o}}}let r=Math.ceil(409.6*t/i);return(o=t)=>{if(!o)return"";let s="";for(;;){let t=n(r),l=r;for(;l--;)if(t[l]<i&&(s+=e[t[l]%e.length],s.length>=o))return s}}})(e,0|t,i))("346789abcdefghjkmnpqrtwxyz",6),o=()=>`i_${r()}`,s=()=>`p_${r()}`,l=()=>`m_${r()}`;function a(e,t){if(e&&!t.has(e)&&e.length<=160)return e;const n=(e.replace(/_\d+$/,"")||e||"i").slice(0,158);for(let i=1;i<1e7;i++){const e=`_${i}`,r=`${n.slice(0,160-e.length)}${e}`;if(!t.has(r))return r}return o()}var d={rectangle:"rect",arrow:"connector"},c={black:"ink",grey:"slate",gray:"slate",blue:"sky","light-blue":"sky",green:"teal","light-green":"moss",red:"rose","light-red":"rose",orange:"coral",yellow:"amber",violet:"violet","light-violet":"violet"};function h(e){return d[e]??e}function f(e){if(void 0!==e)return c[e]??e}function u(e){if(void 0!==e)return"string"==typeof e?{item:e,side:"auto"}:e}function k(e){if(!e)return e;const t=f(e.stroke),n=f(e.fill);return t===e.stroke&&n===e.fill?e:{...e,...void 0!==t?{stroke:t}:{},...void 0!==n?{fill:n}:{}}}var m=12,y={stroke:"ink",strokeWidth:2,dash:"solid",fill:"none",fillMode:"solid",corner:12,opacity:1},g=Object.fromEntries(t.map(e=>[e.kind,[e.w,e.h]]));function p(e){return structuredClone(e)}function w(e){return g[e]??[180,110]}function v(e){return Object.fromEntries((e??[]).filter(e=>e.defaults).map(e=>[e.kind,e.defaults]))}function b(){return{format:"anniedrawing",version:2,meta:{title:"Untitled board"},pages:[{id:"p_main",name:"Page 1",background:"paper",items:[]}],media:{}}}function x(e,t={}){const n=e.kind,i=h(n),r=t[i]??t[n];e={...e,kind:i},r&&(e={...p(r),...e,...r.style?{style:{...p(r.style),...e.style}}:{}});const s=w(i),l={...p(e),id:e.id??o(),kind:i,x:e.x??0,y:e.y??0,w:e.w??s[0],h:e.h??s[1]},a=u(e.from),d=u(e.to),c=k(e.style);return a?l.from=a:delete l.from,d?l.to=d:delete l.to,c?l.style=c:delete l.style,"arrow"===n&&(void 0===l.heads?.end&&(l.heads={...l.heads,end:"arrow"}),void 0===l.route&&(l.route="elbow")),e.children&&(l.children=e.children.map(e=>x(e,t))),l}function R(e,t={}){const n={...y,..."note"===e.kind?{fill:"moss",strokeWidth:0,corner:12}:{},...t[e.kind]?.style},i=p(e);if(0===i.rotation&&delete i.rotation,!1===i.locked&&delete i.locked,!1===i.hidden&&delete i.hidden,i.style){for(const e of Object.keys(i.style))i.style[e]===n[e]&&delete i.style[e];Object.keys(i.style).length||delete i.style}return i.children&&(i.children=i.children.map(e=>R(e,t)),i.children.length||delete i.children),"connector"===i.kind&&(delete i.x,delete i.y,delete i.w,delete i.h),i}export{a as _,p as a,n as b,R as c,f as d,u as f,s as g,l as h,k as i,x as l,o as m,g as n,b as o,h as p,y as r,v as s,m as t,w as u,e as v,t as y};
|
|
2
|
-
//# sourceMappingURL=defaults-C-aC_B4z.js.map
|