@memberjunction/ng-whiteboard 6.1.4 → 6.2.0-edge.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"whiteboard-state.js","sourceRoot":"","sources":["../../src/lib/whiteboard-state.ts"],"names":[],"mappings":"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","sourcesContent":["import { Observable, Subject } from 'rxjs';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/**\n * WHITEBOARD — typed board model + state engine.\n *\n * This file is intentionally Angular-free: it is the single mutation API used by BOTH the\n * user-facing board tools (pen, stickies, shapes, …) and any programmatic co-author —\n * typically an AI agent driving the `Whiteboard_*` tool set (`Whiteboard_AddNote`,\n * `Whiteboard_DrawConnector`, …, see `whiteboard-tools.ts`).\n *\n * Pages (OneNote-style): a board is an ordered list of named PAGES, each with its own\n * items collection; exactly one page is ACTIVE at a time and every item operation\n * (add / update / move / remove / connectors / clear / perception) targets the active\n * page. See {@link WhiteboardState.AddPage} / {@link WhiteboardState.SwitchPage} /\n * {@link WhiteboardState.RenamePage} / {@link WhiteboardState.RemovePage}. A fresh\n * board starts with one page named \"Page 1\"; legacy (pre-pages, flat) persisted JSON\n * rehydrates as that single page.\n *\n * Perception model (how a programmatic co-author \"sees\" the board):\n * - every mutation appends to a compact change journal and emits on {@link WhiteboardState.Changed$};\n * - {@link WhiteboardState.BuildSceneDelta} coalesces the journal since a token into ONE delta\n * (multiple moves of one item → one `moved` entry) with replace-current-state semantics;\n * - {@link WhiteboardState.BuildSceneSummary} produces the full compact scene the\n * \"What the agent sees\" popover renders;\n * - {@link WhiteboardState.ToJSON} / {@link WhiteboardState.FromJSON} persist the board's\n * state of record (e.g. a session-channel artifact in MJ realtime sessions).\n *\n * Extensibility: every targeted mutation also raises a cancelable BEFORE event and a\n * matching AFTER event (`ItemAdding$` / `ItemAdded$`, `ItemUpdating$` / `ItemUpdated$`,\n * `ItemRemoving$` / `ItemRemoved$`) — see the {@link WhiteboardState} class docs.\n */\n\n/** Who authored a board item / mutation. The violet treatment is RESERVED for `'agent'`. */\nexport type WhiteboardAuthor = 'user' | 'agent';\n\n/** The discriminant for the {@link WhiteboardItem} union. */\nexport type WhiteboardItemKind = 'sticky' | 'shape' | 'ink' | 'text' | 'image' | 'connector' | 'highlight' | 'markdown' | 'html';\n\n/** Shape geometry of a {@link WhiteboardShapeItem}. */\nexport type WhiteboardShapeKind = 'rect' | 'ellipse' | 'diamond';\n\n/** Visual tint of a USER sticky (agent stickies always render violet, regardless of tint). */\nexport type WhiteboardStickyTint = 'amber' | 'amber-light';\n\n/**\n * Curated font-size steps for text labels and sticky notes. The toolbar's text-style flyout\n * and the agent's `fontSize` tool params both restrict to these values.\n */\nexport const WHITEBOARD_FONT_SIZES: readonly number[] = [12, 14, 18, 24, 32];\n\n/**\n * Font family choices for text labels / stickies. The keys are mapped to token-friendly\n * font stacks in the board CSS (`wb-font-serif`, `wb-font-mono`; sans is the default).\n */\nexport type WhiteboardFontFamily = 'sans' | 'serif' | 'mono';\n\n/** Font weights for text labels / stickies (regular or bold). */\nexport type WhiteboardFontWeight = 400 | 700;\n\n/** A point in board (content) coordinates. */\nexport interface WhiteboardPoint {\n X: number;\n Y: number;\n}\n\n/** Fields shared by every board item. */\nexport interface WhiteboardItemBase {\n /** Stable item id (e.g. `sticky-3`) — referenced by connectors, deltas and agent tools. */\n ID: string;\n /** Who placed the item. Drives the ownership chrome (chips / violet vs slate-amber). */\n Author: WhiteboardAuthor;\n /** Render order (higher renders on top). Assigned by the engine. */\n Z: number;\n}\n\n/** A sticky note. */\nexport interface WhiteboardStickyItem extends WhiteboardItemBase {\n Kind: 'sticky';\n X: number;\n Y: number;\n /** Width in px; defaults to {@link WHITEBOARD_DEFAULTS.StickyW} when omitted. */\n W?: number;\n Text: string;\n /** User-palette tint; ignored for agent stickies (always violet). */\n Tint?: WhiteboardStickyTint;\n /** Slight playful tilt, in degrees. */\n Rotation?: number;\n /** Curated font size (see {@link WHITEBOARD_FONT_SIZES}); omitted = the CSS default. */\n FontSize?: number;\n /** Font family key (mapped to token-friendly stacks in CSS); omitted = sans. */\n FontFamily?: WhiteboardFontFamily;\n /** Font weight; omitted = the kind's CSS default. */\n FontWeight?: WhiteboardFontWeight;\n}\n\n/** A drawn shape box (rect / ellipse / diamond) with an optional label + sub-label. */\nexport interface WhiteboardShapeItem extends WhiteboardItemBase {\n Kind: 'shape';\n Shape: WhiteboardShapeKind;\n X: number;\n Y: number;\n W: number;\n H: number;\n Label: string;\n Sub?: string;\n}\n\n/** A free-floating text label. */\nexport interface WhiteboardTextItem extends WhiteboardItemBase {\n Kind: 'text';\n X: number;\n Y: number;\n Text: string;\n /** Wrap width in px — text wraps at this width. Omitted = wrap at the default max width. */\n W?: number;\n /** Curated font size (see {@link WHITEBOARD_FONT_SIZES}); omitted = the CSS default. */\n FontSize?: number;\n /** Font family key (mapped to token-friendly stacks in CSS); omitted = sans. */\n FontFamily?: WhiteboardFontFamily;\n /** Font weight; omitted = the kind's CSS default. */\n FontWeight?: WhiteboardFontWeight;\n /**\n * Text color from the USER pen palette. Violet is reserved for the agent's ownership\n * styling (enforced in the user UI — the palette never offers violet); agent text gets\n * its violet from the Author treatment, never from this field.\n */\n Color?: string;\n}\n\n/** A pasted / inserted image card. `Url` is a runtime object URL (not persisted as pixels). */\nexport interface WhiteboardImageItem extends WhiteboardItemBase {\n Kind: 'image';\n X: number;\n Y: number;\n /** Width in px; defaults to {@link WHITEBOARD_DEFAULTS.ImageW}. */\n W?: number;\n Name: string;\n Url?: string | null;\n}\n\n/** A freehand ink stroke (polyline in board coordinates, smoothed at render time). */\nexport interface WhiteboardInkItem extends WhiteboardItemBase {\n Kind: 'ink';\n Points: WhiteboardPoint[];\n /** Stroke color. The user palette NEVER includes violet — violet ink is the agent's. */\n Color: string;\n StrokeWidth: number;\n}\n\n/**\n * A connector between two endpoints. Each endpoint references an item by ID when attached;\n * when the referenced item is removed (or was never set) the endpoint falls back to the\n * absolute `…Point` coordinate.\n */\nexport interface WhiteboardConnectorItem extends WhiteboardItemBase {\n Kind: 'connector';\n FromItemID?: string | null;\n ToItemID?: string | null;\n FromPoint?: WhiteboardPoint | null;\n ToPoint?: WhiteboardPoint | null;\n}\n\n/** A pulsing highlight region (\"pointing without touching\") — dismissed by clicking it. */\nexport interface WhiteboardHighlightItem extends WhiteboardItemBase {\n Kind: 'highlight';\n X: number;\n Y: number;\n W: number;\n H: number;\n Label?: string;\n}\n\n/**\n * A rendered MARKDOWN panel — a rich, formatted card (headings, lists, code, links) for\n * illustrative content that outgrows a sticky note. Width is explicit (the panel's column\n * width); height is content-driven, optionally capped by `H` (overflow clips).\n */\nexport interface WhiteboardMarkdownItem extends WhiteboardItemBase {\n Kind: 'markdown';\n X: number;\n Y: number;\n /** Panel width in px (required — markdown always renders in an explicit column). */\n W: number;\n /** Optional max height in px; content beyond it is clipped. Omitted = content-driven. */\n H?: number;\n /** The markdown source. Rendered SAFELY (sanitized — never raw HTML passthrough). */\n Markdown: string;\n}\n\n/**\n * An interactive HTML widget — arbitrary HTML (scripts included) rendered inside a\n * STRICTLY SANDBOXED iframe (`sandbox=\"allow-scripts\"` only, opaque origin — see the\n * board component for the full security rationale). Dragged/selected by its card chrome —\n * header bar, border ring and lazy placeholder — while pointer events inside the sandboxed\n * frame stay with the widget, so iframe interactivity and board interactions coexist.\n */\nexport interface WhiteboardHtmlItem extends WhiteboardItemBase {\n Kind: 'html';\n X: number;\n Y: number;\n W: number;\n H: number;\n /** The widget's full HTML source (becomes the sandboxed iframe's `srcdoc`). */\n Html: string;\n /** Optional title shown on the widget's header bar. */\n Title?: string;\n}\n\n/** Discriminated union of everything that can live on the board. */\nexport type WhiteboardItem =\n | WhiteboardStickyItem\n | WhiteboardShapeItem\n | WhiteboardTextItem\n | WhiteboardImageItem\n | WhiteboardInkItem\n | WhiteboardConnectorItem\n | WhiteboardHighlightItem\n | WhiteboardMarkdownItem\n | WhiteboardHtmlItem;\n\n/** Distributive Omit that preserves the discriminated union. */\ntype DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;\n\n/** What callers pass to {@link WhiteboardState.AddItem} — the engine stamps ID / Z / Author. */\nexport type WhiteboardItemInput = DistributiveOmit<WhiteboardItem, 'ID' | 'Z' | 'Author'>;\n\n/** Patchable fields for {@link WhiteboardState.UpdateItem} (kind/identity fields excluded). */\nexport interface WhiteboardItemPatch {\n X?: number;\n Y?: number;\n W?: number;\n H?: number;\n Text?: string;\n Label?: string;\n Sub?: string;\n Name?: string;\n Url?: string | null;\n Color?: string;\n StrokeWidth?: number;\n Points?: WhiteboardPoint[];\n Tint?: WhiteboardStickyTint;\n Rotation?: number;\n FontSize?: number;\n FontFamily?: WhiteboardFontFamily;\n FontWeight?: WhiteboardFontWeight;\n Shape?: WhiteboardShapeKind;\n Markdown?: string;\n Html?: string;\n Title?: string;\n FromItemID?: string | null;\n ToItemID?: string | null;\n FromPoint?: WhiteboardPoint | null;\n ToPoint?: WhiteboardPoint | null;\n}\n\n/** Mutation kinds carried on {@link WhiteboardChange} and in the journal. */\nexport type WhiteboardChangeOp = 'add' | 'update' | 'move' | 'remove' | 'replace';\n\n// ────────────────────────────────────────────── before / after mutation events\n\n/**\n * Base shape of every cancelable BEFORE event raised by {@link WhiteboardState} (and by\n * the components layered on top of it). Handlers run SYNCHRONOUSLY during the emit; any\n * handler may set {@link Cancel} to `true` and the operation is aborted before it touches\n * the board (no undo snapshot, no journal entry, no {@link WhiteboardState.Changed$}\n * emission). The matching AFTER event then never fires.\n */\nexport interface WhiteboardCancelableEventArgs {\n /** Set to `true` (in a synchronous handler) to veto the operation. */\n Cancel: boolean;\n}\n\n/**\n * BEFORE-event args for {@link WhiteboardState.ItemAdding$}. Raised by\n * {@link WhiteboardState.AddItem} (and therefore also by {@link WhiteboardState.Highlight}\n * and {@link WhiteboardState.DuplicateItem}, which add through it) before anything is\n * stamped or stored. Handlers may mutate {@link Input} (e.g. clamp coordinates, rewrite\n * text) — the engine adds whatever the args carry after the emit — or set `Cancel` to\n * veto the add entirely (the caller receives `null`).\n */\nexport interface WhiteboardItemAddingEventArgs extends WhiteboardCancelableEventArgs {\n /** The item about to be added (no ID / Z / Author yet — the engine stamps those). */\n Input: WhiteboardItemInput;\n /** Who is adding the item. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.ItemAdded$} — the item is on the board. */\nexport interface WhiteboardItemAddedEventArgs {\n /** The added item, with its engine-stamped ID / Z / Author. */\n Item: WhiteboardItem;\n /** Who added the item. */\n Author: WhiteboardAuthor;\n}\n\n/**\n * Which mutation family an updating/updated event describes:\n * - `'update'` — a field patch via {@link WhiteboardState.UpdateItem};\n * - `'move'` — a reposition via {@link WhiteboardState.MoveItem};\n * - `'reorder'` — a z-order change via {@link WhiteboardState.BringToFront} /\n * {@link WhiteboardState.SendToBack}.\n */\nexport type WhiteboardUpdateOperation = 'update' | 'move' | 'reorder';\n\n/**\n * BEFORE-event args for {@link WhiteboardState.ItemUpdating$}. {@link Item} is the LIVE,\n * pre-mutation item (do not mutate it directly — cancel and apply your own patch\n * instead). For `'update'` operations handlers may adjust {@link Patch}; for `'move'`\n * operations {@link Position} carries the requested top-left target.\n */\nexport interface WhiteboardItemUpdatingEventArgs extends WhiteboardCancelableEventArgs {\n /** The item about to change (current, pre-mutation state). */\n Item: WhiteboardItem;\n /** Which mutation family is about to run. */\n Operation: WhiteboardUpdateOperation;\n /** The field patch (`'update'` operations only). Handlers may adjust it. */\n Patch?: WhiteboardItemPatch;\n /** The requested top-left position (`'move'` operations only). */\n Position?: WhiteboardPoint;\n /** Who is changing the item. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.ItemUpdated$} — the change has applied. */\nexport interface WhiteboardItemUpdatedEventArgs {\n /** The item in its post-mutation state. */\n Item: WhiteboardItem;\n /** Which mutation family ran. */\n Operation: WhiteboardUpdateOperation;\n /** Who changed the item. */\n Author: WhiteboardAuthor;\n}\n\n/**\n * BEFORE-event args for {@link WhiteboardState.ItemRemoving$} — raised before the item\n * leaves the board (and before any connector endpoints anchored to it are frozen).\n * Cancel to keep the item.\n */\nexport interface WhiteboardItemRemovingEventArgs extends WhiteboardCancelableEventArgs {\n /** The item about to be removed. */\n Item: WhiteboardItem;\n /** Who is removing the item. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.ItemRemoved$} — the item is gone. */\nexport interface WhiteboardItemRemovedEventArgs {\n /** The removed item (its last state — no longer on the board). */\n Item: WhiteboardItem;\n /** Who removed the item. */\n Author: WhiteboardAuthor;\n}\n\n/**\n * BEFORE-event args for {@link WhiteboardState.ContentChanging$} — raised (in addition to\n * {@link WhiteboardState.ItemUpdating$}) when an {@link WhiteboardState.UpdateItem} patch\n * touches an item's CONTENT fields: `Text`, `Label`, `Sub`, `Markdown`, `Html` or `Title`.\n * This is the hook for content governance (length limits, redaction, moderation) without\n * having to inspect every geometry patch. Cancel to veto the whole update.\n */\nexport interface WhiteboardContentChangingEventArgs extends WhiteboardCancelableEventArgs {\n /** The item whose content is about to change (current, pre-mutation state). */\n Item: WhiteboardItem;\n /** The full patch being applied (content fields included). Handlers may adjust it. */\n Patch: WhiteboardItemPatch;\n /** Who is changing the content. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.ContentChanged$} — the content has applied. */\nexport interface WhiteboardContentChangedEventArgs {\n /** The item in its post-mutation state. */\n Item: WhiteboardItem;\n /** The patch that was applied. */\n Patch: WhiteboardItemPatch;\n /** Who changed the content. */\n Author: WhiteboardAuthor;\n}\n\n/**\n * AFTER-event args for {@link WhiteboardState.SelectionChanged$} — the selection changed\n * (single OR multi). Selection is UI state: it is not journaled, not undoable and not\n * persisted, so this event is a notification only (not cancelable). Fires for explicit\n * {@link WhiteboardState.Select} / {@link WhiteboardState.ToggleSelect} /\n * {@link WhiteboardState.SelectMany} calls AND for implicit clears (a selected item was\n * removed, the page switched, or a restore dropped it).\n */\nexport interface WhiteboardSelectionChangedEventArgs {\n /** The PRIMARY selected item's ID (last added to the selection), or null when cleared. */\n SelectedID: string | null;\n /** The previously primary item's ID, or null when nothing was selected. */\n PreviousID: string | null;\n /** The full multi-selection (selection order, last = primary). Empty when cleared. */\n SelectedIDs: string[];\n}\n\n/**\n * AFTER-event args for {@link WhiteboardState.BoardCleared$} — every item was removed in\n * one operation via {@link WhiteboardState.Clear}. The clear is a single undo step; one\n * `'replace'` op lands in the journal so perception consumers re-read the (now empty)\n * scene.\n */\nexport interface WhiteboardBoardClearedEventArgs {\n /** Who cleared the board. */\n Author: WhiteboardAuthor;\n /** How many items were removed (highlights included). */\n ItemCount: number;\n}\n\n/**\n * AFTER-event args for {@link WhiteboardState.BoardLoaded$} — a persisted board was\n * rehydrated IN PLACE via {@link WhiteboardState.LoadFromJSON}. Undo/redo stacks and the\n * journal were reset (the restored state is the new baseline) and one `'replace'` op was\n * journaled, so perception consumers re-read the full scene.\n */\nexport interface WhiteboardBoardLoadedEventArgs {\n /** How many items the restored board contains (summed across ALL pages). */\n ItemCount: number;\n}\n\n// ────────────────────────────────────────────── pages\n\n/**\n * Public, read-only descriptor of one board page — what {@link WhiteboardState.Pages}\n * returns and what every page before/after event carries. A snapshot, not a live view:\n * re-read {@link WhiteboardState.Pages} after mutations.\n */\nexport interface WhiteboardPageInfo {\n /** Stable page id (e.g. `page-2`) — accepted anywhere a page name is accepted. */\n ID: string;\n /** Display name (e.g. \"Page 1\"). Not guaranteed unique; IDs are. */\n Name: string;\n /** How many items live on the page (highlights included). */\n ItemCount: number;\n /** Whether this is the board's active page. */\n Active: boolean;\n /**\n * Who CREATED the page. Drives the page strip's delegated-violet garnish for\n * agent-created pages (mirroring the item-level agent treatment). Persisted in the\n * v2 JSON as an additive `author` field; payloads without it rehydrate as `'user'`.\n */\n Author: WhiteboardAuthor;\n}\n\n/**\n * BEFORE-event args for {@link WhiteboardState.PageAdding$} — raised by\n * {@link WhiteboardState.AddPage} before the page exists. Handlers may rewrite\n * {@link Name} (the engine trims it; an emptied name falls back to the auto-name) or set\n * `Cancel` to veto the add (the caller receives `null`).\n */\nexport interface WhiteboardPageAddingEventArgs extends WhiteboardCancelableEventArgs {\n /** The name the page will get (auto-named \"Page N\" when the caller omitted one). */\n Name: string;\n /** Who is adding the page. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.PageAdded$} — the page exists and is active. */\nexport interface WhiteboardPageAddedEventArgs {\n /** The added page (now the active page). */\n Page: WhiteboardPageInfo;\n /** Who added the page. */\n Author: WhiteboardAuthor;\n}\n\n/**\n * BEFORE-event args for {@link WhiteboardState.PageSwitching$} — raised by\n * {@link WhiteboardState.SwitchPage} before the active page changes. Cancel to stay on\n * the current page.\n */\nexport interface WhiteboardPageSwitchingEventArgs extends WhiteboardCancelableEventArgs {\n /** The page that is currently active. */\n FromPage: WhiteboardPageInfo;\n /** The page about to become active. */\n ToPage: WhiteboardPageInfo;\n /** Who is switching. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.PageSwitched$} — the active page changed. */\nexport interface WhiteboardPageSwitchedEventArgs {\n /** The previously active page. */\n FromPage: WhiteboardPageInfo;\n /** The newly active page. */\n ToPage: WhiteboardPageInfo;\n /** Who switched. */\n Author: WhiteboardAuthor;\n}\n\n/**\n * BEFORE-event args for {@link WhiteboardState.PageRenaming$} — raised by\n * {@link WhiteboardState.RenamePage}. Handlers may rewrite {@link NewName} (trimmed by\n * the engine; an emptied rewrite aborts the rename) or set `Cancel` to veto.\n */\nexport interface WhiteboardPageRenamingEventArgs extends WhiteboardCancelableEventArgs {\n /** The page about to be renamed (pre-rename snapshot). */\n Page: WhiteboardPageInfo;\n /** The requested new name. Handlers may adjust it. */\n NewName: string;\n /** Who is renaming. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.PageRenamed$} — the rename applied. */\nexport interface WhiteboardPageRenamedEventArgs {\n /** The page in its post-rename state. */\n Page: WhiteboardPageInfo;\n /** The name the page had before. */\n OldName: string;\n /** Who renamed it. */\n Author: WhiteboardAuthor;\n}\n\n/**\n * BEFORE-event args for {@link WhiteboardState.PageRemoving$} — raised by\n * {@link WhiteboardState.RemovePage} (never for the last remaining page — that is\n * guarded before the event). Cancel to keep the page.\n */\nexport interface WhiteboardPageRemovingEventArgs extends WhiteboardCancelableEventArgs {\n /** The page about to be removed (with all of its items). */\n Page: WhiteboardPageInfo;\n /** Who is removing it. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.PageRemoved$} — the page is gone. */\nexport interface WhiteboardPageRemovedEventArgs {\n /** The removed page (its last state). */\n Page: WhiteboardPageInfo;\n /** When the REMOVED page was active: the neighbor page that became active. Else null. */\n ActivatedPage: WhiteboardPageInfo | null;\n /** Who removed it. */\n Author: WhiteboardAuthor;\n}\n\n/** Compact page descriptor carried on scene deltas / summaries (model-facing). */\nexport interface WhiteboardScenePage {\n id: string;\n name: string;\n active: boolean;\n items: number;\n}\n\n/**\n * One coalesce-able change notification, emitted on {@link WhiteboardState.Changed$}\n * after every mutation. `'replace'` means \"the whole scene was swapped\" (undo / redo /\n * FromJSON) — consumers should re-read the full state.\n */\nexport interface WhiteboardChange {\n Op: WhiteboardChangeOp;\n /** Empty string for `'replace'` ops. */\n ItemID: string;\n Author: WhiteboardAuthor;\n /** Human fragment for toasts / activity (\"added a sticky note\"). */\n SummaryFragment: string;\n /** Monotonic sequence number — also the delta token currency. */\n Seq: number;\n}\n\n/** Compact, model-facing representation of one item inside deltas / summaries. */\nexport interface WhiteboardCompactItem {\n id: string;\n type: WhiteboardItemKind;\n author: WhiteboardAuthor;\n x?: number;\n y?: number;\n w?: number;\n h?: number;\n /** Clipped text content (sticky/text/shape labels; markdown/html: clipped SOURCE). */\n text?: string;\n shape?: WhiteboardShapeKind;\n /** Image file name, or the html widget's Title. */\n name?: string;\n from?: string | WhiteboardPoint | null;\n to?: string | WhiteboardPoint | null;\n points?: number;\n fontSize?: number;\n fontFamily?: WhiteboardFontFamily;\n bold?: boolean;\n color?: string;\n}\n\n/**\n * The coalesced scene delta fed into the live agent context (\"What the agent sees\").\n * Replace-current-state semantics: each entry is the item's CURRENT state, not an edit log.\n * When `reset` is true the `items` array replaces the agent's entire view of the board\n * (emitted after undo/redo/load, or when the journal no longer reaches the caller's token).\n */\nexport interface WhiteboardSceneDelta {\n op: 'scene-delta';\n seq: number;\n added: WhiteboardCompactItem[];\n moved: { id: string; x: number; y: number }[];\n updated: WhiteboardCompactItem[];\n removed: string[];\n reset?: boolean;\n items?: WhiteboardCompactItem[];\n /** The board's page list — `active: true` marks the page the item entries describe. */\n pages: WhiteboardScenePage[];\n summary: string;\n}\n\n/** Full compact scene snapshot (popover stats + delta-reset payloads). ACTIVE page only. */\nexport interface WhiteboardSceneSummary {\n op: 'scene-summary';\n seq: number;\n counts: {\n total: number;\n user: number;\n agent: number;\n byKind: Partial<Record<WhiteboardItemKind, number>>;\n };\n items: WhiteboardCompactItem[];\n /** The board's page list — `active: true` marks the page the item entries describe. */\n pages: WhiteboardScenePage[];\n summary: string;\n}\n\n/** Axis-aligned bounds of an item, in board coordinates. */\nexport interface WhiteboardBounds {\n X: number;\n Y: number;\n W: number;\n H: number;\n}\n\n/** Render-time default dimensions for items whose size is content-driven. */\nexport const WHITEBOARD_DEFAULTS = {\n StickyW: 172,\n StickyH: 96,\n ImageW: 198,\n ImageH: 134,\n TextW: 132,\n TextH: 18,\n ShapeMinH: 56,\n MarkdownW: 280,\n MarkdownMinH: 96,\n HtmlW: 360,\n HtmlH: 240\n} as const;\n\n/**\n * Whether an item kind is BOX-RESIZABLE by the user — i.e. the selection chrome shows the\n * 8 resize handles for it. Everything with a box model resizes: stickies, shapes, text\n * labels, images, markdown panels, HTML widgets and highlight regions. Ink strokes and\n * connectors are path-based and are not box-resizable.\n */\nexport function IsResizableKind(kind: WhiteboardItemKind): boolean {\n return kind === 'sticky' || kind === 'shape' || kind === 'text' || kind === 'image'\n || kind === 'highlight' || kind === 'markdown' || kind === 'html';\n}\n\n/**\n * The patch a COMMITTED resize gesture applies for an item kind, given the gesture's\n * final bounds:\n * - full-box kinds (`shape`, `highlight`, `html`) commit X / Y / W / H;\n * - content-driven-height kinds (`sticky`, `text`, `image`, `markdown`) commit\n * X / Y / W only — their rendered height stays content-driven (markdown's optional\n * `H` max-height cap is set by tools/agents, never by the drag gesture);\n * - non-resizable kinds (`ink`, `connector`) return `null` (nothing to commit).\n */\nexport function BuildResizeCommitPatch(kind: WhiteboardItemKind, bounds: WhiteboardBounds): WhiteboardItemPatch | null {\n if (kind === 'shape' || kind === 'highlight' || kind === 'html') {\n return { X: bounds.X, Y: bounds.Y, W: bounds.W, H: bounds.H };\n }\n if (kind === 'sticky' || kind === 'text' || kind === 'image' || kind === 'markdown') {\n return { X: bounds.X, Y: bounds.Y, W: bounds.W };\n }\n return null;\n}\n\n/** Truncate long item text for summary fragments. */\nfunction clip(text: string, max = 42): string {\n const t = (text || '').replace(/\\s+/g, ' ').trim();\n return t.length > max ? `${t.slice(0, max).trimEnd()}…` : t;\n}\n\ninterface JournalEntry {\n Seq: number;\n Op: WhiteboardChangeOp;\n ItemID: string;\n}\n\n/** Serialized shape of one page inside {@link WhiteboardStateJSON} (version 2+). */\ninterface WhiteboardPageJSON {\n id: string;\n name: string;\n items: WhiteboardItem[];\n /**\n * Who created the page (additive, v2-tolerant: absent in pre-authorship payloads and\n * treated as `'user'` on load). Drives the agent-page chip garnish.\n */\n author?: WhiteboardAuthor;\n}\n\n/**\n * Serialized shape produced by {@link WhiteboardState.ToJSON} — VERSION 2 (paged).\n * Version 1 (the legacy flat shape: `{ version: 1, seq, idCounter, zCounter, items }`)\n * is still accepted by {@link WhiteboardState.FromJSON} / {@link WhiteboardState.LoadFromJSON}\n * and rehydrates as a single page named \"Page 1\".\n */\ninterface WhiteboardStateJSON {\n version: 2;\n seq: number;\n idCounter: number;\n zCounter: number;\n /** Monotonic page-id/auto-name counter (never decremented, so names don't collide). */\n pageCounter: number;\n /** ID of the active page (always one of `pages`). */\n activePageId: string;\n /** The ordered page list (always at least one page). */\n pages: WhiteboardPageJSON[];\n}\n\n/** Internal live record of one page (the active page's map backs `this.items`). */\ninterface PageRecord {\n ID: string;\n Name: string;\n /** Who created the page (drives the agent-page garnish; persisted). */\n Author: WhiteboardAuthor;\n Items: Map<string, WhiteboardItem>;\n}\n\n/**\n * The whiteboard engine: items + ordered render list, single selection, snapshot-based\n * undo/redo (one entry per user gesture or per agent tool call via {@link RunBatch}),\n * change journal + coalesced scene deltas, JSON persistence, and the cancelable\n * BEFORE / AFTER mutation event surface.\n *\n * ## Before / after events\n *\n * Every targeted mutation raises a cancelable BEFORE event and, when it applies, a\n * matching AFTER event:\n *\n * | Mutation | Before (cancelable) | After |\n * |---|---|---|\n * | {@link AddItem} (incl. {@link Highlight}, {@link DuplicateItem}) | {@link ItemAdding$} | {@link ItemAdded$} |\n * | {@link UpdateItem} / {@link MoveItem} / {@link BringToFront} / {@link SendToBack} | {@link ItemUpdating$} | {@link ItemUpdated$} |\n * | {@link UpdateItem} touching content fields (Text / Label / Sub / Markdown / Html / Title) | {@link ContentChanging$} (after ItemUpdating$) | {@link ContentChanged$} |\n * | {@link RemoveItem} | {@link ItemRemoving$} | {@link ItemRemoved$} |\n * | {@link AddPage} | {@link PageAdding$} | {@link PageAdded$} |\n * | {@link SwitchPage} | {@link PageSwitching$} | {@link PageSwitched$} |\n * | {@link RenamePage} | {@link PageRenaming$} | {@link PageRenamed$} |\n * | {@link RemovePage} | {@link PageRemoving$} | {@link PageRemoved$} |\n * | {@link Select} (and implicit clears) | — | {@link SelectionChanged$} |\n * | {@link Clear} | — | {@link BoardCleared$} |\n * | {@link LoadFromJSON} | — | {@link BoardLoaded$} |\n *\n * Handlers run synchronously during the emit; setting `Cancel = true` on the event args\n * aborts the mutation (the caller sees `null` / `false`) with no undo snapshot, journal\n * entry or {@link Changed$} emission. These events layer ALONGSIDE the existing\n * {@link Changed$} / journal / perception machinery — they never replace it. Undo / redo\n * whole-scene replacements are NOT item mutations and only surface through\n * {@link Changed$} as `'replace'` ops.\n */\nexport class WhiteboardState {\n private static readonly UndoMax = 100;\n private static readonly JournalMax = 1000;\n\n /**\n * The ordered page list. A fresh board has one page named \"Page 1\". Every item\n * operation reads/writes the ACTIVE page's map through the `items` accessor below, so\n * the entire pre-pages mutation surface is page-scoped without per-call changes.\n */\n private pages: PageRecord[] = [{ ID: 'page-1', Name: 'Page 1', Author: 'user', Items: new Map<string, WhiteboardItem>() }];\n /** ID of the active page (always present in {@link pages}). */\n private activePageId = 'page-1';\n /** Monotonic page counter — mints page IDs and the \"Page N\" auto-names. */\n private pageCounter = 1;\n\n /** The ACTIVE page's item map (accessor keeps all item mutations page-scoped). */\n private get items(): Map<string, WhiteboardItem> {\n return this.activePage.Items;\n }\n private set items(value: Map<string, WhiteboardItem>) {\n this.activePage.Items = value;\n }\n\n /** The active page record (defensive fallback to the first page — never undefined). */\n private get activePage(): PageRecord {\n return this.pages.find((p) => UUIDsEqual(p.ID, this.activePageId)) ?? this.pages[0];\n }\n\n private idCounter = 0;\n private zCounter = 0;\n private seq = 0;\n\n private undoStack: WhiteboardStateJSON[] = [];\n private redoStack: WhiteboardStateJSON[] = [];\n private batchDepth = 0;\n\n private journal: JournalEntry[] = [];\n /** Per-item snapshot of \"did this item exist at journal-trim time\" is not needed because\n * trimming forces reset semantics for tokens older than the journal window. */\n private journalTrimmedBeforeSeq = 0;\n\n private changed = new Subject<WhiteboardChange>();\n /** Fires after every mutation (including undo/redo `'replace'` events). */\n public readonly Changed$: Observable<WhiteboardChange> = this.changed.asObservable();\n\n private itemAdding = new Subject<WhiteboardItemAddingEventArgs>();\n /**\n * Cancelable BEFORE event of {@link AddItem} (and {@link Highlight} /\n * {@link DuplicateItem}, which add through it). Set `Cancel = true` synchronously to\n * veto the add — {@link AddItem} then returns `null` and nothing changes.\n */\n public readonly ItemAdding$: Observable<WhiteboardItemAddingEventArgs> = this.itemAdding.asObservable();\n\n private itemAdded = new Subject<WhiteboardItemAddedEventArgs>();\n /** AFTER event: an item was added (fires once per applied {@link AddItem}). */\n public readonly ItemAdded$: Observable<WhiteboardItemAddedEventArgs> = this.itemAdded.asObservable();\n\n private itemUpdating = new Subject<WhiteboardItemUpdatingEventArgs>();\n /**\n * Cancelable BEFORE event of {@link UpdateItem} (`Operation: 'update'`),\n * {@link MoveItem} (`'move'`) and {@link BringToFront} / {@link SendToBack}\n * (`'reorder'`). Set `Cancel = true` synchronously to veto — the mutator returns `false`.\n */\n public readonly ItemUpdating$: Observable<WhiteboardItemUpdatingEventArgs> = this.itemUpdating.asObservable();\n\n private itemUpdated = new Subject<WhiteboardItemUpdatedEventArgs>();\n /** AFTER event: an item changed (patch applied / moved / z-reordered). */\n public readonly ItemUpdated$: Observable<WhiteboardItemUpdatedEventArgs> = this.itemUpdated.asObservable();\n\n private itemRemoving = new Subject<WhiteboardItemRemovingEventArgs>();\n /**\n * Cancelable BEFORE event of {@link RemoveItem}. Set `Cancel = true` synchronously to\n * keep the item — {@link RemoveItem} then returns `false` and nothing changes.\n */\n public readonly ItemRemoving$: Observable<WhiteboardItemRemovingEventArgs> = this.itemRemoving.asObservable();\n\n private itemRemoved = new Subject<WhiteboardItemRemovedEventArgs>();\n /** AFTER event: an item was removed from the board. */\n public readonly ItemRemoved$: Observable<WhiteboardItemRemovedEventArgs> = this.itemRemoved.asObservable();\n\n private contentChanging = new Subject<WhiteboardContentChangingEventArgs>();\n /**\n * Cancelable BEFORE event raised — in addition to {@link ItemUpdating$} — when an\n * {@link UpdateItem} patch touches CONTENT fields (Text / Label / Sub / Markdown /\n * Html / Title). The dedicated hook for content governance: set `Cancel = true`\n * synchronously to veto the whole update.\n */\n public readonly ContentChanging$: Observable<WhiteboardContentChangingEventArgs> = this.contentChanging.asObservable();\n\n private contentChanged = new Subject<WhiteboardContentChangedEventArgs>();\n /** AFTER event: an item's content fields changed (markdown / html / text edits). */\n public readonly ContentChanged$: Observable<WhiteboardContentChangedEventArgs> = this.contentChanged.asObservable();\n\n private selectionChanged = new Subject<WhiteboardSelectionChangedEventArgs>();\n /**\n * AFTER event: the single selection changed — via {@link Select} or implicitly (the\n * selected item was removed / dropped by a restore). Selection is transient UI state,\n * so this is a notification only (never cancelable, never journaled).\n */\n public readonly SelectionChanged$: Observable<WhiteboardSelectionChangedEventArgs> = this.selectionChanged.asObservable();\n\n private boardCleared = new Subject<WhiteboardBoardClearedEventArgs>();\n /** AFTER event: {@link Clear} removed everything from the board (one undo step). */\n public readonly BoardCleared$: Observable<WhiteboardBoardClearedEventArgs> = this.boardCleared.asObservable();\n\n private boardLoaded = new Subject<WhiteboardBoardLoadedEventArgs>();\n /** AFTER event: {@link LoadFromJSON} rehydrated a persisted board into this instance. */\n public readonly BoardLoaded$: Observable<WhiteboardBoardLoadedEventArgs> = this.boardLoaded.asObservable();\n\n private pageAdding = new Subject<WhiteboardPageAddingEventArgs>();\n /**\n * Cancelable BEFORE event of {@link AddPage}. Set `Cancel = true` synchronously to\n * veto — {@link AddPage} then returns `null` and nothing changes.\n */\n public readonly PageAdding$: Observable<WhiteboardPageAddingEventArgs> = this.pageAdding.asObservable();\n\n private pageAdded = new Subject<WhiteboardPageAddedEventArgs>();\n /** AFTER event: a page was added (and became the active page). */\n public readonly PageAdded$: Observable<WhiteboardPageAddedEventArgs> = this.pageAdded.asObservable();\n\n private pageSwitching = new Subject<WhiteboardPageSwitchingEventArgs>();\n /**\n * Cancelable BEFORE event of {@link SwitchPage}. Set `Cancel = true` synchronously to\n * stay on the current page — {@link SwitchPage} then returns `false`.\n */\n public readonly PageSwitching$: Observable<WhiteboardPageSwitchingEventArgs> = this.pageSwitching.asObservable();\n\n private pageSwitched = new Subject<WhiteboardPageSwitchedEventArgs>();\n /** AFTER event: the active page changed via {@link SwitchPage}. */\n public readonly PageSwitched$: Observable<WhiteboardPageSwitchedEventArgs> = this.pageSwitched.asObservable();\n\n private pageRenaming = new Subject<WhiteboardPageRenamingEventArgs>();\n /**\n * Cancelable BEFORE event of {@link RenamePage}. Handlers may rewrite `NewName`; set\n * `Cancel = true` synchronously to veto — {@link RenamePage} then returns `false`.\n */\n public readonly PageRenaming$: Observable<WhiteboardPageRenamingEventArgs> = this.pageRenaming.asObservable();\n\n private pageRenamed = new Subject<WhiteboardPageRenamedEventArgs>();\n /** AFTER event: a page was renamed. */\n public readonly PageRenamed$: Observable<WhiteboardPageRenamedEventArgs> = this.pageRenamed.asObservable();\n\n private pageRemoving = new Subject<WhiteboardPageRemovingEventArgs>();\n /**\n * Cancelable BEFORE event of {@link RemovePage} (never raised for the guarded\n * last-page case). Set `Cancel = true` synchronously to keep the page.\n */\n public readonly PageRemoving$: Observable<WhiteboardPageRemovingEventArgs> = this.pageRemoving.asObservable();\n\n private pageRemoved = new Subject<WhiteboardPageRemovedEventArgs>();\n /** AFTER event: a page (and all of its items) was removed from the board. */\n public readonly PageRemoved$: Observable<WhiteboardPageRemovedEventArgs> = this.pageRemoved.asObservable();\n\n /**\n * The MULTI-selection, in selection order (last entry is the primary selection).\n * Selection is volatile UI state — never journaled, never undoable, never persisted,\n * and cleared on page switches and whole-scene restores.\n */\n private selectedIds: string[] = [];\n\n /**\n * The PRIMARY selected item's ID (the most recently selected member of the\n * multi-selection), or null when nothing is selected. Selection is UI state — not\n * persisted. For the full multi-selection see {@link SelectedIDs}.\n */\n public get SelectedID(): string | null {\n return this.selectedIds.length > 0 ? this.selectedIds[this.selectedIds.length - 1] : null;\n }\n\n /** All selected item IDs in selection order (last = primary). Returns a copy. */\n public get SelectedIDs(): string[] {\n return [...this.selectedIds];\n }\n\n // ────────────────────────────────────────────── reads\n\n /** All items on the ACTIVE page in render order (ascending Z). */\n public get Items(): WhiteboardItem[] {\n return Array.from(this.items.values()).sort((a, b) => a.Z - b.Z);\n }\n\n /** The ordered page list (read-only snapshots — see {@link WhiteboardPageInfo}). */\n public get Pages(): WhiteboardPageInfo[] {\n return this.pages.map((p) => this.pageInfo(p));\n }\n\n /** ID of the active page (every item operation targets this page). */\n public get ActivePageID(): string {\n return this.activePage.ID;\n }\n\n /** Display name of the active page. */\n public get ActivePageName(): string {\n return this.activePage.Name;\n }\n\n /** Total item count summed across ALL pages (the active-page count is {@link ElementCount}). */\n public get TotalItemCount(): number {\n return this.pages.reduce((n, p) => n + p.Items.size, 0);\n }\n\n /**\n * Tolerant page lookup: by exact ID first, then by case-insensitive, trimmed name\n * (first match wins on duplicate names). Returns `undefined` when nothing matches.\n */\n public FindPage(idOrName: string): WhiteboardPageInfo | undefined {\n const page = this.resolvePage(idOrName);\n return page ? this.pageInfo(page) : undefined;\n }\n\n /** Current sequence number — use as the `sinceToken` for the next {@link BuildSceneDelta}. */\n public get CurrentSeq(): number {\n return this.seq;\n }\n\n /** Look up one ACTIVE-page item by ID (items on other pages are not visible here). */\n public GetItem(id: string): WhiteboardItem | undefined {\n return this.items.get(id);\n }\n\n /** ACTIVE-page \"elements\" as the status footer reports them (transient highlights excluded). */\n public get ElementCount(): number {\n return this.Items.filter((i) => i.Kind !== 'highlight').length;\n }\n\n /** Active-page elements by author (highlights excluded, same basis as {@link ElementCount}). */\n public CountByAuthor(author: WhiteboardAuthor): number {\n return this.Items.filter((i) => i.Kind !== 'highlight' && i.Author === author).length;\n }\n\n public get CanUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n public get CanRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n // ────────────────────────────────────────────── geometry\n\n /** Axis-aligned bounds for any item (estimates for content-sized kinds). */\n public ItemBounds(item: WhiteboardItem): WhiteboardBounds {\n switch (item.Kind) {\n case 'sticky':\n return { X: item.X, Y: item.Y, W: item.W ?? WHITEBOARD_DEFAULTS.StickyW, H: WHITEBOARD_DEFAULTS.StickyH };\n case 'shape':\n return { X: item.X, Y: item.Y, W: item.W, H: item.H };\n case 'text': {\n // estimate scales with the chosen font size (the CSS default renders ~12px);\n // an explicit wrap width (item.W) wins over the single-line estimate\n const scale = item.FontSize ? item.FontSize / 12 : 1;\n return {\n X: item.X,\n Y: item.Y,\n W: item.W ?? Math.round(WHITEBOARD_DEFAULTS.TextW * scale),\n H: Math.round(WHITEBOARD_DEFAULTS.TextH * scale)\n };\n }\n case 'image':\n return { X: item.X, Y: item.Y, W: item.W ?? WHITEBOARD_DEFAULTS.ImageW, H: WHITEBOARD_DEFAULTS.ImageH };\n case 'highlight':\n return { X: item.X, Y: item.Y, W: item.W, H: item.H };\n case 'markdown':\n // content-driven height: an explicit max (H) wins, otherwise estimate from line count\n return { X: item.X, Y: item.Y, W: item.W, H: item.H ?? WhiteboardState.markdownHeightEstimate(item.Markdown) };\n case 'html':\n return { X: item.X, Y: item.Y, W: item.W, H: item.H };\n case 'ink': {\n return WhiteboardState.pointsBounds(item.Points, item.StrokeWidth);\n }\n case 'connector': {\n const from = this.ResolveEndpoint(item, 'from');\n const to = this.ResolveEndpoint(item, 'to');\n return WhiteboardState.pointsBounds([from, to], 2);\n }\n }\n }\n\n /** Rough rendered height of a markdown panel (line count · line height + card padding). */\n private static markdownHeightEstimate(markdown: string): number {\n const lines = (markdown || '').split('\\n').length;\n return Math.max(WHITEBOARD_DEFAULTS.MarkdownMinH, Math.min(520, 44 + lines * 19));\n }\n\n private static pointsBounds(points: WhiteboardPoint[], pad: number): WhiteboardBounds {\n if (points.length === 0) {\n return { X: 0, Y: 0, W: 0, H: 0 };\n }\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const p of points) {\n minX = Math.min(minX, p.X);\n minY = Math.min(minY, p.Y);\n maxX = Math.max(maxX, p.X);\n maxY = Math.max(maxY, p.Y);\n }\n return { X: minX - pad, Y: minY - pad, W: maxX - minX + pad * 2, H: maxY - minY + pad * 2 };\n }\n\n /** Bounding box of all items (null when the board is empty). Powers fit-to-content + minimap. */\n public ContentBounds(): WhiteboardBounds | null {\n const all = this.Items;\n if (all.length === 0) {\n return null;\n }\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const item of all) {\n const b = this.ItemBounds(item);\n minX = Math.min(minX, b.X);\n minY = Math.min(minY, b.Y);\n maxX = Math.max(maxX, b.X + b.W);\n maxY = Math.max(maxY, b.Y + b.H);\n }\n return { X: minX, Y: minY, W: maxX - minX, H: maxY - minY };\n }\n\n /**\n * Resolve one connector endpoint: anchored to the referenced item's bounds-center when the\n * item still exists, otherwise the absolute fallback point (floating endpoint).\n */\n public ResolveEndpoint(conn: WhiteboardConnectorItem, end: 'from' | 'to'): WhiteboardPoint {\n const refId = end === 'from' ? conn.FromItemID : conn.ToItemID;\n const fallback = end === 'from' ? conn.FromPoint : conn.ToPoint;\n if (refId) {\n const target = this.items.get(refId);\n if (target) {\n const b = this.ItemBounds(target);\n return { X: b.X + b.W / 2, Y: b.Y + b.H / 2 };\n }\n }\n return fallback ?? { X: 0, Y: 0 };\n }\n\n // ────────────────────────────────────────────── selection\n\n /**\n * Set (or clear) the selection to a SINGLE item. Unknown IDs clear the selection.\n * Fires {@link SelectionChanged$} when the effective selection actually changes.\n */\n public Select(id: string | null): void {\n this.applySelection(id != null && this.items.has(id) ? [id] : []);\n }\n\n /**\n * Toggle one item's membership in the multi-selection WITHOUT clearing the rest —\n * the shift-click semantics. A newly added item becomes the primary selection\n * ({@link SelectedID}); unknown IDs are a no-op.\n */\n public ToggleSelect(id: string): void {\n if (!this.items.has(id)) {\n return;\n }\n this.applySelection(this.selectedIds.includes(id)\n ? this.selectedIds.filter((s) => s !== id)\n : [...this.selectedIds, id]);\n }\n\n /**\n * Replace the selection with a set of items (the marquee result). Unknown IDs are\n * dropped and duplicates collapse to their first occurrence; order is preserved\n * (the last surviving entry becomes the primary selection). An empty / fully-unknown\n * list clears the selection.\n */\n public SelectMany(ids: string[]): void {\n const seen = new Set<string>();\n const next: string[] = [];\n for (const id of ids) {\n if (id != null && this.items.has(id) && !seen.has(id)) {\n seen.add(id);\n next.push(id);\n }\n }\n this.applySelection(next);\n }\n\n /** Whether an item is part of the current (single or multi) selection. */\n public IsItemSelected(id: string): boolean {\n return this.selectedIds.includes(id);\n }\n\n /**\n * All ACTIVE-page items whose axis-aligned bounds intersect the given rectangle —\n * the marquee (rubber-band) hit test, in render order. Transient highlight regions\n * are excluded: they are \"pointing\" chrome dismissed by click, never selected.\n * Edge-touching items (zero overlap area) do NOT count as intersecting.\n */\n public ItemsIntersecting(rect: WhiteboardBounds): WhiteboardItem[] {\n return this.Items.filter((item) => {\n if (item.Kind === 'highlight') {\n return false;\n }\n const b = this.ItemBounds(item);\n return b.X < rect.X + rect.W && b.X + b.W > rect.X\n && b.Y < rect.Y + rect.H && b.Y + b.H > rect.Y;\n });\n }\n\n /** Apply a SINGLE-or-clear selection change (legacy internal path). */\n protected changeSelection(next: string | null): void {\n this.applySelection(next != null ? [next] : []);\n }\n\n /** Swap the multi-selection and fire {@link SelectionChanged$} when it differs. */\n protected applySelection(next: string[]): void {\n const current = this.selectedIds;\n if (next.length === current.length && next.every((id, i) => id === current[i])) {\n return;\n }\n const previous = this.SelectedID;\n this.selectedIds = next;\n this.selectionChanged.next({ SelectedID: this.SelectedID, PreviousID: previous, SelectedIDs: [...next] });\n }\n\n // ────────────────────────────────────────────── mutations\n\n /**\n * Add an item; the engine stamps ID, Z and Author and emits one change.\n *\n * Raises the cancelable {@link ItemAdding$} BEFORE event first — when a handler\n * cancels, nothing changes and `null` is returned. On success the stamped item is\n * returned and {@link ItemAdded$} fires after the journal/{@link Changed$} emission.\n */\n public AddItem(input: WhiteboardItemInput, author: WhiteboardAuthor): WhiteboardItem | null {\n const adding: WhiteboardItemAddingEventArgs = { Input: input, Author: author, Cancel: false };\n this.itemAdding.next(adding);\n if (adding.Cancel) {\n return null;\n }\n this.beforeMutate();\n const item = { ...adding.Input, ID: this.nextId(adding.Input.Kind), Z: ++this.zCounter, Author: author } as WhiteboardItem;\n this.items.set(item.ID, item);\n this.record('add', item.ID, author, `added ${WhiteboardState.describe(item)}`);\n this.itemAdded.next({ Item: item, Author: author });\n return item;\n }\n\n /**\n * Patch an item's mutable fields. Returns false when the ID is unknown — or when a\n * handler of the cancelable {@link ItemUpdating$} BEFORE event (or, for patches that\n * touch content fields, the cancelable {@link ContentChanging$} event) vetoed the\n * change. On success {@link ItemUpdated$} — and {@link ContentChanged$} for content\n * patches — fires after the journal/{@link Changed$} emission.\n */\n public UpdateItem(id: string, patch: WhiteboardItemPatch, author: WhiteboardAuthor): boolean {\n const item = this.items.get(id);\n if (!item) {\n return false;\n }\n const updating: WhiteboardItemUpdatingEventArgs = { Item: item, Operation: 'update', Patch: patch, Author: author, Cancel: false };\n this.itemUpdating.next(updating);\n if (updating.Cancel) {\n return false;\n }\n const effective = updating.Patch ?? patch;\n const isContent = WhiteboardState.isContentPatch(effective);\n if (isContent) {\n const changing: WhiteboardContentChangingEventArgs = { Item: item, Patch: effective, Author: author, Cancel: false };\n this.contentChanging.next(changing);\n if (changing.Cancel) {\n return false;\n }\n }\n this.beforeMutate();\n const target = item as WhiteboardItemBase & WhiteboardItemPatch;\n for (const [key, value] of Object.entries(effective)) {\n if (value !== undefined) {\n (target as Record<string, typeof value>)[key] = value;\n }\n }\n this.record('update', id, author, `updated ${WhiteboardState.describe(item)}`);\n this.itemUpdated.next({ Item: item, Operation: 'update', Author: author });\n if (isContent) {\n this.contentChanged.next({ Item: item, Patch: effective, Author: author });\n }\n return true;\n }\n\n /** Whether a patch touches CONTENT fields (drives the ContentChanging/Changed pair). */\n protected static isContentPatch(patch: WhiteboardItemPatch): boolean {\n return patch.Text !== undefined || patch.Label !== undefined || patch.Sub !== undefined\n || patch.Markdown !== undefined || patch.Html !== undefined || patch.Title !== undefined;\n }\n\n /**\n * Move an item to an absolute board position. Positioned kinds move their origin; ink\n * strokes translate every point; connectors translate their floating endpoints.\n *\n * Raises the cancelable {@link ItemUpdating$} BEFORE event (`Operation: 'move'`,\n * `Position` = the requested top-left) — returns false when vetoed or the ID is\n * unknown; fires {@link ItemUpdated$} after an applied move.\n */\n public MoveItem(id: string, x: number, y: number, author: WhiteboardAuthor): boolean {\n const item = this.items.get(id);\n if (!item) {\n return false;\n }\n const moving: WhiteboardItemUpdatingEventArgs = { Item: item, Operation: 'move', Position: { X: x, Y: y }, Author: author, Cancel: false };\n this.itemUpdating.next(moving);\n if (moving.Cancel) {\n return false;\n }\n this.beforeMutate();\n const bounds = this.ItemBounds(item);\n const dx = x - bounds.X;\n const dy = y - bounds.Y;\n if (item.Kind === 'ink') {\n item.Points = item.Points.map((p) => ({ X: p.X + dx, Y: p.Y + dy }));\n }\n else if (item.Kind === 'connector') {\n if (item.FromPoint) {\n item.FromPoint = { X: item.FromPoint.X + dx, Y: item.FromPoint.Y + dy };\n }\n if (item.ToPoint) {\n item.ToPoint = { X: item.ToPoint.X + dx, Y: item.ToPoint.Y + dy };\n }\n }\n else {\n item.X = x;\n item.Y = y;\n }\n this.record('move', id, author, `moved ${WhiteboardState.describe(item)}`);\n this.itemUpdated.next({ Item: item, Operation: 'move', Author: author });\n return true;\n }\n\n /**\n * Remove an item. Connectors that referenced it survive: their endpoint freezes to the\n * removed item's last center (the floating-endpoint fallback).\n *\n * Raises the cancelable {@link ItemRemoving$} BEFORE event — returns false when vetoed\n * or the ID is unknown; fires {@link ItemRemoved$} after an applied removal.\n */\n public RemoveItem(id: string, author: WhiteboardAuthor): boolean {\n const item = this.items.get(id);\n if (!item) {\n return false;\n }\n const removing: WhiteboardItemRemovingEventArgs = { Item: item, Author: author, Cancel: false };\n this.itemRemoving.next(removing);\n if (removing.Cancel) {\n return false;\n }\n this.beforeMutate();\n // Freeze any connector endpoints anchored to the item being removed.\n const center = (() => {\n const b = this.ItemBounds(item);\n return { X: b.X + b.W / 2, Y: b.Y + b.H / 2 };\n })();\n for (const other of this.items.values()) {\n if (other.Kind === 'connector') {\n if (other.FromItemID === id) {\n other.FromItemID = null;\n other.FromPoint = { ...center };\n }\n if (other.ToItemID === id) {\n other.ToItemID = null;\n other.ToPoint = { ...center };\n }\n }\n }\n this.items.delete(id);\n if (this.selectedIds.includes(id)) {\n this.applySelection(this.selectedIds.filter((s) => s !== id));\n }\n this.record('remove', id, author, `removed ${WhiteboardState.describe(item)}`);\n this.itemRemoved.next({ Item: item, Author: author });\n return true;\n }\n\n /**\n * Duplicate an item: a DEEP clone (ink points included) with a fresh engine-stamped\n * identity, offset +16/+16 from the source so the copy is visibly distinct. Connectors\n * (which reference other items) and transient highlights cannot be duplicated — returns\n * `null` without mutating. The clone lands through {@link AddItem}, so it journals as a\n * normal `'add'`, is one undo step, and raises the {@link ItemAdding$} /\n * {@link ItemAdded$} pair (a canceled add also returns `null`).\n */\n public DuplicateItem(id: string, author: WhiteboardAuthor): WhiteboardItem | null {\n const source = this.items.get(id);\n if (!source || source.Kind === 'connector' || source.Kind === 'highlight') {\n return null;\n }\n const { ID: _id, Z: _z, Author: _author, ...rest } = JSON.parse(JSON.stringify(source)) as WhiteboardItem;\n const input = rest as WhiteboardItemInput;\n if (input.Kind === 'ink') {\n input.Points = input.Points.map((p) => ({ X: p.X + 16, Y: p.Y + 16 }));\n }\n else if (input.Kind !== 'connector') {\n input.X += 16;\n input.Y += 16;\n }\n return this.AddItem(input, author);\n }\n\n /**\n * Raise an item above everything else. Follows the engine's existing Z handling:\n * `++zCounter` is by construction greater than every assigned Z (max + 1), exactly how\n * {@link AddItem} stamps new items. Journals as an `'update'`.\n *\n * Raises the cancelable {@link ItemUpdating$} BEFORE event (`Operation: 'reorder'`) —\n * returns false when vetoed or the ID is unknown; fires {@link ItemUpdated$} after.\n */\n public BringToFront(id: string, author: WhiteboardAuthor): boolean {\n const item = this.items.get(id);\n if (!item) {\n return false;\n }\n if (!this.raiseReorder(item, author)) {\n return false;\n }\n this.beforeMutate();\n item.Z = ++this.zCounter;\n this.record('update', id, author, `brought ${WhiteboardState.describe(item)} to the front`);\n this.itemUpdated.next({ Item: item, Operation: 'reorder', Author: author });\n return true;\n }\n\n /**\n * Drop an item below everything else (current min Z − 1). Journals as an `'update'`.\n *\n * Raises the cancelable {@link ItemUpdating$} BEFORE event (`Operation: 'reorder'`) —\n * returns false when vetoed or the ID is unknown; fires {@link ItemUpdated$} after.\n */\n public SendToBack(id: string, author: WhiteboardAuthor): boolean {\n const item = this.items.get(id);\n if (!item) {\n return false;\n }\n if (!this.raiseReorder(item, author)) {\n return false;\n }\n this.beforeMutate();\n let minZ = item.Z;\n for (const other of this.items.values()) {\n minZ = Math.min(minZ, other.Z);\n }\n item.Z = minZ - 1;\n this.record('update', id, author, `sent ${WhiteboardState.describe(item)} to the back`);\n this.itemUpdated.next({ Item: item, Operation: 'reorder', Author: author });\n return true;\n }\n\n /** Raise the cancelable `'reorder'` BEFORE event; returns false when a handler vetoed. */\n protected raiseReorder(item: WhiteboardItem, author: WhiteboardAuthor): boolean {\n const reordering: WhiteboardItemUpdatingEventArgs = { Item: item, Operation: 'reorder', Author: author, Cancel: false };\n this.itemUpdating.next(reordering);\n return !reordering.Cancel;\n }\n\n /**\n * Convenience: add a pulsing highlight region (agent \"pointing without touching\").\n * Adds through {@link AddItem}, so the {@link ItemAdding$} / {@link ItemAdded$} pair\n * fires — returns `null` when a handler canceled the add.\n */\n public Highlight(x: number, y: number, w: number, h: number, label: string | undefined, author: WhiteboardAuthor): WhiteboardHighlightItem | null {\n return this.AddItem({ Kind: 'highlight', X: x, Y: y, W: w, H: h, Label: label }, author) as WhiteboardHighlightItem | null;\n }\n\n /**\n * Remove EVERYTHING from the ACTIVE page as ONE undoable operation (other pages are\n * untouched). Journals a single `'replace'` op (perception consumers re-read the\n * now-empty scene) and fires {@link BoardCleared$}. Clears the selection (firing\n * {@link SelectionChanged$} when one existed). Returns false when the active page was\n * already empty.\n */\n public Clear(author: WhiteboardAuthor = 'user'): boolean {\n if (this.items.size === 0) {\n return false;\n }\n const count = this.items.size;\n this.beforeMutate();\n this.items = new Map<string, WhiteboardItem>();\n this.changeSelection(null);\n this.record('replace', '', author, 'cleared the board');\n this.boardCleared.next({ Author: author, ItemCount: count });\n return true;\n }\n\n /**\n * Move EVERY selected item by the same delta as ONE undo step (the multi-select group\n * drag). Internally one {@link RunBatch} of per-item {@link MoveItem} calls, so each\n * member still raises its own cancelable `'move'` BEFORE event (a veto skips just that\n * member) and journals normally — but a single Undo reverts the whole group move.\n * Returns how many items actually moved (0 when nothing is selected or the delta is 0).\n */\n public MoveSelectedBy(dx: number, dy: number, author: WhiteboardAuthor): number {\n const ids = this.selectedIds.filter((id) => this.items.has(id));\n if (ids.length === 0 || (dx === 0 && dy === 0)) {\n return 0;\n }\n return this.RunBatch(() => {\n // capture every member's bounds BEFORE any member moves, so anchored-connector\n // bounds (which follow their endpoints) don't skew later members' targets\n const targets = ids\n .map((id) => {\n const item = this.items.get(id);\n return item ? { id, bounds: this.ItemBounds(item) } : null;\n })\n .filter((t): t is { id: string; bounds: WhiteboardBounds } => t !== null);\n let moved = 0;\n for (const t of targets) {\n if (this.MoveItem(t.id, t.bounds.X + dx, t.bounds.Y + dy, author)) {\n moved++;\n }\n }\n return moved;\n });\n }\n\n /**\n * Remove EVERY selected item as ONE undo step (the multi-select Delete key). One\n * {@link RunBatch} of per-item {@link RemoveItem} calls — each member still raises its\n * cancelable {@link ItemRemoving$} BEFORE event (a veto keeps just that member), and a\n * single Undo restores the whole group. The selection empties as items are removed.\n * Returns how many items were actually removed.\n */\n public RemoveSelected(author: WhiteboardAuthor): number {\n const ids = this.selectedIds.filter((id) => this.items.has(id));\n if (ids.length === 0) {\n return 0;\n }\n return this.RunBatch(() => {\n let removed = 0;\n for (const id of ids) {\n if (this.RemoveItem(id, author)) {\n removed++;\n }\n }\n return removed;\n });\n }\n\n // ────────────────────────────────────────────── pages\n\n /** Project a live page record to its public read-only descriptor. */\n protected pageInfo(page: PageRecord): WhiteboardPageInfo {\n return { ID: page.ID, Name: page.Name, ItemCount: page.Items.size, Active: UUIDsEqual(page.ID, this.activePageId), Author: page.Author };\n }\n\n /** Resolve a page by exact ID first, then case-insensitive trimmed name. */\n private resolvePage(idOrName: string): PageRecord | undefined {\n const key = (idOrName ?? '').trim();\n if (key.length === 0) {\n return undefined;\n }\n return this.pages.find((p) => UUIDsEqual(p.ID, key))\n ?? this.pages.find((p) => p.Name.trim().toLowerCase() === key.toLowerCase());\n }\n\n /**\n * Add a new page and SWITCH to it. `name` is trimmed; when omitted (or blank) the page\n * auto-names itself \"Page N\" from the monotonic page counter, so auto-names never\n * repeat even after removals.\n *\n * Raises the cancelable {@link PageAdding$} BEFORE event (handlers may rewrite the\n * name) — returns `null` when vetoed; fires {@link PageAdded$} after. One undoable\n * step; journals a `'replace'` op (the agent's visible scene swaps to the new, empty\n * page), so perception consumers re-read the scene.\n */\n public AddPage(name?: string, author: WhiteboardAuthor = 'user'): WhiteboardPageInfo | null {\n const autoName = `Page ${this.pageCounter + 1}`;\n const requested = (name ?? '').trim();\n const adding: WhiteboardPageAddingEventArgs = { Name: requested.length > 0 ? requested : autoName, Author: author, Cancel: false };\n this.pageAdding.next(adding);\n if (adding.Cancel) {\n return null;\n }\n this.beforeMutate();\n this.pageCounter++;\n const page: PageRecord = {\n ID: `page-${this.pageCounter}`,\n Name: (adding.Name ?? '').trim() || autoName,\n Author: author,\n Items: new Map<string, WhiteboardItem>()\n };\n this.pages.push(page);\n this.activePageId = page.ID;\n this.changeSelection(null);\n this.record('replace', '', author, `added page \"${page.Name}\"`);\n const info = this.pageInfo(page);\n this.pageAdded.next({ Page: info, Author: author });\n return info;\n }\n\n /**\n * Make another page the active page. Tolerant lookup: exact ID first, then\n * case-insensitive name (see {@link FindPage}). Switching to the already-active page\n * is a successful no-op (no events, no journal entry).\n *\n * Raises the cancelable {@link PageSwitching$} BEFORE event — returns `false` when\n * vetoed or the page is unknown; fires {@link PageSwitched$} after. Journals a\n * `'replace'` op (the visible scene swaps wholesale) but deliberately pushes NO undo\n * snapshot — switching is navigation, not a content mutation.\n */\n public SwitchPage(idOrName: string, author: WhiteboardAuthor = 'user'): boolean {\n const target = this.resolvePage(idOrName);\n if (!target) {\n return false;\n }\n if (UUIDsEqual(target.ID, this.activePageId)) {\n return true; // already there — successful no-op\n }\n const from = this.pageInfo(this.activePage);\n const switching: WhiteboardPageSwitchingEventArgs = { FromPage: from, ToPage: this.pageInfo(target), Author: author, Cancel: false };\n this.pageSwitching.next(switching);\n if (switching.Cancel) {\n return false;\n }\n this.activePageId = target.ID;\n this.changeSelection(null);\n this.record('replace', '', author, `switched to page \"${target.Name}\"`);\n this.pageSwitched.next({ FromPage: from, ToPage: this.pageInfo(target), Author: author });\n return true;\n }\n\n /**\n * Rename a page (tolerant lookup, same as {@link SwitchPage}). The new name is\n * trimmed; an empty result returns `false`. Renaming to the current name is a\n * successful no-op (no events, no journal entry).\n *\n * Raises the cancelable {@link PageRenaming$} BEFORE event (handlers may rewrite\n * `NewName`) — returns `false` when vetoed; fires {@link PageRenamed$} after. One\n * undoable step; journals a `'replace'` op so the agent's page list stays current.\n */\n public RenamePage(idOrName: string, newName: string, author: WhiteboardAuthor = 'user'): boolean {\n const target = this.resolvePage(idOrName);\n const requested = (newName ?? '').trim();\n if (!target || requested.length === 0) {\n return false;\n }\n if (target.Name === requested) {\n return true; // nothing to do\n }\n const renaming: WhiteboardPageRenamingEventArgs = { Page: this.pageInfo(target), NewName: requested, Author: author, Cancel: false };\n this.pageRenaming.next(renaming);\n if (renaming.Cancel) {\n return false;\n }\n const effective = (renaming.NewName ?? '').trim();\n if (effective.length === 0) {\n return false; // a handler emptied the name — treat as an abort\n }\n this.beforeMutate();\n const oldName = target.Name;\n target.Name = effective;\n this.record('replace', '', author, `renamed page \"${oldName}\" to \"${target.Name}\"`);\n this.pageRenamed.next({ Page: this.pageInfo(target), OldName: oldName, Author: author });\n return true;\n }\n\n /**\n * Remove a page AND all of its items (tolerant lookup, same as {@link SwitchPage}).\n * The LAST remaining page can never be removed (`false`, no events). Removing the\n * ACTIVE page activates a neighbor — the next page when one exists, otherwise the\n * previous one.\n *\n * Raises the cancelable {@link PageRemoving$} BEFORE event — returns `false` when\n * vetoed or the page is unknown; fires {@link PageRemoved$} after (with the activated\n * neighbor when the active page was removed). One undoable step; journals a\n * `'replace'` op.\n */\n public RemovePage(idOrName: string, author: WhiteboardAuthor = 'user'): boolean {\n const target = this.resolvePage(idOrName);\n if (!target || this.pages.length <= 1) {\n return false; // unknown, or the guarded last page\n }\n const removingInfo = this.pageInfo(target);\n const removing: WhiteboardPageRemovingEventArgs = { Page: removingInfo, Author: author, Cancel: false };\n this.pageRemoving.next(removing);\n if (removing.Cancel) {\n return false;\n }\n this.beforeMutate();\n const index = this.pages.indexOf(target);\n this.pages.splice(index, 1);\n let activated: WhiteboardPageInfo | null = null;\n if (UUIDsEqual(target.ID, this.activePageId)) {\n // activate the neighbor: the page that slid into the removed slot, else the new last\n const neighbor = this.pages[Math.min(index, this.pages.length - 1)];\n this.activePageId = neighbor.ID;\n activated = this.pageInfo(neighbor);\n this.changeSelection(null);\n }\n this.record('replace', '', author, `removed page \"${target.Name}\"`);\n this.pageRemoved.next({ Page: removingInfo, ActivatedPage: activated, Author: author });\n return true;\n }\n\n /**\n * Run several mutations as ONE undo step (one snapshot). Used per agent tool call and for\n * compound user gestures, so the toast's \"Undo\" reverts the whole tool effect at once.\n */\n public RunBatch<T>(fn: () => T): T {\n if (this.batchDepth === 0) {\n this.pushUndo();\n }\n this.batchDepth++;\n try {\n return fn();\n }\n finally {\n this.batchDepth--;\n }\n }\n\n // ────────────────────────────────────────────── undo / redo\n\n /** Restore the previous snapshot. Emits a `'replace'` change. */\n public Undo(): boolean {\n const snap = this.undoStack.pop();\n if (!snap) {\n return false;\n }\n this.redoStack.push(this.snapshot());\n this.restore(snap);\n this.record('replace', '', 'user', 'undid the last change');\n return true;\n }\n\n /** Re-apply the most recently undone snapshot. Emits a `'replace'` change. */\n public Redo(): boolean {\n const snap = this.redoStack.pop();\n if (!snap) {\n return false;\n }\n this.undoStack.push(this.snapshot());\n this.restore(snap);\n this.record('replace', '', 'user', 'redid the last change');\n return true;\n }\n\n // ────────────────────────────────────────────── perception (scene deltas)\n\n /**\n * Build the coalesced scene delta of everything that changed AFTER `sinceToken`\n * (a previously observed {@link CurrentSeq}; defaults to 0 = everything).\n *\n * Coalescing: per item, the NET effect wins — N moves → one `moved` entry at the current\n * position; add+move → one `added` entry (current state); add+remove → nothing;\n * update+move → one `updated` entry. When the window contains a `'replace'` (undo/redo/load)\n * or the journal no longer reaches the token, the delta carries `reset: true` plus the full\n * compact `items` array — replace-current-state semantics, never an append-only log.\n */\n public BuildSceneDelta(sinceToken = 0): WhiteboardSceneDelta {\n const delta: WhiteboardSceneDelta = {\n op: 'scene-delta',\n seq: this.seq,\n added: [],\n moved: [],\n updated: [],\n removed: [],\n pages: this.scenePages(),\n summary: ''\n };\n\n const tokenTooOld = sinceToken < this.journalTrimmedBeforeSeq;\n const inRange = this.journal.filter((e) => e.Seq > sinceToken);\n const hasReplace = inRange.some((e) => e.Op === 'replace');\n\n if (tokenTooOld || hasReplace) {\n delta.reset = true;\n delta.items = this.Items.map((i) => this.compact(i));\n delta.summary = this.composeSummaryText({ reset: true });\n return delta;\n }\n\n // Net-effect per item, preserving first-op semantics.\n const firstOp = new Map<string, WhiteboardChangeOp>();\n const lastOp = new Map<string, WhiteboardChangeOp>();\n const sawUpdate = new Set<string>();\n for (const entry of inRange) {\n if (!firstOp.has(entry.ItemID)) {\n firstOp.set(entry.ItemID, entry.Op);\n }\n lastOp.set(entry.ItemID, entry.Op);\n if (entry.Op === 'update') {\n sawUpdate.add(entry.ItemID);\n }\n }\n\n for (const [id, first] of firstOp) {\n const last = lastOp.get(id);\n const item = this.items.get(id);\n if (first === 'add') {\n if (item) {\n delta.added.push(this.compact(item)); // add → (move/update)* coalesces into the added entry\n }\n // add → … → remove: net nothing\n continue;\n }\n if (last === 'remove' || !item) {\n delta.removed.push(id);\n continue;\n }\n if (sawUpdate.has(id)) {\n delta.updated.push(this.compact(item)); // update (+ moves) → one updated entry w/ current state\n continue;\n }\n // moves only → one moved entry at the current position\n const b = this.ItemBounds(item);\n delta.moved.push({ id, x: Math.round(b.X), y: Math.round(b.Y) });\n }\n\n delta.summary = this.composeSummaryText({\n added: delta.added.length,\n moved: delta.moved.length,\n updated: delta.updated.length,\n removed: delta.removed.length\n });\n return delta;\n }\n\n /** Full compact scene + counts — the popover's stats and the delta-reset payload. */\n public BuildSceneSummary(): WhiteboardSceneSummary {\n const items = this.Items;\n const byKind: Partial<Record<WhiteboardItemKind, number>> = {};\n for (const item of items) {\n byKind[item.Kind] = (byKind[item.Kind] ?? 0) + 1;\n }\n return {\n op: 'scene-summary',\n seq: this.seq,\n counts: {\n total: this.ElementCount,\n user: this.CountByAuthor('user'),\n agent: this.CountByAuthor('agent'),\n byKind\n },\n items: items.map((i) => this.compact(i)),\n pages: this.scenePages(),\n summary: this.composeSummaryText({})\n };\n }\n\n /** Compact page list for deltas / summaries (model-facing). */\n protected scenePages(): WhiteboardScenePage[] {\n return this.pages.map((p) => ({\n id: p.ID,\n name: p.Name,\n active: UUIDsEqual(p.ID, this.activePageId),\n items: p.Items.size\n }));\n }\n\n // ────────────────────────────────────────────── persistence\n\n /**\n * Serialize the board (state of record — persisted as the session-channel artifact).\n * Emits the VERSION 2 paged shape (see {@link WhiteboardStateJSON}); the legacy flat\n * shape is still accepted on load and rehydrates as a single page \"Page 1\".\n */\n public ToJSON(): string {\n return JSON.stringify(this.snapshot());\n }\n\n /**\n * Rehydrate a board from {@link ToJSON} output — BOTH shapes accepted: the current\n * paged shape (version 2) and the legacy flat shape (version 1, `items` at the root),\n * which migrates to one page named \"Page 1\". Throws on malformed input (use\n * {@link LoadFromJSON} or `ParseBoardStateJson` for the tolerant variants).\n */\n public static FromJSON(json: string): WhiteboardState {\n const normalized = WhiteboardState.normalizePersisted(JSON.parse(json));\n if (!normalized) {\n throw new Error('WhiteboardState.FromJSON: malformed payload');\n }\n const state = new WhiteboardState();\n state.restore(normalized);\n state.seq = normalized.seq;\n state.journalTrimmedBeforeSeq = state.seq; // older tokens force reset deltas\n return state;\n }\n\n /**\n * Normalize a parsed persisted payload — EITHER shape — into the current\n * {@link WhiteboardStateJSON}. Returns `null` for anything unrecognizable (the\n * callers decide whether that throws or fails soft). Defensive throughout: page\n * entries missing ids/names/item arrays are repaired, an empty page list gains one\n * \"Page 1\", and an unknown `activePageId` falls back to the first page.\n */\n private static normalizePersisted(parsed: unknown): WhiteboardStateJSON | null {\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return null;\n }\n const raw = parsed as Record<string, unknown>;\n const num = (value: unknown, fallback: number): number =>\n typeof value === 'number' && Number.isFinite(value) ? value : fallback;\n\n if (Array.isArray(raw['pages'])) {\n // CURRENT shape (version 2, paged)\n const pages: WhiteboardPageJSON[] = [];\n for (const entry of raw['pages'] as unknown[]) {\n if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {\n continue;\n }\n const p = entry as Record<string, unknown>;\n const name = typeof p['name'] === 'string' && (p['name'] as string).trim().length > 0\n ? (p['name'] as string) : `Page ${pages.length + 1}`;\n pages.push({\n id: typeof p['id'] === 'string' && (p['id'] as string).length > 0 ? (p['id'] as string) : `page-${pages.length + 1}`,\n name,\n // additive authorship field — tolerated absent (pre-garnish payloads → 'user')\n author: p['author'] === 'agent' ? 'agent' : 'user',\n items: Array.isArray(p['items']) ? (p['items'] as WhiteboardItem[]) : []\n });\n }\n if (pages.length === 0) {\n pages.push({ id: 'page-1', name: 'Page 1', items: [] });\n }\n const active = raw['activePageId'];\n return {\n version: 2,\n seq: num(raw['seq'], 0),\n idCounter: num(raw['idCounter'], 0),\n zCounter: num(raw['zCounter'], 0),\n pageCounter: Math.max(num(raw['pageCounter'], pages.length), pages.length),\n activePageId: typeof active === 'string' && pages.some((p) => p.id === active) ? active : pages[0].id,\n pages\n };\n }\n if (Array.isArray(raw['items'])) {\n // LEGACY shape (version 1, flat) — migrate to a single page \"Page 1\"\n return {\n version: 2,\n seq: num(raw['seq'], 0),\n idCounter: num(raw['idCounter'], 0),\n zCounter: num(raw['zCounter'], 0),\n pageCounter: 1,\n activePageId: 'page-1',\n pages: [{ id: 'page-1', name: 'Page 1', items: raw['items'] as WhiteboardItem[] }]\n };\n }\n return null;\n }\n\n /**\n * Rehydrate THIS instance in place from {@link ToJSON} output — used by the channel's\n * `RestoreState` hook so existing subscriptions (perception feed, save pipeline) and any\n * bound surface keep pointing at the same engine. TOLERANT: malformed input returns\n * `false` and leaves the current state untouched (never throws).\n *\n * On success the undo/redo stacks and journal are cleared (restored state is the new\n * baseline), stale delta tokens force reset semantics, one `'replace'` change is\n * emitted so consumers re-read the full scene, and {@link BoardLoaded$} fires.\n */\n public LoadFromJSON(json: string): boolean {\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n }\n catch {\n return false;\n }\n const normalized = WhiteboardState.normalizePersisted(parsed);\n if (!normalized) {\n return false;\n }\n this.restore(normalized);\n this.seq = normalized.seq;\n this.journal = [];\n this.journalTrimmedBeforeSeq = this.seq; // older tokens force reset deltas\n this.undoStack = [];\n this.redoStack = [];\n this.changeSelection(null);\n this.record('replace', '', 'user', 'restored a saved board');\n this.boardLoaded.next({ ItemCount: this.TotalItemCount });\n return true;\n }\n\n // ────────────────────────────────────────────── internals\n\n /** Mint the next stable item ID for a kind (`sticky-3`, `shape-7`, …). */\n protected nextId(kind: WhiteboardItemKind): string {\n return `${kind}-${++this.idCounter}`;\n }\n\n /**\n * Pre-mutation bookkeeping shared by every committed mutation: pushes the undo\n * snapshot (unless inside a {@link RunBatch}, which snapshotted at batch start) and\n * invalidates the redo branch. Subclasses extending the mutation paths should call\n * this exactly once per logical change, AFTER any cancelable before-event survived.\n */\n protected beforeMutate(): void {\n if (this.batchDepth === 0) {\n this.pushUndo();\n }\n // Any forward mutation invalidates the redo branch (batched mutations included).\n this.redoStack = [];\n }\n\n /** Push the current scene onto the undo stack (bounded) and drop the redo branch. */\n protected pushUndo(): void {\n this.undoStack.push(this.snapshot());\n if (this.undoStack.length > WhiteboardState.UndoMax) {\n this.undoStack.shift();\n }\n this.redoStack = [];\n }\n\n /**\n * Deep-copied serializable snapshot of the WHOLE board — every page's items plus the\n * page structure and counters (undo entries / ToJSON). Page items serialize in render\n * order (ascending Z).\n */\n protected snapshot(): WhiteboardStateJSON {\n return {\n version: 2,\n seq: this.seq,\n idCounter: this.idCounter,\n zCounter: this.zCounter,\n pageCounter: this.pageCounter,\n activePageId: this.activePageId,\n pages: this.pages.map((p) => ({\n id: p.ID,\n name: p.Name,\n author: p.Author,\n items: JSON.parse(JSON.stringify(Array.from(p.Items.values()).sort((a, b) => a.Z - b.Z))) as WhiteboardItem[]\n }))\n };\n }\n\n /**\n * Swap the whole board to a snapshot's pages/counters (drops a now-missing selection;\n * an unknown active-page id falls back to the first page; an empty page list gains a\n * fresh \"Page 1\" so the engine never runs page-less).\n */\n protected restore(snap: WhiteboardStateJSON): void {\n this.pages = (snap.pages ?? []).map((p) => ({\n ID: p.id,\n Name: p.name,\n Author: p.author === 'agent' ? 'agent' : 'user',\n Items: new Map((JSON.parse(JSON.stringify(p.items ?? [])) as WhiteboardItem[])\n .filter((i) => !!i && typeof i === 'object' && typeof i.ID === 'string')\n .map((i) => [i.ID, i]))\n }));\n if (this.pages.length === 0) {\n this.pages = [{ ID: 'page-1', Name: 'Page 1', Author: 'user', Items: new Map<string, WhiteboardItem>() }];\n }\n this.activePageId = this.pages.some((p) => UUIDsEqual(p.ID, snap.activePageId)) ? snap.activePageId : this.pages[0].ID;\n this.idCounter = snap.idCounter ?? 0;\n this.zCounter = snap.zCounter ?? 0;\n this.pageCounter = Math.max(snap.pageCounter ?? this.pages.length, this.pages.length);\n // drop selection members the restored active page no longer contains\n const surviving = this.selectedIds.filter((id) => this.items.has(id));\n if (surviving.length !== this.selectedIds.length) {\n this.applySelection(surviving);\n }\n }\n\n /**\n * Post-mutation bookkeeping shared by every committed mutation: bumps the sequence,\n * appends the journal entry (bounded — trimming forces reset deltas for stale tokens)\n * and emits the {@link Changed$} notification.\n */\n protected record(op: WhiteboardChangeOp, itemId: string, author: WhiteboardAuthor, summaryFragment: string): void {\n this.seq++;\n this.journal.push({ Seq: this.seq, Op: op, ItemID: itemId });\n if (this.journal.length > WhiteboardState.JournalMax) {\n const dropped = this.journal.splice(0, this.journal.length - WhiteboardState.JournalMax);\n this.journalTrimmedBeforeSeq = dropped[dropped.length - 1].Seq;\n }\n this.changed.next({ Op: op, ItemID: itemId, Author: author, SummaryFragment: summaryFragment, Seq: this.seq });\n }\n\n /** Project one item to its compact, model-facing representation (deltas / summaries). */\n protected compact(item: WhiteboardItem): WhiteboardCompactItem {\n const c: WhiteboardCompactItem = { id: item.ID, type: item.Kind, author: item.Author };\n switch (item.Kind) {\n case 'sticky':\n c.x = Math.round(item.X);\n c.y = Math.round(item.Y);\n c.text = clip(item.Text, 120);\n WhiteboardState.compactTextStyle(item, c);\n break;\n case 'shape':\n c.x = Math.round(item.X);\n c.y = Math.round(item.Y);\n c.w = Math.round(item.W);\n c.h = Math.round(item.H);\n c.shape = item.Shape;\n c.text = clip(item.Sub ? `${item.Label} (${item.Sub})` : item.Label, 120);\n break;\n case 'text':\n c.x = Math.round(item.X);\n c.y = Math.round(item.Y);\n if (item.W) {\n c.w = Math.round(item.W);\n }\n c.text = clip(item.Text, 120);\n WhiteboardState.compactTextStyle(item, c);\n if (item.Color) {\n c.color = item.Color;\n }\n break;\n case 'image':\n c.x = Math.round(item.X);\n c.y = Math.round(item.Y);\n c.name = item.Name;\n break;\n case 'ink': {\n const b = this.ItemBounds(item);\n c.x = Math.round(b.X);\n c.y = Math.round(b.Y);\n c.w = Math.round(b.W);\n c.h = Math.round(b.H);\n c.points = item.Points.length;\n break;\n }\n case 'connector':\n c.from = item.FromItemID ?? item.FromPoint ?? null;\n c.to = item.ToItemID ?? item.ToPoint ?? null;\n break;\n case 'highlight':\n c.x = Math.round(item.X);\n c.y = Math.round(item.Y);\n c.w = Math.round(item.W);\n c.h = Math.round(item.H);\n if (item.Label) {\n c.text = clip(item.Label, 120);\n }\n break;\n case 'markdown':\n // the agent must SEE what's in the panel — project the clipped SOURCE, not a stub\n c.x = Math.round(item.X);\n c.y = Math.round(item.Y);\n c.w = Math.round(item.W);\n if (item.H != null) {\n c.h = Math.round(item.H);\n }\n c.text = clip(item.Markdown, 200);\n break;\n case 'html':\n c.x = Math.round(item.X);\n c.y = Math.round(item.Y);\n c.w = Math.round(item.W);\n c.h = Math.round(item.H);\n if (item.Title) {\n c.name = clip(item.Title, 80);\n }\n c.text = clip(item.Html, 200);\n break;\n }\n return c;\n }\n\n /** Project the optional text-style fields onto a compact item (sticky / text kinds). */\n private static compactTextStyle(item: WhiteboardStickyItem | WhiteboardTextItem, c: WhiteboardCompactItem): void {\n if (item.FontSize != null) {\n c.fontSize = item.FontSize;\n }\n if (item.FontFamily) {\n c.fontFamily = item.FontFamily;\n }\n if (item.FontWeight === 700) {\n c.bold = true;\n }\n }\n\n /**\n * Compose the human-readable tail line of deltas / summaries (\"2 added, 1 moved. …\"),\n * including which page is active and the full page list — so the model always knows\n * pages exist and which one its item entries describe.\n */\n protected composeSummaryText(parts: { added?: number; moved?: number; updated?: number; removed?: number; reset?: boolean }): string {\n const bits: string[] = [];\n if (parts.reset) {\n bits.push('full scene snapshot (state replaced)');\n }\n else {\n if (parts.added) {\n bits.push(`${parts.added} added`);\n }\n if (parts.moved) {\n bits.push(`${parts.moved} moved`);\n }\n if (parts.updated) {\n bits.push(`${parts.updated} updated`);\n }\n if (parts.removed) {\n bits.push(`${parts.removed} removed`);\n }\n if (bits.length === 0) {\n bits.push('no changes');\n }\n }\n return `${bits.join(', ')}. ${this.composePagesText()}`;\n }\n\n /** The page-aware scene sentence shared by every delta / summary tail line. */\n protected composePagesText(): string {\n const active = this.activePage;\n const index = this.pages.indexOf(active) + 1;\n const counts = `${this.ElementCount} elements (user ${this.CountByAuthor('user')} · agent ${this.CountByAuthor('agent')})`;\n if (this.pages.length === 1) {\n return `Active page \"${active.Name}\" (the only page) has ${counts}.`;\n }\n const others = this.pages\n .filter((p) => !UUIDsEqual(p.ID, active.ID))\n .map((p) => `\"${p.Name}\" (${p.Items.size})`)\n .join(', ');\n return `Active page \"${active.Name}\" (${index} of ${this.pages.length}) has ${counts}. Other pages: ${others}.`;\n }\n\n private static describe(item: WhiteboardItem): string {\n switch (item.Kind) {\n case 'sticky': return `a sticky note (\"${clip(item.Text)}\")`;\n case 'shape': return `a ${item.Shape} (\"${clip(item.Label)}\")`;\n case 'text': return `a text label (\"${clip(item.Text)}\")`;\n case 'image': return `an image (${item.Name})`;\n case 'ink': return 'an ink stroke';\n case 'connector': return 'a connector';\n case 'highlight': return 'a highlight region';\n case 'markdown': return `a markdown panel (\"${clip(item.Markdown)}\")`;\n case 'html': return `an HTML widget${item.Title ? ` (\"${clip(item.Title)}\")` : ''}`;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"whiteboard-state.js","sourceRoot":"","sources":["../../src/lib/whiteboard-state.ts"],"names":[],"mappings":"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","sourcesContent":["import { Observable, Subject } from 'rxjs';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/**\n * WHITEBOARD — typed board model + state engine.\n *\n * This file is intentionally Angular-free: it is the single mutation API used by BOTH the\n * user-facing board tools (pen, stickies, shapes, …) and any programmatic co-author —\n * typically an AI agent driving the `Whiteboard_*` tool set (`Whiteboard_AddNote`,\n * `Whiteboard_DrawConnector`, …, see `whiteboard-tools.ts`).\n *\n * Pages (OneNote-style): a board is an ordered list of named PAGES, each with its own\n * items collection; exactly one page is ACTIVE at a time and every item operation\n * (add / update / move / remove / connectors / clear / perception) targets the active\n * page. See {@link WhiteboardState.AddPage} / {@link WhiteboardState.SwitchPage} /\n * {@link WhiteboardState.RenamePage} / {@link WhiteboardState.RemovePage}. A fresh\n * board starts with one page named \"Page 1\"; legacy (pre-pages, flat) persisted JSON\n * rehydrates as that single page.\n *\n * Perception model (how a programmatic co-author \"sees\" the board):\n * - every mutation appends to a compact change journal and emits on {@link WhiteboardState.Changed$};\n * - {@link WhiteboardState.BuildSceneDelta} coalesces the journal since a token into ONE delta\n * (multiple moves of one item → one `moved` entry) with replace-current-state semantics;\n * - {@link WhiteboardState.BuildSceneSummary} produces the full compact scene the\n * \"What the agent sees\" popover renders;\n * - {@link WhiteboardState.ToJSON} / {@link WhiteboardState.FromJSON} persist the board's\n * state of record (e.g. a session-channel artifact in MJ realtime sessions).\n *\n * Extensibility: every targeted mutation also raises a cancelable BEFORE event and a\n * matching AFTER event (`ItemAdding$` / `ItemAdded$`, `ItemUpdating$` / `ItemUpdated$`,\n * `ItemRemoving$` / `ItemRemoved$`) — see the {@link WhiteboardState} class docs.\n */\n\n/** Who authored a board item / mutation. The violet treatment is RESERVED for `'agent'`. */\nexport type WhiteboardAuthor = 'user' | 'agent';\n\n/** The discriminant for the {@link WhiteboardItem} union. */\nexport type WhiteboardItemKind = 'sticky' | 'shape' | 'ink' | 'text' | 'image' | 'connector' | 'highlight' | 'markdown' | 'html';\n\n/** Shape geometry of a {@link WhiteboardShapeItem}. */\nexport type WhiteboardShapeKind = 'rect' | 'ellipse' | 'diamond';\n\n/** Visual tint of a USER sticky (agent stickies always render violet, regardless of tint). */\nexport type WhiteboardStickyTint = 'amber' | 'amber-light';\n\n/**\n * Curated font-size steps for text labels and sticky notes. The toolbar's text-style flyout\n * and the agent's `fontSize` tool params both restrict to these values.\n */\nexport const WHITEBOARD_FONT_SIZES: readonly number[] = [12, 14, 18, 24, 32];\n\n/**\n * Font family choices for text labels / stickies. The keys are mapped to token-friendly\n * font stacks in the board CSS (`wb-font-serif`, `wb-font-mono`; sans is the default).\n */\nexport type WhiteboardFontFamily = 'sans' | 'serif' | 'mono';\n\n/** Font weights for text labels / stickies (regular or bold). */\nexport type WhiteboardFontWeight = 400 | 700;\n\n/** A point in board (content) coordinates. */\nexport interface WhiteboardPoint {\n X: number;\n Y: number;\n}\n\n/** Fields shared by every board item. */\nexport interface WhiteboardItemBase {\n /** Stable item id (e.g. `sticky-3`) — referenced by connectors, deltas and agent tools. */\n ID: string;\n /** Who placed the item. Drives the ownership chrome (chips / violet vs slate-amber). */\n Author: WhiteboardAuthor;\n /** Render order (higher renders on top). Assigned by the engine. */\n Z: number;\n}\n\n/** A sticky note. */\nexport interface WhiteboardStickyItem extends WhiteboardItemBase {\n Kind: 'sticky';\n X: number;\n Y: number;\n /** Width in px; defaults to {@link WHITEBOARD_DEFAULTS.StickyW} when omitted. */\n W?: number;\n Text: string;\n /** User-palette tint; ignored for agent stickies (always violet). */\n Tint?: WhiteboardStickyTint;\n /** Slight playful tilt, in degrees. */\n Rotation?: number;\n /** Curated font size (see {@link WHITEBOARD_FONT_SIZES}); omitted = the CSS default. */\n FontSize?: number;\n /** Font family key (mapped to token-friendly stacks in CSS); omitted = sans. */\n FontFamily?: WhiteboardFontFamily;\n /** Font weight; omitted = the kind's CSS default. */\n FontWeight?: WhiteboardFontWeight;\n}\n\n/** A drawn shape box (rect / ellipse / diamond) with an optional label + sub-label. */\nexport interface WhiteboardShapeItem extends WhiteboardItemBase {\n Kind: 'shape';\n Shape: WhiteboardShapeKind;\n X: number;\n Y: number;\n W: number;\n H: number;\n Label: string;\n Sub?: string;\n}\n\n/** A free-floating text label. */\nexport interface WhiteboardTextItem extends WhiteboardItemBase {\n Kind: 'text';\n X: number;\n Y: number;\n Text: string;\n /** Wrap width in px — text wraps at this width. Omitted = wrap at the default max width. */\n W?: number;\n /** Curated font size (see {@link WHITEBOARD_FONT_SIZES}); omitted = the CSS default. */\n FontSize?: number;\n /** Font family key (mapped to token-friendly stacks in CSS); omitted = sans. */\n FontFamily?: WhiteboardFontFamily;\n /** Font weight; omitted = the kind's CSS default. */\n FontWeight?: WhiteboardFontWeight;\n /**\n * Text color from the USER pen palette. Violet is reserved for the agent's ownership\n * styling (enforced in the user UI — the palette never offers violet); agent text gets\n * its violet from the Author treatment, never from this field.\n */\n Color?: string;\n}\n\n/** A pasted / inserted image card. `Url` is a runtime object URL (not persisted as pixels). */\nexport interface WhiteboardImageItem extends WhiteboardItemBase {\n Kind: 'image';\n X: number;\n Y: number;\n /** Width in px; defaults to {@link WHITEBOARD_DEFAULTS.ImageW}. */\n W?: number;\n Name: string;\n Url?: string | null;\n}\n\n/** A freehand ink stroke (polyline in board coordinates, smoothed at render time). */\nexport interface WhiteboardInkItem extends WhiteboardItemBase {\n Kind: 'ink';\n Points: WhiteboardPoint[];\n /** Stroke color. The user palette NEVER includes violet — violet ink is the agent's. */\n Color: string;\n StrokeWidth: number;\n}\n\n/**\n * A connector between two endpoints. Each endpoint references an item by ID when attached;\n * when the referenced item is removed (or was never set) the endpoint falls back to the\n * absolute `…Point` coordinate.\n */\nexport interface WhiteboardConnectorItem extends WhiteboardItemBase {\n Kind: 'connector';\n FromItemID?: string | null;\n ToItemID?: string | null;\n FromPoint?: WhiteboardPoint | null;\n ToPoint?: WhiteboardPoint | null;\n}\n\n/** A pulsing highlight region (\"pointing without touching\") — dismissed by clicking it. */\nexport interface WhiteboardHighlightItem extends WhiteboardItemBase {\n Kind: 'highlight';\n X: number;\n Y: number;\n W: number;\n H: number;\n Label?: string;\n}\n\n/**\n * A rendered MARKDOWN panel — a rich, formatted card (headings, lists, code, links) for\n * illustrative content that outgrows a sticky note. Width is explicit (the panel's column\n * width); height is content-driven, optionally capped by `H` (overflow clips).\n */\nexport interface WhiteboardMarkdownItem extends WhiteboardItemBase {\n Kind: 'markdown';\n X: number;\n Y: number;\n /** Panel width in px (required — markdown always renders in an explicit column). */\n W: number;\n /** Optional max height in px; content beyond it is clipped. Omitted = content-driven. */\n H?: number;\n /** The markdown source. Rendered SAFELY (sanitized — never raw HTML passthrough). */\n Markdown: string;\n}\n\n/**\n * An interactive HTML widget — arbitrary HTML (scripts included) rendered inside a\n * STRICTLY SANDBOXED iframe (`sandbox=\"allow-scripts\"` only, opaque origin — see the\n * board component for the full security rationale). Dragged/selected by its card chrome —\n * header bar, border ring and lazy placeholder — while pointer events inside the sandboxed\n * frame stay with the widget, so iframe interactivity and board interactions coexist.\n */\nexport interface WhiteboardHtmlItem extends WhiteboardItemBase {\n Kind: 'html';\n X: number;\n Y: number;\n W: number;\n H: number;\n /** The widget's full HTML source (becomes the sandboxed iframe's `srcdoc`). */\n Html: string;\n /** Optional title shown on the widget's header bar. */\n Title?: string;\n}\n\n/** Discriminated union of everything that can live on the board. */\nexport type WhiteboardItem =\n | WhiteboardStickyItem\n | WhiteboardShapeItem\n | WhiteboardTextItem\n | WhiteboardImageItem\n | WhiteboardInkItem\n | WhiteboardConnectorItem\n | WhiteboardHighlightItem\n | WhiteboardMarkdownItem\n | WhiteboardHtmlItem;\n\n/** Distributive Omit that preserves the discriminated union. */\ntype DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;\n\n/** What callers pass to {@link WhiteboardState.AddItem} — the engine stamps ID / Z / Author. */\nexport type WhiteboardItemInput = DistributiveOmit<WhiteboardItem, 'ID' | 'Z' | 'Author'>;\n\n/** Patchable fields for {@link WhiteboardState.UpdateItem} (kind/identity fields excluded). */\nexport interface WhiteboardItemPatch {\n X?: number;\n Y?: number;\n W?: number;\n H?: number;\n Text?: string;\n Label?: string;\n Sub?: string;\n Name?: string;\n Url?: string | null;\n Color?: string;\n StrokeWidth?: number;\n Points?: WhiteboardPoint[];\n Tint?: WhiteboardStickyTint;\n Rotation?: number;\n FontSize?: number;\n FontFamily?: WhiteboardFontFamily;\n FontWeight?: WhiteboardFontWeight;\n Shape?: WhiteboardShapeKind;\n Markdown?: string;\n Html?: string;\n Title?: string;\n FromItemID?: string | null;\n ToItemID?: string | null;\n FromPoint?: WhiteboardPoint | null;\n ToPoint?: WhiteboardPoint | null;\n}\n\n/** Mutation kinds carried on {@link WhiteboardChange} and in the journal. */\nexport type WhiteboardChangeOp = 'add' | 'update' | 'move' | 'remove' | 'replace';\n\n// ────────────────────────────────────────────── before / after mutation events\n\n/**\n * Base shape of every cancelable BEFORE event raised by {@link WhiteboardState} (and by\n * the components layered on top of it). Handlers run SYNCHRONOUSLY during the emit; any\n * handler may set {@link Cancel} to `true` and the operation is aborted before it touches\n * the board (no undo snapshot, no journal entry, no {@link WhiteboardState.Changed$}\n * emission). The matching AFTER event then never fires.\n */\nexport interface WhiteboardCancelableEventArgs {\n /** Set to `true` (in a synchronous handler) to veto the operation. */\n Cancel: boolean;\n}\n\n/**\n * BEFORE-event args for {@link WhiteboardState.ItemAdding$}. Raised by\n * {@link WhiteboardState.AddItem} (and therefore also by {@link WhiteboardState.Highlight}\n * and {@link WhiteboardState.DuplicateItem}, which add through it) before anything is\n * stamped or stored. Handlers may mutate {@link Input} (e.g. clamp coordinates, rewrite\n * text) — the engine adds whatever the args carry after the emit — or set `Cancel` to\n * veto the add entirely (the caller receives `null`).\n */\nexport interface WhiteboardItemAddingEventArgs extends WhiteboardCancelableEventArgs {\n /** The item about to be added (no ID / Z / Author yet — the engine stamps those). */\n Input: WhiteboardItemInput;\n /** Who is adding the item. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.ItemAdded$} — the item is on the board. */\nexport interface WhiteboardItemAddedEventArgs {\n /** The added item, with its engine-stamped ID / Z / Author. */\n Item: WhiteboardItem;\n /** Who added the item. */\n Author: WhiteboardAuthor;\n}\n\n/**\n * Which mutation family an updating/updated event describes:\n * - `'update'` — a field patch via {@link WhiteboardState.UpdateItem};\n * - `'move'` — a reposition via {@link WhiteboardState.MoveItem};\n * - `'reorder'` — a z-order change via {@link WhiteboardState.BringToFront} /\n * {@link WhiteboardState.SendToBack}.\n */\nexport type WhiteboardUpdateOperation = 'update' | 'move' | 'reorder';\n\n/**\n * BEFORE-event args for {@link WhiteboardState.ItemUpdating$}. {@link Item} is the LIVE,\n * pre-mutation item (do not mutate it directly — cancel and apply your own patch\n * instead). For `'update'` operations handlers may adjust {@link Patch}; for `'move'`\n * operations {@link Position} carries the requested top-left target.\n */\nexport interface WhiteboardItemUpdatingEventArgs extends WhiteboardCancelableEventArgs {\n /** The item about to change (current, pre-mutation state). */\n Item: WhiteboardItem;\n /** Which mutation family is about to run. */\n Operation: WhiteboardUpdateOperation;\n /** The field patch (`'update'` operations only). Handlers may adjust it. */\n Patch?: WhiteboardItemPatch;\n /** The requested top-left position (`'move'` operations only). */\n Position?: WhiteboardPoint;\n /** Who is changing the item. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.ItemUpdated$} — the change has applied. */\nexport interface WhiteboardItemUpdatedEventArgs {\n /** The item in its post-mutation state. */\n Item: WhiteboardItem;\n /** Which mutation family ran. */\n Operation: WhiteboardUpdateOperation;\n /** Who changed the item. */\n Author: WhiteboardAuthor;\n}\n\n/**\n * BEFORE-event args for {@link WhiteboardState.ItemRemoving$} — raised before the item\n * leaves the board (and before any connector endpoints anchored to it are frozen).\n * Cancel to keep the item.\n */\nexport interface WhiteboardItemRemovingEventArgs extends WhiteboardCancelableEventArgs {\n /** The item about to be removed. */\n Item: WhiteboardItem;\n /** Who is removing the item. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.ItemRemoved$} — the item is gone. */\nexport interface WhiteboardItemRemovedEventArgs {\n /** The removed item (its last state — no longer on the board). */\n Item: WhiteboardItem;\n /** Who removed the item. */\n Author: WhiteboardAuthor;\n}\n\n/**\n * BEFORE-event args for {@link WhiteboardState.ContentChanging$} — raised (in addition to\n * {@link WhiteboardState.ItemUpdating$}) when an {@link WhiteboardState.UpdateItem} patch\n * touches an item's CONTENT fields: `Text`, `Label`, `Sub`, `Markdown`, `Html` or `Title`.\n * This is the hook for content governance (length limits, redaction, moderation) without\n * having to inspect every geometry patch. Cancel to veto the whole update.\n */\nexport interface WhiteboardContentChangingEventArgs extends WhiteboardCancelableEventArgs {\n /** The item whose content is about to change (current, pre-mutation state). */\n Item: WhiteboardItem;\n /** The full patch being applied (content fields included). Handlers may adjust it. */\n Patch: WhiteboardItemPatch;\n /** Who is changing the content. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.ContentChanged$} — the content has applied. */\nexport interface WhiteboardContentChangedEventArgs {\n /** The item in its post-mutation state. */\n Item: WhiteboardItem;\n /** The patch that was applied. */\n Patch: WhiteboardItemPatch;\n /** Who changed the content. */\n Author: WhiteboardAuthor;\n}\n\n/**\n * AFTER-event args for {@link WhiteboardState.SelectionChanged$} — the selection changed\n * (single OR multi). Selection is UI state: it is not journaled, not undoable and not\n * persisted, so this event is a notification only (not cancelable). Fires for explicit\n * {@link WhiteboardState.Select} / {@link WhiteboardState.ToggleSelect} /\n * {@link WhiteboardState.SelectMany} calls AND for implicit clears (a selected item was\n * removed, the page switched, or a restore dropped it).\n */\nexport interface WhiteboardSelectionChangedEventArgs {\n /** The PRIMARY selected item's ID (last added to the selection), or null when cleared. */\n SelectedID: string | null;\n /** The previously primary item's ID, or null when nothing was selected. */\n PreviousID: string | null;\n /** The full multi-selection (selection order, last = primary). Empty when cleared. */\n SelectedIDs: string[];\n}\n\n/**\n * AFTER-event args for {@link WhiteboardState.BoardCleared$} — every item was removed in\n * one operation via {@link WhiteboardState.Clear}. The clear is a single undo step; one\n * `'replace'` op lands in the journal so perception consumers re-read the (now empty)\n * scene.\n */\nexport interface WhiteboardBoardClearedEventArgs {\n /** Who cleared the board. */\n Author: WhiteboardAuthor;\n /** How many items were removed (highlights included). */\n ItemCount: number;\n}\n\n/**\n * AFTER-event args for {@link WhiteboardState.BoardLoaded$} — a persisted board was\n * rehydrated IN PLACE via {@link WhiteboardState.LoadFromJSON}. Undo/redo stacks and the\n * journal were reset (the restored state is the new baseline) and one `'replace'` op was\n * journaled, so perception consumers re-read the full scene.\n */\nexport interface WhiteboardBoardLoadedEventArgs {\n /** How many items the restored board contains (summed across ALL pages). */\n ItemCount: number;\n}\n\n// ────────────────────────────────────────────── pages\n\n/**\n * Public, read-only descriptor of one board page — what {@link WhiteboardState.Pages}\n * returns and what every page before/after event carries. A snapshot, not a live view:\n * re-read {@link WhiteboardState.Pages} after mutations.\n */\nexport interface WhiteboardPageInfo {\n /** Stable page id (e.g. `page-2`) — accepted anywhere a page name is accepted. */\n ID: string;\n /** Display name (e.g. \"Page 1\"). Not guaranteed unique; IDs are. */\n Name: string;\n /** How many items live on the page (highlights included). */\n ItemCount: number;\n /** Whether this is the board's active page. */\n Active: boolean;\n /**\n * Who CREATED the page. Drives the page strip's delegated-violet garnish for\n * agent-created pages (mirroring the item-level agent treatment). Persisted in the\n * v2 JSON as an additive `author` field; payloads without it rehydrate as `'user'`.\n */\n Author: WhiteboardAuthor;\n}\n\n/**\n * BEFORE-event args for {@link WhiteboardState.PageAdding$} — raised by\n * {@link WhiteboardState.AddPage} before the page exists. Handlers may rewrite\n * {@link Name} (the engine trims it; an emptied name falls back to the auto-name) or set\n * `Cancel` to veto the add (the caller receives `null`).\n */\nexport interface WhiteboardPageAddingEventArgs extends WhiteboardCancelableEventArgs {\n /** The name the page will get (auto-named \"Page N\" when the caller omitted one). */\n Name: string;\n /** Who is adding the page. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.PageAdded$} — the page exists and is active. */\nexport interface WhiteboardPageAddedEventArgs {\n /** The added page (now the active page). */\n Page: WhiteboardPageInfo;\n /** Who added the page. */\n Author: WhiteboardAuthor;\n}\n\n/**\n * BEFORE-event args for {@link WhiteboardState.PageSwitching$} — raised by\n * {@link WhiteboardState.SwitchPage} before the active page changes. Cancel to stay on\n * the current page.\n */\nexport interface WhiteboardPageSwitchingEventArgs extends WhiteboardCancelableEventArgs {\n /** The page that is currently active. */\n FromPage: WhiteboardPageInfo;\n /** The page about to become active. */\n ToPage: WhiteboardPageInfo;\n /** Who is switching. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.PageSwitched$} — the active page changed. */\nexport interface WhiteboardPageSwitchedEventArgs {\n /** The previously active page. */\n FromPage: WhiteboardPageInfo;\n /** The newly active page. */\n ToPage: WhiteboardPageInfo;\n /** Who switched. */\n Author: WhiteboardAuthor;\n}\n\n/**\n * BEFORE-event args for {@link WhiteboardState.PageRenaming$} — raised by\n * {@link WhiteboardState.RenamePage}. Handlers may rewrite {@link NewName} (trimmed by\n * the engine; an emptied rewrite aborts the rename) or set `Cancel` to veto.\n */\nexport interface WhiteboardPageRenamingEventArgs extends WhiteboardCancelableEventArgs {\n /** The page about to be renamed (pre-rename snapshot). */\n Page: WhiteboardPageInfo;\n /** The requested new name. Handlers may adjust it. */\n NewName: string;\n /** Who is renaming. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.PageRenamed$} — the rename applied. */\nexport interface WhiteboardPageRenamedEventArgs {\n /** The page in its post-rename state. */\n Page: WhiteboardPageInfo;\n /** The name the page had before. */\n OldName: string;\n /** Who renamed it. */\n Author: WhiteboardAuthor;\n}\n\n/**\n * BEFORE-event args for {@link WhiteboardState.PageRemoving$} — raised by\n * {@link WhiteboardState.RemovePage} (never for the last remaining page — that is\n * guarded before the event). Cancel to keep the page.\n */\nexport interface WhiteboardPageRemovingEventArgs extends WhiteboardCancelableEventArgs {\n /** The page about to be removed (with all of its items). */\n Page: WhiteboardPageInfo;\n /** Who is removing it. */\n Author: WhiteboardAuthor;\n}\n\n/** AFTER-event args for {@link WhiteboardState.PageRemoved$} — the page is gone. */\nexport interface WhiteboardPageRemovedEventArgs {\n /** The removed page (its last state). */\n Page: WhiteboardPageInfo;\n /** When the REMOVED page was active: the neighbor page that became active. Else null. */\n ActivatedPage: WhiteboardPageInfo | null;\n /** Who removed it. */\n Author: WhiteboardAuthor;\n}\n\n/** Compact page descriptor carried on scene deltas / summaries (model-facing). */\nexport interface WhiteboardScenePage {\n id: string;\n name: string;\n active: boolean;\n items: number;\n}\n\n/**\n * One coalesce-able change notification, emitted on {@link WhiteboardState.Changed$}\n * after every mutation. `'replace'` means \"the whole scene was swapped\" (undo / redo /\n * FromJSON) — consumers should re-read the full state.\n */\nexport interface WhiteboardChange {\n Op: WhiteboardChangeOp;\n /** Empty string for `'replace'` ops. */\n ItemID: string;\n Author: WhiteboardAuthor;\n /** Human fragment for toasts / activity (\"added a sticky note\"). */\n SummaryFragment: string;\n /** Monotonic sequence number — also the delta token currency. */\n Seq: number;\n}\n\n/** Compact, model-facing representation of one item inside deltas / summaries. */\nexport interface WhiteboardCompactItem {\n id: string;\n type: WhiteboardItemKind;\n author: WhiteboardAuthor;\n x?: number;\n y?: number;\n w?: number;\n h?: number;\n /** Clipped text content (sticky/text/shape labels; markdown/html: clipped SOURCE). */\n text?: string;\n shape?: WhiteboardShapeKind;\n /** Image file name, or the html widget's Title. */\n name?: string;\n from?: string | WhiteboardPoint | null;\n to?: string | WhiteboardPoint | null;\n points?: number;\n fontSize?: number;\n fontFamily?: WhiteboardFontFamily;\n bold?: boolean;\n color?: string;\n}\n\n/**\n * The coalesced scene delta fed into the live agent context (\"What the agent sees\").\n * Replace-current-state semantics: each entry is the item's CURRENT state, not an edit log.\n * When `reset` is true the `items` array replaces the agent's entire view of the board\n * (emitted after undo/redo/load, or when the journal no longer reaches the caller's token).\n */\nexport interface WhiteboardSceneDelta {\n op: 'scene-delta';\n seq: number;\n added: WhiteboardCompactItem[];\n moved: { id: string; x: number; y: number }[];\n updated: WhiteboardCompactItem[];\n removed: string[];\n reset?: boolean;\n items?: WhiteboardCompactItem[];\n /** The board's page list — `active: true` marks the page the item entries describe. */\n pages: WhiteboardScenePage[];\n summary: string;\n}\n\n/** Full compact scene snapshot (popover stats + delta-reset payloads). ACTIVE page only. */\nexport interface WhiteboardSceneSummary {\n op: 'scene-summary';\n seq: number;\n counts: {\n total: number;\n user: number;\n agent: number;\n byKind: Partial<Record<WhiteboardItemKind, number>>;\n };\n items: WhiteboardCompactItem[];\n /** The board's page list — `active: true` marks the page the item entries describe. */\n pages: WhiteboardScenePage[];\n summary: string;\n}\n\n/** Axis-aligned bounds of an item, in board coordinates. */\nexport interface WhiteboardBounds {\n X: number;\n Y: number;\n W: number;\n H: number;\n}\n\n/** Render-time default dimensions for items whose size is content-driven. */\nexport const WHITEBOARD_DEFAULTS = {\n StickyW: 172,\n StickyH: 96,\n ImageW: 198,\n ImageH: 134,\n TextW: 132,\n TextH: 18,\n ShapeMinH: 56,\n MarkdownW: 280,\n MarkdownMinH: 96,\n HtmlW: 360,\n HtmlH: 240\n} as const;\n\n/**\n * Whether an item kind is BOX-RESIZABLE by the user — i.e. the selection chrome shows the\n * 8 resize handles for it. Everything with a box model resizes: stickies, shapes, text\n * labels, images, markdown panels, HTML widgets and highlight regions. Ink strokes and\n * connectors are path-based and are not box-resizable.\n */\nexport function IsResizableKind(kind: WhiteboardItemKind): boolean {\n return kind === 'sticky' || kind === 'shape' || kind === 'text' || kind === 'image'\n || kind === 'highlight' || kind === 'markdown' || kind === 'html';\n}\n\n/**\n * The patch a COMMITTED resize gesture applies for an item kind, given the gesture's\n * final bounds:\n * - full-box kinds (`shape`, `highlight`, `html`) commit X / Y / W / H;\n * - content-driven-height kinds (`sticky`, `text`, `image`, `markdown`) commit\n * X / Y / W only — their rendered height stays content-driven (markdown's optional\n * `H` max-height cap is set by tools/agents, never by the drag gesture);\n * - non-resizable kinds (`ink`, `connector`) return `null` (nothing to commit).\n */\nexport function BuildResizeCommitPatch(kind: WhiteboardItemKind, bounds: WhiteboardBounds): WhiteboardItemPatch | null {\n if (kind === 'shape' || kind === 'highlight' || kind === 'html') {\n return { X: bounds.X, Y: bounds.Y, W: bounds.W, H: bounds.H };\n }\n if (kind === 'sticky' || kind === 'text' || kind === 'image' || kind === 'markdown') {\n return { X: bounds.X, Y: bounds.Y, W: bounds.W };\n }\n return null;\n}\n\n/** Truncate long item text for summary fragments. */\nfunction clip(text: string, max = 42): string {\n const t = (text || '').replace(/\\s+/g, ' ').trim();\n return t.length > max ? `${t.slice(0, max).trimEnd()}…` : t;\n}\n\ninterface JournalEntry {\n Seq: number;\n Op: WhiteboardChangeOp;\n ItemID: string;\n}\n\n/** Serialized shape of one page inside {@link WhiteboardStateJSON} (version 2+). */\ninterface WhiteboardPageJSON {\n id: string;\n name: string;\n items: WhiteboardItem[];\n /**\n * Who created the page (additive, v2-tolerant: absent in pre-authorship payloads and\n * treated as `'user'` on load). Drives the agent-page chip garnish.\n */\n author?: WhiteboardAuthor;\n}\n\n/**\n * Serialized shape produced by {@link WhiteboardState.ToJSON} — VERSION 2 (paged).\n * Version 1 (the legacy flat shape: `{ version: 1, seq, idCounter, zCounter, items }`)\n * is still accepted by {@link WhiteboardState.FromJSON} / {@link WhiteboardState.LoadFromJSON}\n * and rehydrates as a single page named \"Page 1\".\n */\ninterface WhiteboardStateJSON {\n version: 2;\n seq: number;\n idCounter: number;\n zCounter: number;\n /** Monotonic page-id/auto-name counter (never decremented, so names don't collide). */\n pageCounter: number;\n /** ID of the active page (always one of `pages`). */\n activePageId: string;\n /** The ordered page list (always at least one page). */\n pages: WhiteboardPageJSON[];\n}\n\n/** Internal live record of one page (the active page's map backs `this.items`). */\ninterface PageRecord {\n ID: string;\n Name: string;\n /** Who created the page (drives the agent-page garnish; persisted). */\n Author: WhiteboardAuthor;\n Items: Map<string, WhiteboardItem>;\n}\n\n/**\n * The whiteboard engine: items + ordered render list, single selection, snapshot-based\n * undo/redo (one entry per user gesture or per agent tool call via {@link RunBatch}),\n * change journal + coalesced scene deltas, JSON persistence, and the cancelable\n * BEFORE / AFTER mutation event surface.\n *\n * ## Before / after events\n *\n * Every targeted mutation raises a cancelable BEFORE event and, when it applies, a\n * matching AFTER event:\n *\n * | Mutation | Before (cancelable) | After |\n * |---|---|---|\n * | {@link AddItem} (incl. {@link Highlight}, {@link DuplicateItem}) | {@link ItemAdding$} | {@link ItemAdded$} |\n * | {@link UpdateItem} / {@link MoveItem} / {@link BringToFront} / {@link SendToBack} | {@link ItemUpdating$} | {@link ItemUpdated$} |\n * | {@link UpdateItem} touching content fields (Text / Label / Sub / Markdown / Html / Title) | {@link ContentChanging$} (after ItemUpdating$) | {@link ContentChanged$} |\n * | {@link RemoveItem} | {@link ItemRemoving$} | {@link ItemRemoved$} |\n * | {@link AddPage} | {@link PageAdding$} | {@link PageAdded$} |\n * | {@link SwitchPage} | {@link PageSwitching$} | {@link PageSwitched$} |\n * | {@link RenamePage} | {@link PageRenaming$} | {@link PageRenamed$} |\n * | {@link RemovePage} | {@link PageRemoving$} | {@link PageRemoved$} |\n * | {@link Select} (and implicit clears) | — | {@link SelectionChanged$} |\n * | {@link Clear} | — | {@link BoardCleared$} |\n * | {@link LoadFromJSON} | — | {@link BoardLoaded$} |\n *\n * Handlers run synchronously during the emit; setting `Cancel = true` on the event args\n * aborts the mutation (the caller sees `null` / `false`) with no undo snapshot, journal\n * entry or {@link Changed$} emission. These events layer ALONGSIDE the existing\n * {@link Changed$} / journal / perception machinery — they never replace it. Undo / redo\n * whole-scene replacements are NOT item mutations and only surface through\n * {@link Changed$} as `'replace'` ops.\n */\nexport class WhiteboardState {\n private static readonly undoMax = 100;\n private static readonly journalMax = 1000;\n\n /**\n * The ordered page list. A fresh board has one page named \"Page 1\". Every item\n * operation reads/writes the ACTIVE page's map through the `items` accessor below, so\n * the entire pre-pages mutation surface is page-scoped without per-call changes.\n */\n private pages: PageRecord[] = [{ ID: 'page-1', Name: 'Page 1', Author: 'user', Items: new Map<string, WhiteboardItem>() }];\n /** ID of the active page (always present in {@link pages}). */\n private activePageId = 'page-1';\n /** Monotonic page counter — mints page IDs and the \"Page N\" auto-names. */\n private pageCounter = 1;\n\n /** The ACTIVE page's item map (accessor keeps all item mutations page-scoped). */\n private get items(): Map<string, WhiteboardItem> {\n return this.activePage.Items;\n }\n private set items(value: Map<string, WhiteboardItem>) {\n this.activePage.Items = value;\n }\n\n /** The active page record (defensive fallback to the first page — never undefined). */\n private get activePage(): PageRecord {\n return this.pages.find((p) => UUIDsEqual(p.ID, this.activePageId)) ?? this.pages[0];\n }\n\n private idCounter = 0;\n private zCounter = 0;\n private seq = 0;\n\n private undoStack: WhiteboardStateJSON[] = [];\n private redoStack: WhiteboardStateJSON[] = [];\n private batchDepth = 0;\n\n private journal: JournalEntry[] = [];\n /** Per-item snapshot of \"did this item exist at journal-trim time\" is not needed because\n * trimming forces reset semantics for tokens older than the journal window. */\n private journalTrimmedBeforeSeq = 0;\n\n private changed = new Subject<WhiteboardChange>();\n /** Fires after every mutation (including undo/redo `'replace'` events). */\n public readonly Changed$: Observable<WhiteboardChange> = this.changed.asObservable();\n\n private itemAdding = new Subject<WhiteboardItemAddingEventArgs>();\n /**\n * Cancelable BEFORE event of {@link AddItem} (and {@link Highlight} /\n * {@link DuplicateItem}, which add through it). Set `Cancel = true` synchronously to\n * veto the add — {@link AddItem} then returns `null` and nothing changes.\n */\n public readonly ItemAdding$: Observable<WhiteboardItemAddingEventArgs> = this.itemAdding.asObservable();\n\n private itemAdded = new Subject<WhiteboardItemAddedEventArgs>();\n /** AFTER event: an item was added (fires once per applied {@link AddItem}). */\n public readonly ItemAdded$: Observable<WhiteboardItemAddedEventArgs> = this.itemAdded.asObservable();\n\n private itemUpdating = new Subject<WhiteboardItemUpdatingEventArgs>();\n /**\n * Cancelable BEFORE event of {@link UpdateItem} (`Operation: 'update'`),\n * {@link MoveItem} (`'move'`) and {@link BringToFront} / {@link SendToBack}\n * (`'reorder'`). Set `Cancel = true` synchronously to veto — the mutator returns `false`.\n */\n public readonly ItemUpdating$: Observable<WhiteboardItemUpdatingEventArgs> = this.itemUpdating.asObservable();\n\n private itemUpdated = new Subject<WhiteboardItemUpdatedEventArgs>();\n /** AFTER event: an item changed (patch applied / moved / z-reordered). */\n public readonly ItemUpdated$: Observable<WhiteboardItemUpdatedEventArgs> = this.itemUpdated.asObservable();\n\n private itemRemoving = new Subject<WhiteboardItemRemovingEventArgs>();\n /**\n * Cancelable BEFORE event of {@link RemoveItem}. Set `Cancel = true` synchronously to\n * keep the item — {@link RemoveItem} then returns `false` and nothing changes.\n */\n public readonly ItemRemoving$: Observable<WhiteboardItemRemovingEventArgs> = this.itemRemoving.asObservable();\n\n private itemRemoved = new Subject<WhiteboardItemRemovedEventArgs>();\n /** AFTER event: an item was removed from the board. */\n public readonly ItemRemoved$: Observable<WhiteboardItemRemovedEventArgs> = this.itemRemoved.asObservable();\n\n private contentChanging = new Subject<WhiteboardContentChangingEventArgs>();\n /**\n * Cancelable BEFORE event raised — in addition to {@link ItemUpdating$} — when an\n * {@link UpdateItem} patch touches CONTENT fields (Text / Label / Sub / Markdown /\n * Html / Title). The dedicated hook for content governance: set `Cancel = true`\n * synchronously to veto the whole update.\n */\n public readonly ContentChanging$: Observable<WhiteboardContentChangingEventArgs> = this.contentChanging.asObservable();\n\n private contentChanged = new Subject<WhiteboardContentChangedEventArgs>();\n /** AFTER event: an item's content fields changed (markdown / html / text edits). */\n public readonly ContentChanged$: Observable<WhiteboardContentChangedEventArgs> = this.contentChanged.asObservable();\n\n private selectionChanged = new Subject<WhiteboardSelectionChangedEventArgs>();\n /**\n * AFTER event: the single selection changed — via {@link Select} or implicitly (the\n * selected item was removed / dropped by a restore). Selection is transient UI state,\n * so this is a notification only (never cancelable, never journaled).\n */\n public readonly SelectionChanged$: Observable<WhiteboardSelectionChangedEventArgs> = this.selectionChanged.asObservable();\n\n private boardCleared = new Subject<WhiteboardBoardClearedEventArgs>();\n /** AFTER event: {@link Clear} removed everything from the board (one undo step). */\n public readonly BoardCleared$: Observable<WhiteboardBoardClearedEventArgs> = this.boardCleared.asObservable();\n\n private boardLoaded = new Subject<WhiteboardBoardLoadedEventArgs>();\n /** AFTER event: {@link LoadFromJSON} rehydrated a persisted board into this instance. */\n public readonly BoardLoaded$: Observable<WhiteboardBoardLoadedEventArgs> = this.boardLoaded.asObservable();\n\n private pageAdding = new Subject<WhiteboardPageAddingEventArgs>();\n /**\n * Cancelable BEFORE event of {@link AddPage}. Set `Cancel = true` synchronously to\n * veto — {@link AddPage} then returns `null` and nothing changes.\n */\n public readonly PageAdding$: Observable<WhiteboardPageAddingEventArgs> = this.pageAdding.asObservable();\n\n private pageAdded = new Subject<WhiteboardPageAddedEventArgs>();\n /** AFTER event: a page was added (and became the active page). */\n public readonly PageAdded$: Observable<WhiteboardPageAddedEventArgs> = this.pageAdded.asObservable();\n\n private pageSwitching = new Subject<WhiteboardPageSwitchingEventArgs>();\n /**\n * Cancelable BEFORE event of {@link SwitchPage}. Set `Cancel = true` synchronously to\n * stay on the current page — {@link SwitchPage} then returns `false`.\n */\n public readonly PageSwitching$: Observable<WhiteboardPageSwitchingEventArgs> = this.pageSwitching.asObservable();\n\n private pageSwitched = new Subject<WhiteboardPageSwitchedEventArgs>();\n /** AFTER event: the active page changed via {@link SwitchPage}. */\n public readonly PageSwitched$: Observable<WhiteboardPageSwitchedEventArgs> = this.pageSwitched.asObservable();\n\n private pageRenaming = new Subject<WhiteboardPageRenamingEventArgs>();\n /**\n * Cancelable BEFORE event of {@link RenamePage}. Handlers may rewrite `NewName`; set\n * `Cancel = true` synchronously to veto — {@link RenamePage} then returns `false`.\n */\n public readonly PageRenaming$: Observable<WhiteboardPageRenamingEventArgs> = this.pageRenaming.asObservable();\n\n private pageRenamed = new Subject<WhiteboardPageRenamedEventArgs>();\n /** AFTER event: a page was renamed. */\n public readonly PageRenamed$: Observable<WhiteboardPageRenamedEventArgs> = this.pageRenamed.asObservable();\n\n private pageRemoving = new Subject<WhiteboardPageRemovingEventArgs>();\n /**\n * Cancelable BEFORE event of {@link RemovePage} (never raised for the guarded\n * last-page case). Set `Cancel = true` synchronously to keep the page.\n */\n public readonly PageRemoving$: Observable<WhiteboardPageRemovingEventArgs> = this.pageRemoving.asObservable();\n\n private pageRemoved = new Subject<WhiteboardPageRemovedEventArgs>();\n /** AFTER event: a page (and all of its items) was removed from the board. */\n public readonly PageRemoved$: Observable<WhiteboardPageRemovedEventArgs> = this.pageRemoved.asObservable();\n\n /**\n * The MULTI-selection, in selection order (last entry is the primary selection).\n * Selection is volatile UI state — never journaled, never undoable, never persisted,\n * and cleared on page switches and whole-scene restores.\n */\n private selectedIds: string[] = [];\n\n /**\n * The PRIMARY selected item's ID (the most recently selected member of the\n * multi-selection), or null when nothing is selected. Selection is UI state — not\n * persisted. For the full multi-selection see {@link SelectedIDs}.\n */\n public get SelectedID(): string | null {\n return this.selectedIds.length > 0 ? this.selectedIds[this.selectedIds.length - 1] : null;\n }\n\n /** All selected item IDs in selection order (last = primary). Returns a copy. */\n public get SelectedIDs(): string[] {\n return [...this.selectedIds];\n }\n\n // ────────────────────────────────────────────── reads\n\n /** All items on the ACTIVE page in render order (ascending Z). */\n public get Items(): WhiteboardItem[] {\n return Array.from(this.items.values()).sort((a, b) => a.Z - b.Z);\n }\n\n /** The ordered page list (read-only snapshots — see {@link WhiteboardPageInfo}). */\n public get Pages(): WhiteboardPageInfo[] {\n return this.pages.map((p) => this.pageInfo(p));\n }\n\n /** ID of the active page (every item operation targets this page). */\n public get ActivePageID(): string {\n return this.activePage.ID;\n }\n\n /** Display name of the active page. */\n public get ActivePageName(): string {\n return this.activePage.Name;\n }\n\n /** Total item count summed across ALL pages (the active-page count is {@link ElementCount}). */\n public get TotalItemCount(): number {\n return this.pages.reduce((n, p) => n + p.Items.size, 0);\n }\n\n /**\n * Tolerant page lookup: by exact ID first, then by case-insensitive, trimmed name\n * (first match wins on duplicate names). Returns `undefined` when nothing matches.\n */\n public FindPage(idOrName: string): WhiteboardPageInfo | undefined {\n const page = this.resolvePage(idOrName);\n return page ? this.pageInfo(page) : undefined;\n }\n\n /** Current sequence number — use as the `sinceToken` for the next {@link BuildSceneDelta}. */\n public get CurrentSeq(): number {\n return this.seq;\n }\n\n /** Look up one ACTIVE-page item by ID (items on other pages are not visible here). */\n public GetItem(id: string): WhiteboardItem | undefined {\n return this.items.get(id);\n }\n\n /** ACTIVE-page \"elements\" as the status footer reports them (transient highlights excluded). */\n public get ElementCount(): number {\n return this.Items.filter((i) => i.Kind !== 'highlight').length;\n }\n\n /** Active-page elements by author (highlights excluded, same basis as {@link ElementCount}). */\n public CountByAuthor(author: WhiteboardAuthor): number {\n return this.Items.filter((i) => i.Kind !== 'highlight' && i.Author === author).length;\n }\n\n public get CanUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n public get CanRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n // ────────────────────────────────────────────── geometry\n\n /** Axis-aligned bounds for any item (estimates for content-sized kinds). */\n public ItemBounds(item: WhiteboardItem): WhiteboardBounds {\n switch (item.Kind) {\n case 'sticky':\n return { X: item.X, Y: item.Y, W: item.W ?? WHITEBOARD_DEFAULTS.StickyW, H: WHITEBOARD_DEFAULTS.StickyH };\n case 'shape':\n return { X: item.X, Y: item.Y, W: item.W, H: item.H };\n case 'text': {\n // estimate scales with the chosen font size (the CSS default renders ~12px);\n // an explicit wrap width (item.W) wins over the single-line estimate\n const scale = item.FontSize ? item.FontSize / 12 : 1;\n return {\n X: item.X,\n Y: item.Y,\n W: item.W ?? Math.round(WHITEBOARD_DEFAULTS.TextW * scale),\n H: Math.round(WHITEBOARD_DEFAULTS.TextH * scale)\n };\n }\n case 'image':\n return { X: item.X, Y: item.Y, W: item.W ?? WHITEBOARD_DEFAULTS.ImageW, H: WHITEBOARD_DEFAULTS.ImageH };\n case 'highlight':\n return { X: item.X, Y: item.Y, W: item.W, H: item.H };\n case 'markdown':\n // content-driven height: an explicit max (H) wins, otherwise estimate from line count\n return { X: item.X, Y: item.Y, W: item.W, H: item.H ?? WhiteboardState.markdownHeightEstimate(item.Markdown) };\n case 'html':\n return { X: item.X, Y: item.Y, W: item.W, H: item.H };\n case 'ink': {\n return WhiteboardState.pointsBounds(item.Points, item.StrokeWidth);\n }\n case 'connector': {\n const from = this.ResolveEndpoint(item, 'from');\n const to = this.ResolveEndpoint(item, 'to');\n return WhiteboardState.pointsBounds([from, to], 2);\n }\n }\n }\n\n /** Rough rendered height of a markdown panel (line count · line height + card padding). */\n private static markdownHeightEstimate(markdown: string): number {\n const lines = (markdown || '').split('\\n').length;\n return Math.max(WHITEBOARD_DEFAULTS.MarkdownMinH, Math.min(520, 44 + lines * 19));\n }\n\n private static pointsBounds(points: WhiteboardPoint[], pad: number): WhiteboardBounds {\n if (points.length === 0) {\n return { X: 0, Y: 0, W: 0, H: 0 };\n }\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const p of points) {\n minX = Math.min(minX, p.X);\n minY = Math.min(minY, p.Y);\n maxX = Math.max(maxX, p.X);\n maxY = Math.max(maxY, p.Y);\n }\n return { X: minX - pad, Y: minY - pad, W: maxX - minX + pad * 2, H: maxY - minY + pad * 2 };\n }\n\n /** Bounding box of all items (null when the board is empty). Powers fit-to-content + minimap. */\n public ContentBounds(): WhiteboardBounds | null {\n const all = this.Items;\n if (all.length === 0) {\n return null;\n }\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const item of all) {\n const b = this.ItemBounds(item);\n minX = Math.min(minX, b.X);\n minY = Math.min(minY, b.Y);\n maxX = Math.max(maxX, b.X + b.W);\n maxY = Math.max(maxY, b.Y + b.H);\n }\n return { X: minX, Y: minY, W: maxX - minX, H: maxY - minY };\n }\n\n /**\n * Resolve one connector endpoint: anchored to the referenced item's bounds-center when the\n * item still exists, otherwise the absolute fallback point (floating endpoint).\n */\n public ResolveEndpoint(conn: WhiteboardConnectorItem, end: 'from' | 'to'): WhiteboardPoint {\n const refId = end === 'from' ? conn.FromItemID : conn.ToItemID;\n const fallback = end === 'from' ? conn.FromPoint : conn.ToPoint;\n if (refId) {\n const target = this.items.get(refId);\n if (target) {\n const b = this.ItemBounds(target);\n return { X: b.X + b.W / 2, Y: b.Y + b.H / 2 };\n }\n }\n return fallback ?? { X: 0, Y: 0 };\n }\n\n // ────────────────────────────────────────────── selection\n\n /**\n * Set (or clear) the selection to a SINGLE item. Unknown IDs clear the selection.\n * Fires {@link SelectionChanged$} when the effective selection actually changes.\n */\n public Select(id: string | null): void {\n this.applySelection(id != null && this.items.has(id) ? [id] : []);\n }\n\n /**\n * Toggle one item's membership in the multi-selection WITHOUT clearing the rest —\n * the shift-click semantics. A newly added item becomes the primary selection\n * ({@link SelectedID}); unknown IDs are a no-op.\n */\n public ToggleSelect(id: string): void {\n if (!this.items.has(id)) {\n return;\n }\n this.applySelection(this.selectedIds.includes(id)\n ? this.selectedIds.filter((s) => s !== id)\n : [...this.selectedIds, id]);\n }\n\n /**\n * Replace the selection with a set of items (the marquee result). Unknown IDs are\n * dropped and duplicates collapse to their first occurrence; order is preserved\n * (the last surviving entry becomes the primary selection). An empty / fully-unknown\n * list clears the selection.\n */\n public SelectMany(ids: string[]): void {\n const seen = new Set<string>();\n const next: string[] = [];\n for (const id of ids) {\n if (id != null && this.items.has(id) && !seen.has(id)) {\n seen.add(id);\n next.push(id);\n }\n }\n this.applySelection(next);\n }\n\n /** Whether an item is part of the current (single or multi) selection. */\n public IsItemSelected(id: string): boolean {\n return this.selectedIds.includes(id);\n }\n\n /**\n * All ACTIVE-page items whose axis-aligned bounds intersect the given rectangle —\n * the marquee (rubber-band) hit test, in render order. Transient highlight regions\n * are excluded: they are \"pointing\" chrome dismissed by click, never selected.\n * Edge-touching items (zero overlap area) do NOT count as intersecting.\n */\n public ItemsIntersecting(rect: WhiteboardBounds): WhiteboardItem[] {\n return this.Items.filter((item) => {\n if (item.Kind === 'highlight') {\n return false;\n }\n const b = this.ItemBounds(item);\n return b.X < rect.X + rect.W && b.X + b.W > rect.X\n && b.Y < rect.Y + rect.H && b.Y + b.H > rect.Y;\n });\n }\n\n /** Apply a SINGLE-or-clear selection change (legacy internal path). */\n protected changeSelection(next: string | null): void {\n this.applySelection(next != null ? [next] : []);\n }\n\n /** Swap the multi-selection and fire {@link SelectionChanged$} when it differs. */\n protected applySelection(next: string[]): void {\n const current = this.selectedIds;\n if (next.length === current.length && next.every((id, i) => id === current[i])) {\n return;\n }\n const previous = this.SelectedID;\n this.selectedIds = next;\n this.selectionChanged.next({ SelectedID: this.SelectedID, PreviousID: previous, SelectedIDs: [...next] });\n }\n\n // ────────────────────────────────────────────── mutations\n\n /**\n * Add an item; the engine stamps ID, Z and Author and emits one change.\n *\n * Raises the cancelable {@link ItemAdding$} BEFORE event first — when a handler\n * cancels, nothing changes and `null` is returned. On success the stamped item is\n * returned and {@link ItemAdded$} fires after the journal/{@link Changed$} emission.\n */\n public AddItem(input: WhiteboardItemInput, author: WhiteboardAuthor): WhiteboardItem | null {\n const adding: WhiteboardItemAddingEventArgs = { Input: input, Author: author, Cancel: false };\n this.itemAdding.next(adding);\n if (adding.Cancel) {\n return null;\n }\n this.beforeMutate();\n const item = { ...adding.Input, ID: this.nextId(adding.Input.Kind), Z: ++this.zCounter, Author: author } as WhiteboardItem;\n this.items.set(item.ID, item);\n this.record('add', item.ID, author, `added ${WhiteboardState.describe(item)}`);\n this.itemAdded.next({ Item: item, Author: author });\n return item;\n }\n\n /**\n * Patch an item's mutable fields. Returns false when the ID is unknown — or when a\n * handler of the cancelable {@link ItemUpdating$} BEFORE event (or, for patches that\n * touch content fields, the cancelable {@link ContentChanging$} event) vetoed the\n * change. On success {@link ItemUpdated$} — and {@link ContentChanged$} for content\n * patches — fires after the journal/{@link Changed$} emission.\n */\n public UpdateItem(id: string, patch: WhiteboardItemPatch, author: WhiteboardAuthor): boolean {\n const item = this.items.get(id);\n if (!item) {\n return false;\n }\n const updating: WhiteboardItemUpdatingEventArgs = { Item: item, Operation: 'update', Patch: patch, Author: author, Cancel: false };\n this.itemUpdating.next(updating);\n if (updating.Cancel) {\n return false;\n }\n const effective = updating.Patch ?? patch;\n const isContent = WhiteboardState.isContentPatch(effective);\n if (isContent) {\n const changing: WhiteboardContentChangingEventArgs = { Item: item, Patch: effective, Author: author, Cancel: false };\n this.contentChanging.next(changing);\n if (changing.Cancel) {\n return false;\n }\n }\n this.beforeMutate();\n const target = item as WhiteboardItemBase & WhiteboardItemPatch;\n for (const [key, value] of Object.entries(effective)) {\n if (value !== undefined) {\n (target as Record<string, typeof value>)[key] = value;\n }\n }\n this.record('update', id, author, `updated ${WhiteboardState.describe(item)}`);\n this.itemUpdated.next({ Item: item, Operation: 'update', Author: author });\n if (isContent) {\n this.contentChanged.next({ Item: item, Patch: effective, Author: author });\n }\n return true;\n }\n\n /** Whether a patch touches CONTENT fields (drives the ContentChanging/Changed pair). */\n protected static isContentPatch(patch: WhiteboardItemPatch): boolean {\n return patch.Text !== undefined || patch.Label !== undefined || patch.Sub !== undefined\n || patch.Markdown !== undefined || patch.Html !== undefined || patch.Title !== undefined;\n }\n\n /**\n * Move an item to an absolute board position. Positioned kinds move their origin; ink\n * strokes translate every point; connectors translate their floating endpoints.\n *\n * Raises the cancelable {@link ItemUpdating$} BEFORE event (`Operation: 'move'`,\n * `Position` = the requested top-left) — returns false when vetoed or the ID is\n * unknown; fires {@link ItemUpdated$} after an applied move.\n */\n public MoveItem(id: string, x: number, y: number, author: WhiteboardAuthor): boolean {\n const item = this.items.get(id);\n if (!item) {\n return false;\n }\n const moving: WhiteboardItemUpdatingEventArgs = { Item: item, Operation: 'move', Position: { X: x, Y: y }, Author: author, Cancel: false };\n this.itemUpdating.next(moving);\n if (moving.Cancel) {\n return false;\n }\n this.beforeMutate();\n const bounds = this.ItemBounds(item);\n const dx = x - bounds.X;\n const dy = y - bounds.Y;\n if (item.Kind === 'ink') {\n item.Points = item.Points.map((p) => ({ X: p.X + dx, Y: p.Y + dy }));\n }\n else if (item.Kind === 'connector') {\n if (item.FromPoint) {\n item.FromPoint = { X: item.FromPoint.X + dx, Y: item.FromPoint.Y + dy };\n }\n if (item.ToPoint) {\n item.ToPoint = { X: item.ToPoint.X + dx, Y: item.ToPoint.Y + dy };\n }\n }\n else {\n item.X = x;\n item.Y = y;\n }\n this.record('move', id, author, `moved ${WhiteboardState.describe(item)}`);\n this.itemUpdated.next({ Item: item, Operation: 'move', Author: author });\n return true;\n }\n\n /**\n * Remove an item. Connectors that referenced it survive: their endpoint freezes to the\n * removed item's last center (the floating-endpoint fallback).\n *\n * Raises the cancelable {@link ItemRemoving$} BEFORE event — returns false when vetoed\n * or the ID is unknown; fires {@link ItemRemoved$} after an applied removal.\n */\n public RemoveItem(id: string, author: WhiteboardAuthor): boolean {\n const item = this.items.get(id);\n if (!item) {\n return false;\n }\n const removing: WhiteboardItemRemovingEventArgs = { Item: item, Author: author, Cancel: false };\n this.itemRemoving.next(removing);\n if (removing.Cancel) {\n return false;\n }\n this.beforeMutate();\n // Freeze any connector endpoints anchored to the item being removed.\n const center = (() => {\n const b = this.ItemBounds(item);\n return { X: b.X + b.W / 2, Y: b.Y + b.H / 2 };\n })();\n for (const other of this.items.values()) {\n if (other.Kind === 'connector') {\n if (other.FromItemID === id) {\n other.FromItemID = null;\n other.FromPoint = { ...center };\n }\n if (other.ToItemID === id) {\n other.ToItemID = null;\n other.ToPoint = { ...center };\n }\n }\n }\n this.items.delete(id);\n if (this.selectedIds.includes(id)) {\n this.applySelection(this.selectedIds.filter((s) => s !== id));\n }\n this.record('remove', id, author, `removed ${WhiteboardState.describe(item)}`);\n this.itemRemoved.next({ Item: item, Author: author });\n return true;\n }\n\n /**\n * Duplicate an item: a DEEP clone (ink points included) with a fresh engine-stamped\n * identity, offset +16/+16 from the source so the copy is visibly distinct. Connectors\n * (which reference other items) and transient highlights cannot be duplicated — returns\n * `null` without mutating. The clone lands through {@link AddItem}, so it journals as a\n * normal `'add'`, is one undo step, and raises the {@link ItemAdding$} /\n * {@link ItemAdded$} pair (a canceled add also returns `null`).\n */\n public DuplicateItem(id: string, author: WhiteboardAuthor): WhiteboardItem | null {\n const source = this.items.get(id);\n if (!source || source.Kind === 'connector' || source.Kind === 'highlight') {\n return null;\n }\n const { ID: _id, Z: _z, Author: _author, ...rest } = JSON.parse(JSON.stringify(source)) as WhiteboardItem;\n const input = rest as WhiteboardItemInput;\n if (input.Kind === 'ink') {\n input.Points = input.Points.map((p) => ({ X: p.X + 16, Y: p.Y + 16 }));\n }\n else if (input.Kind !== 'connector') {\n input.X += 16;\n input.Y += 16;\n }\n return this.AddItem(input, author);\n }\n\n /**\n * Raise an item above everything else. Follows the engine's existing Z handling:\n * `++zCounter` is by construction greater than every assigned Z (max + 1), exactly how\n * {@link AddItem} stamps new items. Journals as an `'update'`.\n *\n * Raises the cancelable {@link ItemUpdating$} BEFORE event (`Operation: 'reorder'`) —\n * returns false when vetoed or the ID is unknown; fires {@link ItemUpdated$} after.\n */\n public BringToFront(id: string, author: WhiteboardAuthor): boolean {\n const item = this.items.get(id);\n if (!item) {\n return false;\n }\n if (!this.raiseReorder(item, author)) {\n return false;\n }\n this.beforeMutate();\n item.Z = ++this.zCounter;\n this.record('update', id, author, `brought ${WhiteboardState.describe(item)} to the front`);\n this.itemUpdated.next({ Item: item, Operation: 'reorder', Author: author });\n return true;\n }\n\n /**\n * Drop an item below everything else (current min Z − 1). Journals as an `'update'`.\n *\n * Raises the cancelable {@link ItemUpdating$} BEFORE event (`Operation: 'reorder'`) —\n * returns false when vetoed or the ID is unknown; fires {@link ItemUpdated$} after.\n */\n public SendToBack(id: string, author: WhiteboardAuthor): boolean {\n const item = this.items.get(id);\n if (!item) {\n return false;\n }\n if (!this.raiseReorder(item, author)) {\n return false;\n }\n this.beforeMutate();\n let minZ = item.Z;\n for (const other of this.items.values()) {\n minZ = Math.min(minZ, other.Z);\n }\n item.Z = minZ - 1;\n this.record('update', id, author, `sent ${WhiteboardState.describe(item)} to the back`);\n this.itemUpdated.next({ Item: item, Operation: 'reorder', Author: author });\n return true;\n }\n\n /** Raise the cancelable `'reorder'` BEFORE event; returns false when a handler vetoed. */\n protected raiseReorder(item: WhiteboardItem, author: WhiteboardAuthor): boolean {\n const reordering: WhiteboardItemUpdatingEventArgs = { Item: item, Operation: 'reorder', Author: author, Cancel: false };\n this.itemUpdating.next(reordering);\n return !reordering.Cancel;\n }\n\n /**\n * Convenience: add a pulsing highlight region (agent \"pointing without touching\").\n * Adds through {@link AddItem}, so the {@link ItemAdding$} / {@link ItemAdded$} pair\n * fires — returns `null` when a handler canceled the add.\n */\n public Highlight(x: number, y: number, w: number, h: number, label: string | undefined, author: WhiteboardAuthor): WhiteboardHighlightItem | null {\n return this.AddItem({ Kind: 'highlight', X: x, Y: y, W: w, H: h, Label: label }, author) as WhiteboardHighlightItem | null;\n }\n\n /**\n * Remove EVERYTHING from the ACTIVE page as ONE undoable operation (other pages are\n * untouched). Journals a single `'replace'` op (perception consumers re-read the\n * now-empty scene) and fires {@link BoardCleared$}. Clears the selection (firing\n * {@link SelectionChanged$} when one existed). Returns false when the active page was\n * already empty.\n */\n public Clear(author: WhiteboardAuthor = 'user'): boolean {\n if (this.items.size === 0) {\n return false;\n }\n const count = this.items.size;\n this.beforeMutate();\n this.items = new Map<string, WhiteboardItem>();\n this.changeSelection(null);\n this.record('replace', '', author, 'cleared the board');\n this.boardCleared.next({ Author: author, ItemCount: count });\n return true;\n }\n\n /**\n * Move EVERY selected item by the same delta as ONE undo step (the multi-select group\n * drag). Internally one {@link RunBatch} of per-item {@link MoveItem} calls, so each\n * member still raises its own cancelable `'move'` BEFORE event (a veto skips just that\n * member) and journals normally — but a single Undo reverts the whole group move.\n * Returns how many items actually moved (0 when nothing is selected or the delta is 0).\n */\n public MoveSelectedBy(dx: number, dy: number, author: WhiteboardAuthor): number {\n const ids = this.selectedIds.filter((id) => this.items.has(id));\n if (ids.length === 0 || (dx === 0 && dy === 0)) {\n return 0;\n }\n return this.RunBatch(() => {\n // capture every member's bounds BEFORE any member moves, so anchored-connector\n // bounds (which follow their endpoints) don't skew later members' targets\n const targets = ids\n .map((id) => {\n const item = this.items.get(id);\n return item ? { id, bounds: this.ItemBounds(item) } : null;\n })\n .filter((t): t is { id: string; bounds: WhiteboardBounds } => t !== null);\n let moved = 0;\n for (const t of targets) {\n if (this.MoveItem(t.id, t.bounds.X + dx, t.bounds.Y + dy, author)) {\n moved++;\n }\n }\n return moved;\n });\n }\n\n /**\n * Remove EVERY selected item as ONE undo step (the multi-select Delete key). One\n * {@link RunBatch} of per-item {@link RemoveItem} calls — each member still raises its\n * cancelable {@link ItemRemoving$} BEFORE event (a veto keeps just that member), and a\n * single Undo restores the whole group. The selection empties as items are removed.\n * Returns how many items were actually removed.\n */\n public RemoveSelected(author: WhiteboardAuthor): number {\n const ids = this.selectedIds.filter((id) => this.items.has(id));\n if (ids.length === 0) {\n return 0;\n }\n return this.RunBatch(() => {\n let removed = 0;\n for (const id of ids) {\n if (this.RemoveItem(id, author)) {\n removed++;\n }\n }\n return removed;\n });\n }\n\n // ────────────────────────────────────────────── pages\n\n /** Project a live page record to its public read-only descriptor. */\n protected pageInfo(page: PageRecord): WhiteboardPageInfo {\n return { ID: page.ID, Name: page.Name, ItemCount: page.Items.size, Active: UUIDsEqual(page.ID, this.activePageId), Author: page.Author };\n }\n\n /** Resolve a page by exact ID first, then case-insensitive trimmed name. */\n private resolvePage(idOrName: string): PageRecord | undefined {\n const key = (idOrName ?? '').trim();\n if (key.length === 0) {\n return undefined;\n }\n return this.pages.find((p) => UUIDsEqual(p.ID, key))\n ?? this.pages.find((p) => p.Name.trim().toLowerCase() === key.toLowerCase());\n }\n\n /**\n * Add a new page and SWITCH to it. `name` is trimmed; when omitted (or blank) the page\n * auto-names itself \"Page N\" from the monotonic page counter, so auto-names never\n * repeat even after removals.\n *\n * Raises the cancelable {@link PageAdding$} BEFORE event (handlers may rewrite the\n * name) — returns `null` when vetoed; fires {@link PageAdded$} after. One undoable\n * step; journals a `'replace'` op (the agent's visible scene swaps to the new, empty\n * page), so perception consumers re-read the scene.\n */\n public AddPage(name?: string, author: WhiteboardAuthor = 'user'): WhiteboardPageInfo | null {\n const autoName = `Page ${this.pageCounter + 1}`;\n const requested = (name ?? '').trim();\n const adding: WhiteboardPageAddingEventArgs = { Name: requested.length > 0 ? requested : autoName, Author: author, Cancel: false };\n this.pageAdding.next(adding);\n if (adding.Cancel) {\n return null;\n }\n this.beforeMutate();\n this.pageCounter++;\n const page: PageRecord = {\n ID: `page-${this.pageCounter}`,\n Name: (adding.Name ?? '').trim() || autoName,\n Author: author,\n Items: new Map<string, WhiteboardItem>()\n };\n this.pages.push(page);\n this.activePageId = page.ID;\n this.changeSelection(null);\n this.record('replace', '', author, `added page \"${page.Name}\"`);\n const info = this.pageInfo(page);\n this.pageAdded.next({ Page: info, Author: author });\n return info;\n }\n\n /**\n * Make another page the active page. Tolerant lookup: exact ID first, then\n * case-insensitive name (see {@link FindPage}). Switching to the already-active page\n * is a successful no-op (no events, no journal entry).\n *\n * Raises the cancelable {@link PageSwitching$} BEFORE event — returns `false` when\n * vetoed or the page is unknown; fires {@link PageSwitched$} after. Journals a\n * `'replace'` op (the visible scene swaps wholesale) but deliberately pushes NO undo\n * snapshot — switching is navigation, not a content mutation.\n */\n public SwitchPage(idOrName: string, author: WhiteboardAuthor = 'user'): boolean {\n const target = this.resolvePage(idOrName);\n if (!target) {\n return false;\n }\n if (UUIDsEqual(target.ID, this.activePageId)) {\n return true; // already there — successful no-op\n }\n const from = this.pageInfo(this.activePage);\n const switching: WhiteboardPageSwitchingEventArgs = { FromPage: from, ToPage: this.pageInfo(target), Author: author, Cancel: false };\n this.pageSwitching.next(switching);\n if (switching.Cancel) {\n return false;\n }\n this.activePageId = target.ID;\n this.changeSelection(null);\n this.record('replace', '', author, `switched to page \"${target.Name}\"`);\n this.pageSwitched.next({ FromPage: from, ToPage: this.pageInfo(target), Author: author });\n return true;\n }\n\n /**\n * Rename a page (tolerant lookup, same as {@link SwitchPage}). The new name is\n * trimmed; an empty result returns `false`. Renaming to the current name is a\n * successful no-op (no events, no journal entry).\n *\n * Raises the cancelable {@link PageRenaming$} BEFORE event (handlers may rewrite\n * `NewName`) — returns `false` when vetoed; fires {@link PageRenamed$} after. One\n * undoable step; journals a `'replace'` op so the agent's page list stays current.\n */\n public RenamePage(idOrName: string, newName: string, author: WhiteboardAuthor = 'user'): boolean {\n const target = this.resolvePage(idOrName);\n const requested = (newName ?? '').trim();\n if (!target || requested.length === 0) {\n return false;\n }\n if (target.Name === requested) {\n return true; // nothing to do\n }\n const renaming: WhiteboardPageRenamingEventArgs = { Page: this.pageInfo(target), NewName: requested, Author: author, Cancel: false };\n this.pageRenaming.next(renaming);\n if (renaming.Cancel) {\n return false;\n }\n const effective = (renaming.NewName ?? '').trim();\n if (effective.length === 0) {\n return false; // a handler emptied the name — treat as an abort\n }\n this.beforeMutate();\n const oldName = target.Name;\n target.Name = effective;\n this.record('replace', '', author, `renamed page \"${oldName}\" to \"${target.Name}\"`);\n this.pageRenamed.next({ Page: this.pageInfo(target), OldName: oldName, Author: author });\n return true;\n }\n\n /**\n * Remove a page AND all of its items (tolerant lookup, same as {@link SwitchPage}).\n * The LAST remaining page can never be removed (`false`, no events). Removing the\n * ACTIVE page activates a neighbor — the next page when one exists, otherwise the\n * previous one.\n *\n * Raises the cancelable {@link PageRemoving$} BEFORE event — returns `false` when\n * vetoed or the page is unknown; fires {@link PageRemoved$} after (with the activated\n * neighbor when the active page was removed). One undoable step; journals a\n * `'replace'` op.\n */\n public RemovePage(idOrName: string, author: WhiteboardAuthor = 'user'): boolean {\n const target = this.resolvePage(idOrName);\n if (!target || this.pages.length <= 1) {\n return false; // unknown, or the guarded last page\n }\n const removingInfo = this.pageInfo(target);\n const removing: WhiteboardPageRemovingEventArgs = { Page: removingInfo, Author: author, Cancel: false };\n this.pageRemoving.next(removing);\n if (removing.Cancel) {\n return false;\n }\n this.beforeMutate();\n const index = this.pages.indexOf(target);\n this.pages.splice(index, 1);\n let activated: WhiteboardPageInfo | null = null;\n if (UUIDsEqual(target.ID, this.activePageId)) {\n // activate the neighbor: the page that slid into the removed slot, else the new last\n const neighbor = this.pages[Math.min(index, this.pages.length - 1)];\n this.activePageId = neighbor.ID;\n activated = this.pageInfo(neighbor);\n this.changeSelection(null);\n }\n this.record('replace', '', author, `removed page \"${target.Name}\"`);\n this.pageRemoved.next({ Page: removingInfo, ActivatedPage: activated, Author: author });\n return true;\n }\n\n /**\n * Run several mutations as ONE undo step (one snapshot). Used per agent tool call and for\n * compound user gestures, so the toast's \"Undo\" reverts the whole tool effect at once.\n */\n public RunBatch<T>(fn: () => T): T {\n if (this.batchDepth === 0) {\n this.pushUndo();\n }\n this.batchDepth++;\n try {\n return fn();\n }\n finally {\n this.batchDepth--;\n }\n }\n\n // ────────────────────────────────────────────── undo / redo\n\n /** Restore the previous snapshot. Emits a `'replace'` change. */\n public Undo(): boolean {\n const snap = this.undoStack.pop();\n if (!snap) {\n return false;\n }\n this.redoStack.push(this.snapshot());\n this.restore(snap);\n this.record('replace', '', 'user', 'undid the last change');\n return true;\n }\n\n /** Re-apply the most recently undone snapshot. Emits a `'replace'` change. */\n public Redo(): boolean {\n const snap = this.redoStack.pop();\n if (!snap) {\n return false;\n }\n this.undoStack.push(this.snapshot());\n this.restore(snap);\n this.record('replace', '', 'user', 'redid the last change');\n return true;\n }\n\n // ────────────────────────────────────────────── perception (scene deltas)\n\n /**\n * Build the coalesced scene delta of everything that changed AFTER `sinceToken`\n * (a previously observed {@link CurrentSeq}; defaults to 0 = everything).\n *\n * Coalescing: per item, the NET effect wins — N moves → one `moved` entry at the current\n * position; add+move → one `added` entry (current state); add+remove → nothing;\n * update+move → one `updated` entry. When the window contains a `'replace'` (undo/redo/load)\n * or the journal no longer reaches the token, the delta carries `reset: true` plus the full\n * compact `items` array — replace-current-state semantics, never an append-only log.\n */\n public BuildSceneDelta(sinceToken = 0): WhiteboardSceneDelta {\n const delta: WhiteboardSceneDelta = {\n op: 'scene-delta',\n seq: this.seq,\n added: [],\n moved: [],\n updated: [],\n removed: [],\n pages: this.scenePages(),\n summary: ''\n };\n\n const tokenTooOld = sinceToken < this.journalTrimmedBeforeSeq;\n const inRange = this.journal.filter((e) => e.Seq > sinceToken);\n const hasReplace = inRange.some((e) => e.Op === 'replace');\n\n if (tokenTooOld || hasReplace) {\n delta.reset = true;\n delta.items = this.Items.map((i) => this.compact(i));\n delta.summary = this.composeSummaryText({ reset: true });\n return delta;\n }\n\n // Net-effect per item, preserving first-op semantics.\n const firstOp = new Map<string, WhiteboardChangeOp>();\n const lastOp = new Map<string, WhiteboardChangeOp>();\n const sawUpdate = new Set<string>();\n for (const entry of inRange) {\n if (!firstOp.has(entry.ItemID)) {\n firstOp.set(entry.ItemID, entry.Op);\n }\n lastOp.set(entry.ItemID, entry.Op);\n if (entry.Op === 'update') {\n sawUpdate.add(entry.ItemID);\n }\n }\n\n for (const [id, first] of firstOp) {\n const last = lastOp.get(id);\n const item = this.items.get(id);\n if (first === 'add') {\n if (item) {\n delta.added.push(this.compact(item)); // add → (move/update)* coalesces into the added entry\n }\n // add → … → remove: net nothing\n continue;\n }\n if (last === 'remove' || !item) {\n delta.removed.push(id);\n continue;\n }\n if (sawUpdate.has(id)) {\n delta.updated.push(this.compact(item)); // update (+ moves) → one updated entry w/ current state\n continue;\n }\n // moves only → one moved entry at the current position\n const b = this.ItemBounds(item);\n delta.moved.push({ id, x: Math.round(b.X), y: Math.round(b.Y) });\n }\n\n delta.summary = this.composeSummaryText({\n added: delta.added.length,\n moved: delta.moved.length,\n updated: delta.updated.length,\n removed: delta.removed.length\n });\n return delta;\n }\n\n /** Full compact scene + counts — the popover's stats and the delta-reset payload. */\n public BuildSceneSummary(): WhiteboardSceneSummary {\n const items = this.Items;\n const byKind: Partial<Record<WhiteboardItemKind, number>> = {};\n for (const item of items) {\n byKind[item.Kind] = (byKind[item.Kind] ?? 0) + 1;\n }\n return {\n op: 'scene-summary',\n seq: this.seq,\n counts: {\n total: this.ElementCount,\n user: this.CountByAuthor('user'),\n agent: this.CountByAuthor('agent'),\n byKind\n },\n items: items.map((i) => this.compact(i)),\n pages: this.scenePages(),\n summary: this.composeSummaryText({})\n };\n }\n\n /** Compact page list for deltas / summaries (model-facing). */\n protected scenePages(): WhiteboardScenePage[] {\n return this.pages.map((p) => ({\n id: p.ID,\n name: p.Name,\n active: UUIDsEqual(p.ID, this.activePageId),\n items: p.Items.size\n }));\n }\n\n // ────────────────────────────────────────────── persistence\n\n /**\n * Serialize the board (state of record — persisted as the session-channel artifact).\n * Emits the VERSION 2 paged shape (see {@link WhiteboardStateJSON}); the legacy flat\n * shape is still accepted on load and rehydrates as a single page \"Page 1\".\n */\n public ToJSON(): string {\n return JSON.stringify(this.snapshot());\n }\n\n /**\n * Rehydrate a board from {@link ToJSON} output — BOTH shapes accepted: the current\n * paged shape (version 2) and the legacy flat shape (version 1, `items` at the root),\n * which migrates to one page named \"Page 1\". Throws on malformed input (use\n * {@link LoadFromJSON} or `ParseBoardStateJson` for the tolerant variants).\n */\n public static FromJSON(json: string): WhiteboardState {\n const normalized = WhiteboardState.normalizePersisted(JSON.parse(json));\n if (!normalized) {\n throw new Error('WhiteboardState.FromJSON: malformed payload');\n }\n const state = new WhiteboardState();\n state.restore(normalized);\n state.seq = normalized.seq;\n state.journalTrimmedBeforeSeq = state.seq; // older tokens force reset deltas\n return state;\n }\n\n /**\n * Normalize a parsed persisted payload — EITHER shape — into the current\n * {@link WhiteboardStateJSON}. Returns `null` for anything unrecognizable (the\n * callers decide whether that throws or fails soft). Defensive throughout: page\n * entries missing ids/names/item arrays are repaired, an empty page list gains one\n * \"Page 1\", and an unknown `activePageId` falls back to the first page.\n */\n private static normalizePersisted(parsed: unknown): WhiteboardStateJSON | null {\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n return null;\n }\n const raw = parsed as Record<string, unknown>;\n const num = (value: unknown, fallback: number): number =>\n typeof value === 'number' && Number.isFinite(value) ? value : fallback;\n\n if (Array.isArray(raw['pages'])) {\n // CURRENT shape (version 2, paged)\n const pages: WhiteboardPageJSON[] = [];\n for (const entry of raw['pages'] as unknown[]) {\n if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {\n continue;\n }\n const p = entry as Record<string, unknown>;\n const name = typeof p['name'] === 'string' && (p['name'] as string).trim().length > 0\n ? (p['name'] as string) : `Page ${pages.length + 1}`;\n pages.push({\n id: typeof p['id'] === 'string' && (p['id'] as string).length > 0 ? (p['id'] as string) : `page-${pages.length + 1}`,\n name,\n // additive authorship field — tolerated absent (pre-garnish payloads → 'user')\n author: p['author'] === 'agent' ? 'agent' : 'user',\n items: Array.isArray(p['items']) ? (p['items'] as WhiteboardItem[]) : []\n });\n }\n if (pages.length === 0) {\n pages.push({ id: 'page-1', name: 'Page 1', items: [] });\n }\n const active = raw['activePageId'];\n return {\n version: 2,\n seq: num(raw['seq'], 0),\n idCounter: num(raw['idCounter'], 0),\n zCounter: num(raw['zCounter'], 0),\n pageCounter: Math.max(num(raw['pageCounter'], pages.length), pages.length),\n activePageId: typeof active === 'string' && pages.some((p) => p.id === active) ? active : pages[0].id,\n pages\n };\n }\n if (Array.isArray(raw['items'])) {\n // LEGACY shape (version 1, flat) — migrate to a single page \"Page 1\"\n return {\n version: 2,\n seq: num(raw['seq'], 0),\n idCounter: num(raw['idCounter'], 0),\n zCounter: num(raw['zCounter'], 0),\n pageCounter: 1,\n activePageId: 'page-1',\n pages: [{ id: 'page-1', name: 'Page 1', items: raw['items'] as WhiteboardItem[] }]\n };\n }\n return null;\n }\n\n /**\n * Rehydrate THIS instance in place from {@link ToJSON} output — used by the channel's\n * `RestoreState` hook so existing subscriptions (perception feed, save pipeline) and any\n * bound surface keep pointing at the same engine. TOLERANT: malformed input returns\n * `false` and leaves the current state untouched (never throws).\n *\n * On success the undo/redo stacks and journal are cleared (restored state is the new\n * baseline), stale delta tokens force reset semantics, one `'replace'` change is\n * emitted so consumers re-read the full scene, and {@link BoardLoaded$} fires.\n */\n public LoadFromJSON(json: string): boolean {\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n }\n catch {\n return false;\n }\n const normalized = WhiteboardState.normalizePersisted(parsed);\n if (!normalized) {\n return false;\n }\n this.restore(normalized);\n this.seq = normalized.seq;\n this.journal = [];\n this.journalTrimmedBeforeSeq = this.seq; // older tokens force reset deltas\n this.undoStack = [];\n this.redoStack = [];\n this.changeSelection(null);\n this.record('replace', '', 'user', 'restored a saved board');\n this.boardLoaded.next({ ItemCount: this.TotalItemCount });\n return true;\n }\n\n // ────────────────────────────────────────────── internals\n\n /** Mint the next stable item ID for a kind (`sticky-3`, `shape-7`, …). */\n protected nextId(kind: WhiteboardItemKind): string {\n return `${kind}-${++this.idCounter}`;\n }\n\n /**\n * Pre-mutation bookkeeping shared by every committed mutation: pushes the undo\n * snapshot (unless inside a {@link RunBatch}, which snapshotted at batch start) and\n * invalidates the redo branch. Subclasses extending the mutation paths should call\n * this exactly once per logical change, AFTER any cancelable before-event survived.\n */\n protected beforeMutate(): void {\n if (this.batchDepth === 0) {\n this.pushUndo();\n }\n // Any forward mutation invalidates the redo branch (batched mutations included).\n this.redoStack = [];\n }\n\n /** Push the current scene onto the undo stack (bounded) and drop the redo branch. */\n protected pushUndo(): void {\n this.undoStack.push(this.snapshot());\n if (this.undoStack.length > WhiteboardState.undoMax) {\n this.undoStack.shift();\n }\n this.redoStack = [];\n }\n\n /**\n * Deep-copied serializable snapshot of the WHOLE board — every page's items plus the\n * page structure and counters (undo entries / ToJSON). Page items serialize in render\n * order (ascending Z).\n */\n protected snapshot(): WhiteboardStateJSON {\n return {\n version: 2,\n seq: this.seq,\n idCounter: this.idCounter,\n zCounter: this.zCounter,\n pageCounter: this.pageCounter,\n activePageId: this.activePageId,\n pages: this.pages.map((p) => ({\n id: p.ID,\n name: p.Name,\n author: p.Author,\n items: JSON.parse(JSON.stringify(Array.from(p.Items.values()).sort((a, b) => a.Z - b.Z))) as WhiteboardItem[]\n }))\n };\n }\n\n /**\n * Swap the whole board to a snapshot's pages/counters (drops a now-missing selection;\n * an unknown active-page id falls back to the first page; an empty page list gains a\n * fresh \"Page 1\" so the engine never runs page-less).\n */\n protected restore(snap: WhiteboardStateJSON): void {\n this.pages = (snap.pages ?? []).map((p) => ({\n ID: p.id,\n Name: p.name,\n Author: p.author === 'agent' ? 'agent' : 'user',\n Items: new Map((JSON.parse(JSON.stringify(p.items ?? [])) as WhiteboardItem[])\n .filter((i) => !!i && typeof i === 'object' && typeof i.ID === 'string')\n .map((i) => [i.ID, i]))\n }));\n if (this.pages.length === 0) {\n this.pages = [{ ID: 'page-1', Name: 'Page 1', Author: 'user', Items: new Map<string, WhiteboardItem>() }];\n }\n this.activePageId = this.pages.some((p) => UUIDsEqual(p.ID, snap.activePageId)) ? snap.activePageId : this.pages[0].ID;\n this.idCounter = snap.idCounter ?? 0;\n this.zCounter = snap.zCounter ?? 0;\n this.pageCounter = Math.max(snap.pageCounter ?? this.pages.length, this.pages.length);\n // drop selection members the restored active page no longer contains\n const surviving = this.selectedIds.filter((id) => this.items.has(id));\n if (surviving.length !== this.selectedIds.length) {\n this.applySelection(surviving);\n }\n }\n\n /**\n * Post-mutation bookkeeping shared by every committed mutation: bumps the sequence,\n * appends the journal entry (bounded — trimming forces reset deltas for stale tokens)\n * and emits the {@link Changed$} notification.\n */\n protected record(op: WhiteboardChangeOp, itemId: string, author: WhiteboardAuthor, summaryFragment: string): void {\n this.seq++;\n this.journal.push({ Seq: this.seq, Op: op, ItemID: itemId });\n if (this.journal.length > WhiteboardState.journalMax) {\n const dropped = this.journal.splice(0, this.journal.length - WhiteboardState.journalMax);\n this.journalTrimmedBeforeSeq = dropped[dropped.length - 1].Seq;\n }\n this.changed.next({ Op: op, ItemID: itemId, Author: author, SummaryFragment: summaryFragment, Seq: this.seq });\n }\n\n /** Project one item to its compact, model-facing representation (deltas / summaries). */\n protected compact(item: WhiteboardItem): WhiteboardCompactItem {\n const c: WhiteboardCompactItem = { id: item.ID, type: item.Kind, author: item.Author };\n switch (item.Kind) {\n case 'sticky':\n c.x = Math.round(item.X);\n c.y = Math.round(item.Y);\n c.text = clip(item.Text, 120);\n WhiteboardState.compactTextStyle(item, c);\n break;\n case 'shape':\n c.x = Math.round(item.X);\n c.y = Math.round(item.Y);\n c.w = Math.round(item.W);\n c.h = Math.round(item.H);\n c.shape = item.Shape;\n c.text = clip(item.Sub ? `${item.Label} (${item.Sub})` : item.Label, 120);\n break;\n case 'text':\n c.x = Math.round(item.X);\n c.y = Math.round(item.Y);\n if (item.W) {\n c.w = Math.round(item.W);\n }\n c.text = clip(item.Text, 120);\n WhiteboardState.compactTextStyle(item, c);\n if (item.Color) {\n c.color = item.Color;\n }\n break;\n case 'image':\n c.x = Math.round(item.X);\n c.y = Math.round(item.Y);\n c.name = item.Name;\n break;\n case 'ink': {\n const b = this.ItemBounds(item);\n c.x = Math.round(b.X);\n c.y = Math.round(b.Y);\n c.w = Math.round(b.W);\n c.h = Math.round(b.H);\n c.points = item.Points.length;\n break;\n }\n case 'connector':\n c.from = item.FromItemID ?? item.FromPoint ?? null;\n c.to = item.ToItemID ?? item.ToPoint ?? null;\n break;\n case 'highlight':\n c.x = Math.round(item.X);\n c.y = Math.round(item.Y);\n c.w = Math.round(item.W);\n c.h = Math.round(item.H);\n if (item.Label) {\n c.text = clip(item.Label, 120);\n }\n break;\n case 'markdown':\n // the agent must SEE what's in the panel — project the clipped SOURCE, not a stub\n c.x = Math.round(item.X);\n c.y = Math.round(item.Y);\n c.w = Math.round(item.W);\n if (item.H != null) {\n c.h = Math.round(item.H);\n }\n c.text = clip(item.Markdown, 200);\n break;\n case 'html':\n c.x = Math.round(item.X);\n c.y = Math.round(item.Y);\n c.w = Math.round(item.W);\n c.h = Math.round(item.H);\n if (item.Title) {\n c.name = clip(item.Title, 80);\n }\n c.text = clip(item.Html, 200);\n break;\n }\n return c;\n }\n\n /** Project the optional text-style fields onto a compact item (sticky / text kinds). */\n private static compactTextStyle(item: WhiteboardStickyItem | WhiteboardTextItem, c: WhiteboardCompactItem): void {\n if (item.FontSize != null) {\n c.fontSize = item.FontSize;\n }\n if (item.FontFamily) {\n c.fontFamily = item.FontFamily;\n }\n if (item.FontWeight === 700) {\n c.bold = true;\n }\n }\n\n /**\n * Compose the human-readable tail line of deltas / summaries (\"2 added, 1 moved. …\"),\n * including which page is active and the full page list — so the model always knows\n * pages exist and which one its item entries describe.\n */\n protected composeSummaryText(parts: { added?: number; moved?: number; updated?: number; removed?: number; reset?: boolean }): string {\n const bits: string[] = [];\n if (parts.reset) {\n bits.push('full scene snapshot (state replaced)');\n }\n else {\n if (parts.added) {\n bits.push(`${parts.added} added`);\n }\n if (parts.moved) {\n bits.push(`${parts.moved} moved`);\n }\n if (parts.updated) {\n bits.push(`${parts.updated} updated`);\n }\n if (parts.removed) {\n bits.push(`${parts.removed} removed`);\n }\n if (bits.length === 0) {\n bits.push('no changes');\n }\n }\n return `${bits.join(', ')}. ${this.composePagesText()}`;\n }\n\n /** The page-aware scene sentence shared by every delta / summary tail line. */\n protected composePagesText(): string {\n const active = this.activePage;\n const index = this.pages.indexOf(active) + 1;\n const counts = `${this.ElementCount} elements (user ${this.CountByAuthor('user')} · agent ${this.CountByAuthor('agent')})`;\n if (this.pages.length === 1) {\n return `Active page \"${active.Name}\" (the only page) has ${counts}.`;\n }\n const others = this.pages\n .filter((p) => !UUIDsEqual(p.ID, active.ID))\n .map((p) => `\"${p.Name}\" (${p.Items.size})`)\n .join(', ');\n return `Active page \"${active.Name}\" (${index} of ${this.pages.length}) has ${counts}. Other pages: ${others}.`;\n }\n\n private static describe(item: WhiteboardItem): string {\n switch (item.Kind) {\n case 'sticky': return `a sticky note (\"${clip(item.Text)}\")`;\n case 'shape': return `a ${item.Shape} (\"${clip(item.Label)}\")`;\n case 'text': return `a text label (\"${clip(item.Text)}\")`;\n case 'image': return `an image (${item.Name})`;\n case 'ink': return 'an ink stroke';\n case 'connector': return 'a connector';\n case 'highlight': return 'a highlight region';\n case 'markdown': return `a markdown panel (\"${clip(item.Markdown)}\")`;\n case 'html': return `an HTML widget${item.Title ? ` (\"${clip(item.Title)}\")` : ''}`;\n }\n }\n}\n"]}