@dotit/editor 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/font-size.ts","../src/page-geometry.ts","../src/pagination.ts","../src/bridge.ts","../src/keyword-styles.ts","../src/extensions.ts","../src/block-props.ts","../src/types.ts","../src/print-iframe.ts","../src/print.ts","../src/DocsToolbar.tsx","../src/Ruler.tsx","../src/TrustBanner.tsx","../src/trust-state.ts","../src/template-highlight.ts","../src/VisualEditor.tsx","../src/IntentTextEditor.tsx"],"sourcesContent":["import { Extension } from \"@tiptap/core\";\nimport \"@tiptap/extension-text-style\";\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n fontSize: {\n setFontSize: (size: string) => ReturnType;\n unsetFontSize: () => ReturnType;\n };\n }\n}\n\nexport const FontSize = Extension.create({\n name: \"fontSize\",\n\n addOptions() {\n return { types: [\"textStyle\"] };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n fontSize: {\n default: null,\n parseHTML: (el) =>\n (el as HTMLElement).style.fontSize?.replace(/['\"]+/g, \"\") || null,\n renderHTML: (attributes) => {\n if (!attributes.fontSize) return {};\n return { style: `font-size: ${attributes.fontSize}` };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setFontSize:\n (size) =>\n ({ chain }) =>\n chain().setMark(\"textStyle\", { fontSize: size }).run(),\n unsetFontSize:\n () =>\n ({ chain }) =>\n chain()\n .setMark(\"textStyle\", { fontSize: null })\n .removeEmptyTextStyle()\n .run(),\n };\n },\n});\n","// Single source of truth for page geometry in the visual editor.\n//\n// The SAME `page:` block drives core's @page print CSS and this on-screen\n// geometry, so the editor view and the printed PDF paginate identically —\n// that's what makes the editor WYSIWYG. All values are CSS px at 96dpi\n// (1mm = 96/25.4 px), kept as floats to avoid drift across many pages.\n\nimport { parseIntentText } from \"@dotit/core\";\n\nexport const MM = 96 / 25.4;\n\n/** Named paper sizes in mm — keep in sync with core's PAPER_SIZES. */\nconst PAPER_MM: Record<string, [number, number]> = {\n A4: [210, 297],\n A5: [148, 210],\n A3: [297, 420],\n Letter: [215.9, 279.4],\n Legal: [215.9, 355.6],\n Tabloid: [279.4, 431.8],\n};\n\n/** Ruler unit per named paper size — metric sheets read in cm, US sheets in inches. */\nconst PAPER_UNIT: Record<string, \"cm\" | \"in\"> = {\n A4: \"cm\",\n A5: \"cm\",\n A3: \"cm\",\n LETTER: \"in\",\n LEGAL: \"in\",\n TABLOID: \"in\",\n};\n\n/** Default print margin — MUST match core renderPrint's default (20mm). */\nconst DEFAULT_MARGIN_MM = 20;\n/** Narrow pages (receipts) default tight margins — matches core (≤120mm → 4mm). */\nconst NARROW_MARGIN_MM = 4;\nconst NARROW_WIDTH_MM = 120;\n\nexport interface PageGeometry {\n /** Page width in px. */\n width: number;\n /** Page height in px — Infinity when height is `auto` (continuous receipt). */\n height: number;\n /** True when the page grows with content (e.g. `80mm auto`): no pagination. */\n autoHeight: boolean;\n marginTop: number;\n marginRight: number;\n marginBottom: number;\n marginLeft: number;\n /** Height available for content on one page (height - vertical margins). */\n contentHeight: number;\n /** Header text ('' if none). Supports {{page}}/{{pages}} tokens. */\n header: string;\n /** Footer text ('' if none). Supports {{page}}/{{pages}} tokens. */\n footer: string;\n /** Ruler unit derived from the page size (A-series → cm, Letter/Legal → in). */\n unit: \"cm\" | \"in\";\n}\n\nfunction parseLength(v: string): number | null {\n const m = /^(-?\\d+(?:\\.\\d+)?)\\s*(mm|cm|in|px|pt)?$/.exec(v.trim());\n if (!m) return null;\n const n = parseFloat(m[1]);\n switch (m[2] || \"mm\") {\n case \"mm\":\n return n * MM;\n case \"cm\":\n return n * 10 * MM;\n case \"in\":\n return n * 96;\n case \"pt\":\n return (n / 72) * 96;\n case \"px\":\n return n;\n default:\n return null;\n }\n}\n\n/** Parse a CSS-style margin shorthand (1–4 values) into [t, r, b, l] px. */\nfunction parseMargins(raw: string, fallback: number): [number, number, number, number] {\n const parts = raw.trim().split(/\\s+/).map(parseLength);\n if (parts.some((p) => p === null) || parts.length === 0)\n return [fallback, fallback, fallback, fallback];\n const v = parts as number[];\n if (v.length === 1) return [v[0], v[0], v[0], v[0]];\n if (v.length === 2) return [v[0], v[1], v[0], v[1]];\n if (v.length === 3) return [v[0], v[1], v[2], v[1]];\n return [v[0], v[1], v[2], v[3]];\n}\n\n/** Compute the page geometry from `.it` source (its page:/header:/footer: blocks). */\nexport function getPageGeometry(source: string): PageGeometry {\n let size = \"A4\";\n let marginRaw: string | undefined;\n let header = \"\";\n let footer = \"\";\n try {\n const doc = parseIntentText(source);\n const page = doc.blocks.find((b) => b.type === \"page\");\n const props = (page?.properties || {}) as Record<string, string>;\n if (props.size) size = String(props.size);\n marginRaw = (props.margin ?? props.margins) as string | undefined;\n header =\n doc.blocks.find((b) => b.type === \"header\")?.content ||\n String(props.header || \"\");\n footer =\n doc.blocks.find((b) => b.type === \"footer\")?.content ||\n String(props.footer || \"\");\n } catch {\n /* defaults */\n }\n\n // Resolve page size: named, or \"<w> <h>\" (h may be `auto`).\n let width = PAPER_MM.A4[0] * MM;\n let height: number = PAPER_MM.A4[1] * MM;\n let autoHeight = false;\n let unit: \"cm\" | \"in\" = \"cm\";\n const named = PAPER_MM[size] || PAPER_MM[size.toUpperCase?.() as string];\n if (named) {\n width = named[0] * MM;\n height = named[1] * MM;\n unit = PAPER_UNIT[size.toUpperCase()] || \"cm\";\n } else {\n const parts = size.trim().split(/\\s+/);\n const w = parts[0] ? parseLength(parts[0]) : null;\n if (w) width = w;\n // Custom sizes declared in inches read in inches; everything else metric.\n if (/(\\d)\\s*in\\b/.test(size)) unit = \"in\";\n if (parts[1] === \"auto\") {\n autoHeight = true;\n height = Infinity;\n } else {\n const h = parts[1] ? parseLength(parts[1]) : null;\n if (h) height = h;\n }\n }\n\n const defMargin =\n (width <= NARROW_WIDTH_MM * MM ? NARROW_MARGIN_MM : DEFAULT_MARGIN_MM) * MM;\n const [mt, mr, mb, ml] = marginRaw\n ? parseMargins(marginRaw, defMargin)\n : [defMargin, defMargin, defMargin, defMargin];\n\n return {\n width,\n height,\n autoHeight,\n marginTop: mt,\n marginRight: mr,\n marginBottom: mb,\n marginLeft: ml,\n contentHeight: autoHeight ? Infinity : height - mt - mb,\n header,\n footer,\n unit,\n };\n}\n\n/** Resolve {{page}}/{{pages}} tokens for on-screen display. */\nexport function resolvePageTokens(\n text: string,\n page: number,\n pages: number,\n): string {\n return text\n .replace(/\\{\\{\\s*page\\s*\\}\\}/g, String(page))\n .replace(/\\{\\{\\s*pages\\s*\\}\\}/g, String(pages));\n}\n","// Word-like page pagination for the visual editor.\n//\n// One continuous contenteditable sheet is visually cut into real pages:\n// at each page boundary a non-editable spacer widget renders\n// [filler to the page bottom + footer band] [page gap] [header band]\n// and a terminal spacer closes the LAST page with its filler + footer band,\n// so every page — first, middle, last — shows its header/footer and keeps its\n// exact print height. Content is never hidden or clipped (the old masking bug);\n// the caret stays in document order.\n//\n// Geometry comes from page-geometry.ts (the document's own `page:` block) — the\n// same numbers core's @page print CSS uses, which is what makes the editor view\n// match the printed PDF page-for-page.\n\nimport { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport type { PageGeometry } from \"./page-geometry\";\nimport { resolvePageTokens } from \"./page-geometry\";\n\nexport interface PaginationOptions {\n /** Live geometry — read on every layout pass so doc edits apply instantly. */\n geometry: () => PageGeometry;\n /** Grey gap between page cards (px). */\n gap: number;\n /** Called with the resulting page count after each layout pass. */\n onPages?: (pages: number) => void;\n}\n\nconst paginationKey = new PluginKey(\"pagination\");\n\n// Renders exactly what print's @page margin box shows: the resolved text,\n// horizontally centered, vertically centered in the margin area. No extra\n// auto page number — print shows one only when the footer contains {{page}}.\nfunction bandHtml(\n kind: \"header\" | \"footer\",\n text: string,\n page: number,\n pages: number,\n): string {\n const resolved = resolvePageTokens(text, page, pages);\n return `<div class=\"docs-pb-${kind}\">\n <span class=\"docs-pb-text\">${escapeHtml(resolved)}</span>\n </div>`;\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nexport const Pagination = Extension.create<PaginationOptions>({\n name: \"pagination\",\n\n addOptions() {\n return {\n geometry: () =>\n ({\n width: 794,\n height: 1122.52,\n autoHeight: false,\n marginTop: 75.59,\n marginRight: 75.59,\n marginBottom: 75.59,\n marginLeft: 75.59,\n contentHeight: 971.34,\n header: \"\",\n footer: \"\",\n }) as PageGeometry,\n gap: 28,\n onPages: undefined,\n };\n },\n\n addProseMirrorPlugins() {\n const opts = this.options;\n\n return [\n new Plugin({\n key: paginationKey,\n state: {\n init: () => DecorationSet.empty,\n apply(tr, old) {\n const meta = tr.getMeta(paginationKey);\n if (meta) return meta as DecorationSet;\n return old.map(tr.mapping, tr.doc);\n },\n },\n props: {\n decorations(state) {\n return paginationKey.getState(state);\n },\n },\n view(view) {\n let raf = 0;\n let lastSig = \"\";\n\n // Interior break: close page N (filler + footer), gap, open page N+1 (header).\n const makeBreak = (\n g: PageGeometry,\n restHeight: number,\n page: number,\n pages: number,\n ): HTMLElement => {\n const el = document.createElement(\"div\");\n el.className = \"docs-page-spacer\";\n el.contentEditable = \"false\";\n el.setAttribute(\"data-it-spacer\", \"\");\n el.style.setProperty(\"--pb-mx-l\", `${g.marginLeft}px`);\n el.style.setProperty(\"--pb-mx-r\", `${g.marginRight}px`);\n el.innerHTML = `\n <div class=\"docs-pb-fill\" style=\"height:${restHeight}px\"></div>\n <div class=\"docs-pb-margin docs-pb-margin-bottom\" style=\"height:${g.marginBottom}px\">\n ${bandHtml(\"footer\", g.footer, page, pages)}\n </div>\n <div class=\"docs-pb-gap\" style=\"height:${opts.gap}px\"></div>\n <div class=\"docs-pb-margin docs-pb-margin-top\" style=\"height:${g.marginTop}px\">\n ${bandHtml(\"header\", g.header, page + 1, pages)}\n </div>`;\n return el;\n };\n\n // Terminal spacer: close the LAST page so it is exactly page-height and\n // shows its footer like every other page.\n const makeTail = (\n g: PageGeometry,\n restHeight: number,\n page: number,\n pages: number,\n ): HTMLElement => {\n const el = document.createElement(\"div\");\n el.className = \"docs-page-spacer docs-page-tail\";\n el.contentEditable = \"false\";\n el.setAttribute(\"data-it-spacer\", \"\");\n el.style.setProperty(\"--pb-mx-l\", `${g.marginLeft}px`);\n el.style.setProperty(\"--pb-mx-r\", `${g.marginRight}px`);\n el.innerHTML = `\n <div class=\"docs-pb-fill\" style=\"height:${restHeight}px\"></div>\n <div class=\"docs-pb-margin docs-pb-margin-bottom\" style=\"height:${g.marginBottom}px\">\n ${bandHtml(\"footer\", g.footer, page, pages)}\n </div>`;\n return el;\n };\n\n const recompute = () => {\n const g = opts.geometry();\n const dom = view.dom as HTMLElement;\n const doc = view.state.doc;\n\n // Continuous mode (e.g. `80mm auto` receipts): no pagination at all.\n if (g.autoHeight) {\n if (lastSig !== \"auto\") {\n lastSig = \"auto\";\n view.dispatch(\n view.state.tr.setMeta(paginationKey, DecorationSet.empty),\n );\n opts.onPages?.(1);\n }\n return;\n }\n\n // Pass 1 — measure where the breaks fall, using RECT positions so\n // CSS margin collapsing is accounted for exactly (summing heights +\n // margins overestimates and drifts off the print engine's breaks).\n // Spacer heights above each block are subtracted to recover each\n // block's \"natural\" position — stable across re-layouts.\n const domTop = dom.getBoundingClientRect().top;\n const all = Array.from(dom.children) as HTMLElement[];\n const blocks: { natTop: number; natBottom: number }[] = [];\n let spacerAbove = 0;\n for (const c of all) {\n if (c.hasAttribute?.(\"data-it-spacer\")) {\n spacerAbove += c.offsetHeight;\n continue;\n }\n const r = c.getBoundingClientRect();\n blocks.push({\n natTop: r.top - domTop - spacerAbove,\n natBottom: r.bottom - domTop - spacerAbove,\n });\n }\n\n const breaks: { pos: number; rest: number }[] = [];\n let pos = 0;\n let pageStart = blocks.length ? blocks[0].natTop : 0;\n let lastBottom = pageStart;\n for (let i = 0; i < blocks.length && i < doc.childCount; i++) {\n const b = blocks[i];\n const nodeSize = doc.child(i).nodeSize;\n if (\n b.natTop > pageStart && // never break before the page's first block\n b.natBottom - pageStart > g.contentHeight\n ) {\n breaks.push({\n pos,\n rest: Math.max(0, g.contentHeight - (b.natTop - pageStart)),\n });\n pageStart = b.natTop;\n }\n lastBottom = b.natBottom;\n pos += nodeSize;\n }\n const pages = breaks.length + 1;\n const lastRest = Math.max(\n 0,\n g.contentHeight - (lastBottom - pageStart),\n );\n\n const sig =\n breaks.map((b) => `${b.pos}:${Math.round(b.rest)}`).join(\",\") +\n `|${Math.round(lastRest)}|${pages}|${g.header}|${g.footer}|${Math.round(g.contentHeight)}`;\n if (sig === lastSig) return;\n lastSig = sig;\n\n // Pass 2 — build decorations with the final page count (so {{pages}}\n // and per-page numbers are correct).\n const decos: Decoration[] = breaks.map((b, idx) =>\n Decoration.widget(\n b.pos,\n () => makeBreak(g, b.rest, idx + 1, pages),\n { side: -1, key: `pb-${idx + 1}-${Math.round(b.rest)}` },\n ),\n );\n decos.push(\n Decoration.widget(\n doc.content.size,\n () => makeTail(g, lastRest, pages, pages),\n { side: 1, key: `pb-tail-${pages}-${Math.round(lastRest)}` },\n ),\n );\n\n const set = DecorationSet.create(view.state.doc, decos);\n view.dispatch(view.state.tr.setMeta(paginationKey, set));\n opts.onPages?.(pages);\n };\n\n const schedule = () => {\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(recompute);\n };\n\n schedule();\n return {\n update: schedule,\n destroy: () => cancelAnimationFrame(raf),\n };\n },\n }),\n ];\n },\n});\n","// Bridge: IntentText source ↔ TipTap JSON document\n// Converts .it source text to TipTap-compatible JSON and back\n\nimport { parseIntentText } from \"@dotit/core\";\nimport type { JSONContent } from \"@tiptap/core\";\n\n/** A TipTap mark on a text node. */\ntype Mark = {\n type: string;\n attrs?: Record<string, unknown>;\n [k: string]: unknown;\n};\n\n// IT keywords that map to dedicated TipTap nodes\nconst CALLOUT_TYPES = new Set([\"tip\", \"info\", \"warning\", \"danger\", \"success\"]);\n// Document-level metadata / layout keywords — shown as a chip, not body content.\nconst META_KEYWORDS = new Set([\n \"page\",\n \"meta\",\n \"font\",\n \"header\",\n \"footer\",\n \"watermark\",\n]);\n// Tamper-evidence / history keywords — rendered as styled trust chips, with the\n// exact source line preserved verbatim for round-trip (the document hash must not\n// change from editing in the visual editor).\nconst TRUST_KEYWORDS = new Set([\n \"sign\",\n \"seal\",\n \"approve\",\n \"freeze\",\n \"amend\",\n \"amendment\",\n]);\nconst HEADING_MAP: Record<string, string> = {\n title: \"itTitle\",\n section: \"itSection\",\n sub: \"itSub\",\n};\n\nconst KEYWORD_ALIASES: Record<string, string> = {\n note: \"text\",\n \"body-text\": \"text\",\n};\n\n// Style keys managed through TipTap marks/attributes.\n// These are extracted FROM marks on doc→source, and applied AS marks on source→doc.\n// Canonical keys match core's STYLE_PROPERTIES (family/bg/italic), so styling done\n// in the editor renders identically through core. Legacy editor keys (style/font/\n// bgcolor) are kept so older documents still round-trip.\nconst MARK_STYLE_KEYS = new Set([\n \"weight\",\n \"italic\",\n \"underline\",\n \"strike\",\n \"color\",\n \"family\",\n \"size\",\n \"bg\",\n \"valign\",\n \"align\",\n // legacy aliases\n \"style\",\n \"font\",\n \"bgcolor\",\n]);\n\n/* ── Helpers ─────────────────────────────────────────────────── */\n\n/** Parse the JSON-encoded props attribute. */\nfunction parseProps(raw: unknown): Record<string, string> {\n if (!raw || raw === \"{}\") return {};\n try {\n return typeof raw === \"string\"\n ? JSON.parse(raw)\n : (raw as Record<string, string>) || {};\n } catch {\n return {};\n }\n}\n\n/** Format a props object as ' | key: val | key2: val2' (or ''). */\nfunction formatProps(\n props: Record<string, string>,\n exclude?: Set<string>,\n): string {\n const entries = Object.entries(props).filter(\n ([k, v]) => v !== undefined && v !== \"\" && (!exclude || !exclude.has(k)),\n );\n if (entries.length === 0) return \"\";\n return \" | \" + entries.map(([k, v]) => `${k}: ${v}`).join(\" | \");\n}\n\n/**\n * Convert text string to TipTap content nodes.\n * Literal \\n (backslash-n) in the source becomes hardBreak nodes.\n */\nfunction textToContent(text: string): JSONContent[] {\n if (!text) return [];\n const parts = text.split(\"\\\\n\");\n const result: JSONContent[] = [];\n parts.forEach((part, i) => {\n if (part) result.push({ type: \"text\", text: part });\n if (i < parts.length - 1) result.push({ type: \"hardBreak\" });\n });\n return result;\n}\n\n/** A core inline AST node (subset we map to TipTap marks). */\ntype InlineNode = {\n type: string;\n value?: string;\n href?: string;\n props?: Record<string, string>;\n};\n\n/** Map one core inline node to the TipTap marks it should carry (or null = plain). */\nfunction inlineNodeMarks(node: InlineNode): Mark[] | null {\n switch (node.type) {\n case \"bold\":\n return [{ type: \"bold\" }];\n case \"italic\":\n return [{ type: \"italic\" }];\n case \"strike\":\n return [{ type: \"strike\" }];\n case \"code\":\n return [{ type: \"code\" }];\n case \"highlight\":\n return [{ type: \"highlight\" }];\n case \"styled\": {\n const p = node.props || {};\n const marks: Mark[] = [];\n const ts: Record<string, string> = {};\n if (p.weight && p.weight !== \"normal\") marks.push({ type: \"bold\" });\n if (p.italic === \"true\") marks.push({ type: \"italic\" });\n if (p.underline === \"true\") marks.push({ type: \"underline\" });\n if (p.strike === \"true\") marks.push({ type: \"strike\" });\n if (p.color) ts.color = p.color;\n if (p.family) ts.fontFamily = p.family;\n if (p.size) ts.fontSize = p.size;\n if (Object.keys(ts).length) marks.push({ type: \"textStyle\", attrs: ts });\n if (p.bg) marks.push({ type: \"highlight\", attrs: { color: p.bg } });\n if (p.valign === \"sub\") marks.push({ type: \"subscript\" });\n if (p.valign === \"super\") marks.push({ type: \"superscript\" });\n return marks.length ? marks : null;\n }\n default:\n return null; // text, mention, tag, date, label, link → plain text\n }\n}\n\n// Inline node types that map cleanly to TipTap marks (and thus round-trip exactly).\n// Other node types (label, mention, tag, date, link, note, quote, code, footnote)\n// carry delimiters that can't be reconstructed from the AST alone, so a line\n// containing any of them is kept literal (textToContent) — preserving the source.\nconst MAPPABLE_INLINE = new Set([\n \"text\",\n \"bold\",\n \"italic\",\n \"strike\",\n \"highlight\",\n \"styled\",\n]);\n\n/**\n * Build TipTap content from core's inline AST, so inline marks AND styled spans\n * (`[text]{…}`) become real TipTap marks (partial styling survives the round-trip).\n * If the line mixes in delimiter-bearing nodes (mentions, tags, links, code, …) or\n * has nothing to mark, keep it literal so those tokens round-trip unchanged.\n */\nfunction inlineToContent(\n inline: InlineNode[] | undefined,\n fallbackText: string,\n): JSONContent[] {\n if (\n !inline ||\n inline.length === 0 ||\n inline.every((n) => n.type === \"text\") ||\n !inline.every((n) => MAPPABLE_INLINE.has(n.type))\n ) {\n return textToContent(fallbackText);\n }\n const result: JSONContent[] = [];\n for (const node of inline) {\n const marks = inlineNodeMarks(node);\n const value = node.value ?? \"\";\n // Preserve literal \\n as hardBreaks even inside styled runs.\n const parts = value.split(\"\\\\n\");\n parts.forEach((part, i) => {\n if (part)\n result.push(marks ? { type: \"text\", text: part, marks } : { type: \"text\", text: part });\n if (i < parts.length - 1) result.push({ type: \"hardBreak\" });\n });\n }\n return result.length ? result : textToContent(fallbackText);\n}\n\n/**\n * Apply IT properties as TipTap marks on text content nodes.\n * E.g. weight:bold → bold mark, color:#f00 → textStyle{color}, etc.\n */\nfunction applyPropsAsMarks(\n content: JSONContent[],\n properties: Record<string, string | number> | undefined,\n): JSONContent[] {\n if (!properties || content.length === 0) return content;\n\n const marks: Mark[] = [];\n const tsAttrs: Record<string, string> = {};\n\n const p = properties;\n // Canonical core keys (family/bg/italic), with legacy editor keys as fallback.\n const family = p.family ?? p.font;\n const bg = p.bg ?? p.bgcolor;\n if (String(p.weight || \"\").toLowerCase() === \"bold\")\n marks.push({ type: \"bold\" });\n if (String(p.italic || \"\") === \"true\" || String(p.style || \"\").toLowerCase() === \"italic\")\n marks.push({ type: \"italic\" });\n if (String(p.underline || \"\") === \"true\") marks.push({ type: \"underline\" });\n if (String(p.strike || \"\") === \"true\") marks.push({ type: \"strike\" });\n if (String(p.valign || \"\") === \"sub\") marks.push({ type: \"subscript\" });\n if (String(p.valign || \"\") === \"super\") marks.push({ type: \"superscript\" });\n if (p.color) tsAttrs.color = String(p.color);\n if (family) tsAttrs.fontFamily = String(family);\n if (p.size) tsAttrs.fontSize = String(p.size);\n if (bg) marks.push({ type: \"highlight\", attrs: { color: String(bg) } });\n\n if (Object.keys(tsAttrs).length > 0)\n marks.push({ type: \"textStyle\", attrs: tsAttrs });\n\n if (marks.length === 0) return content;\n\n return content.map((n) =>\n n.type === \"text\"\n ? { ...n, marks: [...((n.marks || []) as Mark[]), ...marks] }\n : n,\n );\n}\n\n/** One text run's marks → the IT style props they map to (line-level vocabulary). */\nfunction marksToProps(marks: Mark[] | undefined): Record<string, string> {\n const props: Record<string, string> = {};\n for (const mark of marks || []) {\n switch (mark.type) {\n case \"bold\":\n props.weight = \"bold\";\n break;\n case \"italic\":\n props.italic = \"true\";\n break;\n case \"underline\":\n props.underline = \"true\";\n break;\n case \"strike\":\n props.strike = \"true\";\n break;\n case \"textStyle\":\n if (mark.attrs?.color) props.color = String(mark.attrs.color);\n if (mark.attrs?.fontFamily) props.family = String(mark.attrs.fontFamily);\n if (mark.attrs?.fontSize) props.size = String(mark.attrs.fontSize);\n break;\n case \"highlight\":\n if (mark.attrs?.color) props.bg = String(mark.attrs.color);\n break;\n case \"subscript\":\n props.valign = \"sub\";\n break;\n case \"superscript\":\n props.valign = \"super\";\n break;\n }\n }\n return props;\n}\n\n/**\n * Serialize ONE text run (with its marks) to .it inline syntax:\n * - no marks → raw text\n * - a single semantic mark → the mark char (*bold* _italic_ ~strike~ `code` ^hl^)\n * - link → [text](href)\n * - color/font/size, or combined marks → a styled span [text]{ k: v; k: v }\n * This is what lets partial styling round-trip (vs. flattening to the whole line).\n */\nfunction runToInlineText(child: JSONContent): string {\n if (child.type === \"hardBreak\") return \"\\\\n\";\n if (child.type !== \"text\") return extractText(child);\n const t = child.text || \"\";\n if (!t) return \"\";\n const marks = (child.marks || []) as Mark[];\n if (!marks.length) return t;\n\n const types = new Set(marks.map((m) => m.type));\n const link = marks.find((m) => m.type === \"link\");\n if (link?.attrs?.href) return `[${t}](${link.attrs.href})`;\n\n const ts = marks.find((m) => m.type === \"textStyle\")?.attrs || {};\n const hl = marks.find((m) => m.type === \"highlight\")?.attrs || {};\n const hasColorFont = !!(ts.color || ts.fontFamily || ts.fontSize || hl.color);\n const semanticCount = [\"bold\", \"italic\", \"strike\", \"underline\", \"code\"].filter(\n (k) => types.has(k),\n ).length;\n\n // Single semantic mark with no color/font and no combining → tidy mark char.\n if (!hasColorFont && semanticCount === 1 && !types.has(\"underline\")) {\n if (types.has(\"bold\")) return `*${t}*`;\n if (types.has(\"italic\")) return `_${t}_`;\n if (types.has(\"strike\")) return `~${t}~`;\n if (types.has(\"code\")) return `\\`${t}\\``;\n }\n if (!hasColorFont && semanticCount === 0 && types.has(\"highlight\") && !hl.color)\n return `^${t}^`;\n\n // Everything else (color/font/size, combined marks, underline) → styled span.\n const props = marksToProps(marks);\n const out: string[] = [];\n if (props.color) out.push(`color: ${props.color}`);\n if (props.family) out.push(`family: ${props.family}`);\n if (props.size) out.push(`size: ${props.size}`);\n if (props.weight) out.push(`weight: ${props.weight}`);\n if (props.italic === \"true\") out.push(`italic: true`);\n if (props.underline) out.push(`underline: true`);\n if (props.strike) out.push(`strike: true`);\n if (props.bg) out.push(`bg: ${props.bg}`);\n if (props.valign) out.push(`valign: ${props.valign}`);\n return out.length ? `[${t}]{ ${out.join(\"; \")} }` : t;\n}\n\n/**\n * Serialize a block's inline content to .it text, plus any block-level style props.\n * Whole-line case (a single uniformly-styled text run) → clean line-level props;\n * partial styling (multiple runs / mixed marks) → inline marks + styled spans.\n * `align` is always block-level.\n */\n/** Mark types the serializer can faithfully represent in `.it` (→ core-renderable). */\nconst SUPPORTED_MARKS = new Set([\n \"bold\",\n \"italic\",\n \"underline\",\n \"strike\",\n \"code\",\n \"highlight\",\n \"textStyle\",\n \"link\",\n \"subscript\",\n \"superscript\",\n]);\n\n/**\n * Fidelity guard: walk a TipTap doc for mark types the serializer can't represent\n * in `.it` (so they'd be lost on save and wouldn't print through core). Returns the\n * sorted unique unsupported mark types. Normally empty — every toolbar mark is\n * supported and TipTap drops unregistered marks on paste — so this catches\n * regressions (a new mark added without a serializer) rather than everyday use.\n */\nexport function detectUnsupportedStyling(node: JSONContent): string[] {\n const found = new Set<string>();\n const walk = (n: JSONContent) => {\n for (const m of (n.marks || []) as { type: string }[]) {\n if (!SUPPORTED_MARKS.has(m.type)) found.add(m.type);\n }\n for (const c of n.content || []) walk(c);\n };\n walk(node);\n return [...found].sort();\n}\n\nfunction inlineToSource(node: JSONContent): {\n text: string;\n props: Record<string, string>;\n} {\n const children = node.content || [];\n const align: Record<string, string> =\n node.attrs?.textAlign && node.attrs.textAlign !== \"left\"\n ? { align: String(node.attrs.textAlign) }\n : {};\n\n // Whole-line: exactly one text run → keep its style as line-level props.\n if (children.length === 1 && children[0].type === \"text\") {\n return {\n text: children[0].text || \"\",\n props: { ...marksToProps(children[0].marks as Mark[]), ...align },\n };\n }\n // Partial styling → marks/spans inline, no block-level style props.\n return { text: children.map(runToInlineText).join(\"\"), props: { ...align } };\n}\n\n/**\n * Extract plain text content from a TipTap node (no marks).\n * HardBreak nodes become literal \\n (backslash-n). Used for code blocks.\n */\nfunction extractText(node: JSONContent): string {\n if (!node.content) return \"\";\n return node.content\n .map((child) => {\n if (child.type === \"text\") return child.text || \"\";\n if (child.type === \"hardBreak\") return \"\\\\n\";\n return extractText(child);\n })\n .join(\"\");\n}\n\n/**\n * Merge mark-derived style props with existing (non-style) props.\n * Mark props override existing style keys; non-style keys are preserved.\n */\nfunction mergeProps(\n existingRaw: unknown,\n markProps: Record<string, string>,\n exclude?: Set<string>,\n): Record<string, string> {\n const existing = parseProps(existingRaw);\n // Remove mark-managed keys from existing (they'll come from marks)\n for (const key of MARK_STYLE_KEYS) delete existing[key];\n // Also remove any explicitly excluded keys\n if (exclude) for (const key of exclude) delete existing[key];\n return { ...existing, ...markProps };\n}\n\nfunction normalizeKeyword(keyword: string): string {\n const k = keyword.toLowerCase();\n return KEYWORD_ALIASES[k] || k;\n}\n\nfunction lineKeyword(trimmedLine: string): string | null {\n if (trimmedLine === \"---\") return \"divider\";\n const m = trimmedLine.match(/^([a-zA-Z][\\w-]*):/);\n if (!m) return null;\n return normalizeKeyword(m[1]);\n}\n\nfunction parsedBlockKeyword(blockType: string): string {\n return normalizeKeyword(blockType);\n}\n\nfunction keywordsMatch(sourceKey: string, parsedKey: string): boolean {\n if (sourceKey === parsedKey) return true;\n // Some callout aliases normalize to info in parser output.\n if (\n sourceKey === \"info\" &&\n [\"tip\", \"warning\", \"danger\", \"success\"].includes(parsedKey)\n ) {\n return true;\n }\n if (\n parsedKey === \"info\" &&\n [\"tip\", \"warning\", \"danger\", \"success\"].includes(sourceKey)\n ) {\n return true;\n }\n return false;\n}\n\nfunction parseInlineProps(rest: string): {\n content: string;\n properties: Record<string, string>;\n} {\n if (!rest) return { content: \"\", properties: {} };\n const parts = rest.split(\" | \");\n let content = parts[0] || \"\";\n const properties: Record<string, string> = {};\n\n for (let i = 1; i < parts.length; i++) {\n const seg = parts[i];\n const m = seg.match(/^([a-zA-Z_][\\w-]*)\\s*:\\s*(.*)$/);\n if (!m) {\n // Keep literal text segments that are not valid IT pipe props.\n content += ` | ${seg}`;\n continue;\n }\n properties[m[1]] = m[2];\n }\n\n return { content, properties };\n}\n\nfunction fallbackLineToBlock(trimmedLine: string): {\n type: string;\n content?: string;\n properties?: Record<string, string>;\n inline?: InlineNode[];\n} | null {\n if (trimmedLine === \"---\") return { type: \"divider\" };\n const m = trimmedLine.match(/^([a-zA-Z][\\w-]*):\\s*(.*)$/);\n if (!m) return null;\n\n const type = normalizeKeyword(m[1]);\n const rest = m[2] || \"\";\n const { content, properties } = parseInlineProps(rest);\n // Parse the content's inline marks/spans (*bold*, [text]{…}) via core so they\n // become TipTap marks. Core preserves {{vars}}, so templates are unaffected.\n let inline: InlineNode[] | undefined;\n try {\n inline = parseIntentText(`text: ${content}`).blocks[0]\n ?.inline as InlineNode[] | undefined;\n } catch {\n inline = undefined;\n }\n return { type, content, properties, inline };\n}\n\n/* ── Source → Doc ─────────────────────────────────────────── */\n\n/**\n * Convert IntentText source to TipTap JSON content\n */\n/** Match a bullet (`- x` / `* x`) or ordered (`1. x`) list line → its item text. */\nfunction listLineMatch(\n trimmed: string,\n): { ordered: boolean; text: string } | null {\n const bullet = trimmed.match(/^[-*]\\s+(.*)$/);\n if (bullet) return { ordered: false, text: bullet[1] };\n const ordered = trimmed.match(/^\\d+\\.\\s+(.*)$/);\n if (ordered) return { ordered: true, text: ordered[1] };\n return null;\n}\n\n/** A TipTap listItem wrapping a single paragraph of the item text. */\nfunction makeListItem(text: string): JSONContent {\n return {\n type: \"listItem\",\n content: [{ type: \"paragraph\", content: textToContent(text) }],\n };\n}\n\nexport function sourceToDoc(source: string): JSONContent {\n if (!source.trim()) {\n return {\n type: \"doc\",\n content: [{ type: \"paragraph\" }],\n };\n }\n\n const doc = parseIntentText(source);\n const content: JSONContent[] = [];\n\n for (const block of doc.blocks) {\n const node = blockToNode(block);\n if (node) content.push(node);\n }\n\n // Also handle comment lines (// ...) that the parser might skip\n const lines = source.split(\"\\n\");\n let blockIdx = 0;\n const result: JSONContent[] = [];\n\n for (let li = 0; li < lines.length; li++) {\n const line = lines[li];\n const trimmed = line.trim();\n\n // Skip empty lines\n if (!trimmed) continue;\n\n // Document-level metadata / layout blocks (page:, meta:, font:, header:,\n // footer:, watermark:) are not body content. Render them as a subtle preserved\n // chip (not raw \"| size: A4\" text) and keep the exact source line for\n // round-trip. Consume the matching parsed block to keep the stream aligned.\n {\n const mkw = lineKeyword(trimmed);\n if (mkw && META_KEYWORDS.has(mkw)) {\n result.push({ type: \"itMeta\", attrs: { raw: trimmed } });\n const pType = doc.blocks[blockIdx]?.type;\n if (pType && keywordsMatch(mkw, parsedBlockKeyword(pType))) blockIdx++;\n continue;\n }\n // Trust / history blocks → styled chip, exact source preserved.\n if (mkw && TRUST_KEYWORDS.has(mkw)) {\n result.push({ type: \"itTrust\", attrs: { raw: trimmed, keyword: mkw } });\n const pType = doc.blocks[blockIdx]?.type;\n if (pType && keywordsMatch(mkw, parsedBlockKeyword(pType))) blockIdx++;\n continue;\n }\n // Metric / total → label-left / value-right row, exact source preserved.\n if (mkw === \"metric\") {\n result.push({ type: \"itMetric\", attrs: { raw: trimmed } });\n const pType = doc.blocks[blockIdx]?.type;\n if (pType && keywordsMatch(mkw, parsedBlockKeyword(pType))) blockIdx++;\n continue;\n }\n // Scoped document style rule → visible chip; the rule itself is applied\n // live to the canvas by VisualEditor (documentStyleCSS). Raw preserved.\n if (mkw === \"style\") {\n result.push({ type: \"itStyleRule\", attrs: { raw: trimmed } });\n const pType = doc.blocks[blockIdx]?.type;\n if (pType && keywordsMatch(mkw, parsedBlockKeyword(pType))) blockIdx++;\n continue;\n }\n }\n\n // Group a run of bullet/ordered list lines into one TipTap list node, so\n // lists round-trip as list-items (not generic blocks). docToSource emits\n // `- item` / `N. item` for these.\n const listStart = listLineMatch(trimmed);\n if (listStart) {\n const ordered = listStart.ordered;\n const items: JSONContent[] = [];\n let lj = li;\n while (lj < lines.length) {\n const t = lines[lj].trim();\n const m = t ? listLineMatch(t) : null;\n if (!m || m.ordered !== ordered) break;\n items.push(makeListItem(m.text));\n // If this list item is a top-level block (not a section child), it also\n // sits in `content` — consume it so the trailing append doesn't dupe it.\n const pType = doc.blocks[blockIdx]?.type;\n if (pType === \"list-item\" || pType === \"step-item\") blockIdx++;\n lj++;\n }\n result.push({\n type: ordered ? \"orderedList\" : \"bulletList\",\n content: items,\n });\n li = lj - 1; // -1: the for-loop will increment\n continue;\n }\n\n // Group a run of `| a | b | c |` pipe-table lines into one itTable node, so\n // tables render instead of vanishing. The table is a section child (not a\n // top-level block), so we do NOT touch blockIdx. docToSource emits the\n // `| ... |` lines back.\n if (\n trimmed.startsWith(\"|\") &&\n trimmed.endsWith(\"|\") &&\n (trimmed.match(/\\|/g) || []).length >= 3\n ) {\n const rows: string[][] = [];\n let lj = li;\n while (lj < lines.length) {\n const t = lines[lj].trim();\n if (!(t.startsWith(\"|\") && t.endsWith(\"|\"))) break;\n rows.push(\n t\n .slice(1, -1)\n .split(\"|\")\n .map((c) => c.trim()),\n );\n lj++;\n }\n result.push({ type: \"itTable\", attrs: { rows: JSON.stringify(rows) } });\n li = lj - 1;\n continue;\n }\n\n // Comment lines\n if (trimmed.startsWith(\"//\")) {\n result.push({\n type: \"itComment\",\n content: trimmed.slice(2).trim()\n ? [{ type: \"text\", text: trimmed.slice(2).trim() }]\n : [],\n });\n continue;\n }\n\n // Code block fence — skip, handled by parser\n if (trimmed.startsWith(\"```\")) continue;\n\n const sourceKey = lineKeyword(trimmed);\n\n // Keep text/template lines literal to avoid parser normalization\n // (e.g. markdown marker stripping or placeholder mutation).\n if (sourceKey && (sourceKey === \"text\" || trimmed.includes(\"{{\"))) {\n const rawBlock = fallbackLineToBlock(trimmed);\n if (rawBlock) {\n const node = blockToNode(rawBlock);\n if (node) result.push(node);\n\n // Consume matching parsed block to keep parser index aligned.\n if (blockIdx < doc.blocks.length) {\n const parsedKey = parsedBlockKeyword(doc.blocks[blockIdx].type);\n if (keywordsMatch(sourceKey, parsedKey)) {\n blockIdx++;\n }\n }\n continue;\n }\n }\n\n // If parser produced a block, only consume it when keyword matches current line.\n if (blockIdx < content.length && sourceKey) {\n const nextParsed = doc.blocks[blockIdx];\n const parsedKey = parsedBlockKeyword(nextParsed.type);\n if (keywordsMatch(sourceKey, parsedKey)) {\n result.push(content[blockIdx]);\n blockIdx++;\n continue;\n }\n }\n\n // Fallback: parse line directly so raw source lines are never dropped.\n const rawBlock = fallbackLineToBlock(trimmed);\n if (rawBlock) {\n const node = blockToNode(rawBlock);\n if (node) result.push(node);\n continue;\n }\n\n // Final fallback: keep parser progression if nothing else matched.\n if (blockIdx < content.length) {\n result.push(content[blockIdx]);\n blockIdx++;\n }\n }\n\n // If we missed any blocks, append them\n while (blockIdx < content.length) {\n result.push(content[blockIdx]);\n blockIdx++;\n }\n\n return {\n type: \"doc\",\n content: result.length > 0 ? result : [{ type: \"paragraph\" }],\n };\n}\n\nfunction blockToNode(block: {\n type: string;\n content?: string;\n properties?: Record<string, string | number>;\n inline?: InlineNode[];\n}): JSONContent | null {\n const { type, content, properties, inline } = block;\n const text = content || \"\";\n\n // Build content from the inline AST (so *bold*, [text]{…} spans → real marks),\n // then layer any line-level style props (whole-line styling) as marks on top.\n let textContent = inlineToContent(inline, text);\n textContent = applyPropsAsMarks(textContent, properties);\n\n // Serialize all props to JSON string for TipTap attrs (used by extensions.ts buildStyle)\n const propsJson = properties\n ? JSON.stringify(\n Object.fromEntries(\n Object.entries(properties).map(([k, v]) => [k, String(v)]),\n ),\n )\n : \"{}\";\n\n // textAlign from 'align' property (for TipTap TextAlign extension)\n const textAlign = properties?.align ? String(properties.align) : undefined;\n\n // Title, Section, Sub → dedicated heading nodes\n if (type in HEADING_MAP) {\n return {\n type: HEADING_MAP[type],\n attrs: { props: propsJson, ...(textAlign && { textAlign }) },\n content: textContent.length ? textContent : undefined,\n };\n }\n\n // Summary\n if (type === \"summary\") {\n return {\n type: \"itSummary\",\n attrs: { props: propsJson, ...(textAlign && { textAlign }) },\n content: textContent.length ? textContent : undefined,\n };\n }\n\n // Text / body-text → paragraph. Core block properties (end/leading/\n // space-before/space-after) become real paragraph attributes so the\n // visual editor renders them AND serializes them back (see block-props.ts).\n if (type === \"text\" || type === \"body-text\") {\n const attrs: Record<string, string> = {};\n if (textAlign) attrs.textAlign = textAlign;\n if (properties?.end) attrs.end = String(properties.end);\n if (properties?.leading) attrs.leading = String(properties.leading);\n if (properties?.[\"space-before\"])\n attrs.spaceBefore = String(properties[\"space-before\"]);\n if (properties?.[\"space-after\"])\n attrs.spaceAfter = String(properties[\"space-after\"]);\n return {\n type: \"paragraph\",\n ...(Object.keys(attrs).length && { attrs }),\n content: textContent.length ? textContent : undefined,\n };\n }\n\n // Callouts\n if (CALLOUT_TYPES.has(type)) {\n const variant =\n type === \"info\" ? String(properties?.type || \"info\").toLowerCase() : type;\n const safeVariant = CALLOUT_TYPES.has(variant) ? variant : \"info\";\n\n return {\n type: \"itCallout\",\n attrs: { variant: safeVariant, props: propsJson },\n content: textContent.length ? textContent : undefined,\n };\n }\n\n // Quote\n if (type === \"quote\") {\n return {\n type: \"itQuote\",\n attrs: {\n by: properties?.by ? String(properties.by) : \"\",\n props: propsJson,\n ...(textAlign && { textAlign }),\n },\n content: textContent.length ? textContent : undefined,\n };\n }\n\n // Code (no marks on code blocks)\n if (type === \"code\") {\n return {\n type: \"itCode\",\n attrs: {\n lang: properties?.lang ? String(properties.lang) : \"\",\n props: propsJson,\n },\n content: text ? [{ type: \"text\", text }] : undefined,\n };\n }\n\n // Divider\n if (type === \"divider\") {\n return { type: \"itDivider\" };\n }\n\n // Break (page break)\n if (type === \"break\") {\n return { type: \"itBreak\" };\n }\n\n // All other keywords → generic block\n const propStr = properties\n ? Object.entries(properties)\n .filter(([, v]) => v !== undefined && v !== \"\")\n .map(([k, v]) => `${k}: ${v}`)\n .join(\" | \")\n : \"\";\n\n return {\n type: \"itGenericBlock\",\n attrs: { keyword: type, properties: propStr, props: propsJson },\n content: textContent.length ? textContent : undefined,\n };\n}\n\n/* ── Doc → Source ─────────────────────────────────────────── */\n\n/**\n * Convert TipTap JSON back to IntentText source\n */\nexport function docToSource(doc: JSONContent): string {\n if (!doc.content) return \"\";\n\n const lines: string[] = [];\n\n for (const node of doc.content) {\n lines.push(...nodeToLines(node));\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Convert a single TipTap node to one or more IT source lines. */\nfunction nodeToLines(node: JSONContent): string[] {\n // Lists → canonical `.it` bullet syntax so they round-trip as list-items, not\n // text. `- item` parses back to a list-item; `N. item` to a step-item.\n if (node.type === \"bulletList\" && node.content) {\n return node.content.flatMap((item) => {\n if (!item.content) return [];\n return item.content.map((child) => {\n const { text: t, props: mp } = inlineToSource(child);\n return `- ${t}${formatProps(mp)}`;\n });\n });\n }\n if (node.type === \"orderedList\" && node.content) {\n let idx = 1;\n return node.content.flatMap((item) => {\n if (!item.content) return [];\n return item.content.map((child) => {\n const { text: t, props: mp } = inlineToSource(child);\n return `${idx++}. ${t}${formatProps(mp)}`;\n });\n });\n }\n\n const line = nodeToLine(node);\n return line !== null ? [line] : [];\n}\n\nfunction nodeToLine(node: JSONContent): string | null {\n const { text, props: markProps } = inlineToSource(node);\n\n switch (node.type) {\n case \"itTitle\": {\n const merged = mergeProps(node.attrs?.props, markProps);\n return `title: ${text}${formatProps(merged)}`;\n }\n\n case \"itSummary\": {\n const merged = mergeProps(node.attrs?.props, markProps);\n return `summary: ${text}${formatProps(merged)}`;\n }\n\n case \"itSection\": {\n const merged = mergeProps(node.attrs?.props, markProps);\n return `section: ${text}${formatProps(merged)}`;\n }\n\n case \"itSub\": {\n const merged = mergeProps(node.attrs?.props, markProps);\n return `sub: ${text}${formatProps(merged)}`;\n }\n\n case \"paragraph\": {\n // Core block properties stored as paragraph attributes (block-props.ts)\n // → written back onto the line so PDF output matches the screen.\n const a = node.attrs || {};\n const blockProps: Record<string, string> = {};\n if (a.end) blockProps.end = String(a.end);\n if (a.leading) blockProps.leading = String(a.leading);\n if (a.spaceBefore) blockProps[\"space-before\"] = String(a.spaceBefore);\n if (a.spaceAfter) blockProps[\"space-after\"] = String(a.spaceAfter);\n return `text: ${text}${formatProps({ ...blockProps, ...markProps })}`;\n }\n\n case \"itCallout\": {\n const variant = node.attrs?.variant || \"tip\";\n const merged = mergeProps(\n node.attrs?.props,\n markProps,\n new Set([\"variant\"]),\n );\n if (variant === \"info\") {\n return `info: ${text}${formatProps(merged)}`;\n }\n return `info: ${text} | type: ${variant}${formatProps(merged, new Set([\"type\"]))}`;\n }\n\n case \"itQuote\": {\n const by = node.attrs?.by;\n const byPart = by ? ` | by: ${by}` : \"\";\n const merged = mergeProps(node.attrs?.props, markProps, new Set([\"by\"]));\n return `quote: ${text}${byPart}${formatProps(merged)}`;\n }\n\n case \"itCode\": {\n const lang = node.attrs?.lang || \"\";\n // Code is literal — never apply inline marks/spans.\n return `\\`\\`\\`${lang}\\n${extractText(node)}\\n\\`\\`\\``;\n }\n\n case \"itDivider\":\n return \"divider:\";\n\n case \"itTable\": {\n let rows: string[][] = [];\n try {\n rows = JSON.parse(node.attrs?.rows || \"[]\");\n } catch {\n rows = [];\n }\n return rows.map((r) => `| ${r.join(\" | \")} |`).join(\"\\n\");\n }\n\n case \"itMeta\":\n return node.attrs?.raw || \"\";\n\n case \"itTrust\":\n return node.attrs?.raw || \"\";\n\n case \"itMetric\":\n return node.attrs?.raw || \"\";\n\n case \"itStyleRule\":\n return node.attrs?.raw || \"\";\n\n case \"itBreak\":\n return \"break:\";\n\n case \"itComment\":\n return text ? `// ${text}` : \"//\";\n\n case \"itGenericBlock\": {\n const kw = node.attrs?.keyword || \"text\";\n const merged = mergeProps(node.attrs?.props, markProps);\n return `${kw}: ${text}${formatProps(merged)}`;\n }\n\n default:\n return text ? `text: ${text}${formatProps(markProps)}` : null;\n }\n}\n","// Keyword Style Map — Maps IT pipe properties to CSS\n// When user writes: text: Hello | align: center | color: #555\n// The editor applies matching CSS styles in real time.\n// Unknown properties are silently ignored and preserved.\n\nexport type StyleProperty =\n | \"align\"\n | \"color\"\n | \"bgcolor\"\n | \"size\"\n | \"weight\"\n | \"style\"\n | \"border\"\n | \"padding\"\n | \"indent\"\n | \"opacity\"\n | \"radius\"\n | \"shadow\"\n | \"width\"\n | \"height\"\n | \"spacing\"\n | \"columns\"\n | \"font\"\n | \"leading\"\n | \"striped\"\n | \"icon\"\n | \"blur\"\n | \"angle\"\n | \"family\"\n | \"margins\";\n\ninterface StyleRule {\n property: StyleProperty;\n css: string; // CSS property name\n transform?: (v: string) => string; // optional value transform\n}\n\n// Build style map: keyword → array of rules\nfunction direct(property: StyleProperty, css: string): StyleRule {\n return { property, css };\n}\n\n// Common property sets reused across keywords\nconst TEXT_STYLES: StyleRule[] = [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n direct(\"weight\", \"fontWeight\"),\n { property: \"style\", css: \"fontStyle\" },\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"padding\", \"padding\"),\n direct(\"indent\", \"paddingLeft\"),\n direct(\"opacity\", \"opacity\"),\n];\n\nconst CALLOUT_STYLES: StyleRule[] = [\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"color\", \"color\"),\n direct(\"border\", \"borderLeft\"),\n];\n\nconst CHIP_STYLES: StyleRule[] = [\n direct(\"color\", \"borderColor\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n];\n\nexport const KEYWORD_STYLES: Record<string, StyleRule[]> = {\n // ── Identity ──\n title: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n direct(\"weight\", \"fontWeight\"),\n direct(\"font\", \"fontFamily\"),\n ],\n summary: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n { property: \"style\", css: \"fontStyle\" },\n ],\n\n // ── Structure ──\n section: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n direct(\"weight\", \"fontWeight\"),\n direct(\"border\", \"borderBottom\"),\n direct(\"spacing\", \"marginTop\"),\n ],\n sub: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n direct(\"weight\", \"fontWeight\"),\n ],\n divider: [\n { property: \"style\", css: \"borderStyle\" },\n direct(\"color\", \"borderColor\"),\n direct(\"width\", \"borderTopWidth\"),\n direct(\"spacing\", \"margin\"),\n ],\n\n // ── Content ──\n text: [...TEXT_STYLES],\n tip: [...CALLOUT_STYLES],\n info: [...CALLOUT_STYLES],\n warning: [...CALLOUT_STYLES],\n danger: [...CALLOUT_STYLES],\n success: [...CALLOUT_STYLES],\n quote: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n { property: \"style\", css: \"fontStyle\" },\n direct(\"border\", \"borderLeft\"),\n direct(\"padding\", \"paddingLeft\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n ],\n cite: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n { property: \"style\", css: \"fontStyle\" },\n ],\n def: [\n direct(\"color\", \"color\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"border\", \"borderLeft\"),\n direct(\"padding\", \"paddingLeft\"),\n ],\n caption: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n { property: \"style\", css: \"fontStyle\" },\n ],\n footnote: [direct(\"color\", \"color\"), direct(\"size\", \"fontSize\")],\n byline: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n { property: \"style\", css: \"fontStyle\" },\n direct(\"weight\", \"fontWeight\"),\n ],\n epigraph: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n { property: \"style\", css: \"fontStyle\" },\n direct(\"padding\", \"padding\"),\n ],\n dedication: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n { property: \"style\", css: \"fontStyle\" },\n direct(\"padding\", \"padding\"),\n ],\n\n // ── Media ──\n image: [\n direct(\"width\", \"width\"),\n direct(\"height\", \"height\"),\n direct(\"radius\", \"borderRadius\"),\n direct(\"border\", \"border\"),\n direct(\"opacity\", \"opacity\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n {\n property: \"shadow\",\n css: \"boxShadow\",\n transform: () => \"0 4px 12px rgba(0,0,0,0.15)\",\n },\n ],\n figure: [\n direct(\"width\", \"width\"),\n direct(\"align\", \"textAlign\"),\n direct(\"border\", \"border\"),\n direct(\"padding\", \"padding\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n {\n property: \"shadow\",\n css: \"boxShadow\",\n transform: () => \"0 4px 12px rgba(0,0,0,0.15)\",\n },\n ],\n link: [direct(\"color\", \"color\"), direct(\"weight\", \"fontWeight\")],\n ref: [direct(\"color\", \"color\"), { property: \"style\", css: \"fontStyle\" }],\n embed: [\n direct(\"width\", \"width\"),\n direct(\"height\", \"height\"),\n direct(\"border\", \"border\"),\n direct(\"radius\", \"borderRadius\"),\n ],\n\n // ── Data ──\n metric: [\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n direct(\"align\", \"textAlign\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"border\", \"border\"),\n direct(\"padding\", \"padding\"),\n ],\n columns: [\n direct(\"border\", \"border\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"padding\", \"padding\"),\n direct(\"size\", \"fontSize\"),\n direct(\"align\", \"textAlign\"),\n ],\n row: [\n direct(\"border\", \"border\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"padding\", \"padding\"),\n direct(\"size\", \"fontSize\"),\n direct(\"align\", \"textAlign\"),\n ],\n input: [\n direct(\"color\", \"color\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"border\", \"borderLeft\"),\n direct(\"size\", \"fontSize\"),\n ],\n output: [\n direct(\"color\", \"color\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"border\", \"borderLeft\"),\n direct(\"size\", \"fontSize\"),\n ],\n\n // ── Code ──\n code: [\n direct(\"size\", \"fontSize\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"color\", \"color\"),\n direct(\"padding\", \"padding\"),\n direct(\"radius\", \"borderRadius\"),\n direct(\"border\", \"border\"),\n ],\n\n // ── Contact ──\n contact: [\n direct(\"color\", \"color\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"border\", \"border\"),\n direct(\"padding\", \"padding\"),\n direct(\"size\", \"fontSize\"),\n ],\n deadline: [\n direct(\"color\", \"color\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"weight\", \"fontWeight\"),\n direct(\"size\", \"fontSize\"),\n ],\n\n // ── Agent workflow chips ──\n step: [...CHIP_STYLES],\n decision: [...CHIP_STYLES],\n gate: [...CHIP_STYLES],\n trigger: [...CHIP_STYLES],\n loop: [...CHIP_STYLES],\n parallel: [...CHIP_STYLES],\n call: [...CHIP_STYLES],\n wait: [...CHIP_STYLES],\n checkpoint: [...CHIP_STYLES],\n error: [...CHIP_STYLES],\n result: [...CHIP_STYLES],\n audit: [...CHIP_STYLES],\n signal: [...CHIP_STYLES],\n handoff: [...CHIP_STYLES],\n retry: [...CHIP_STYLES],\n progress: [...CHIP_STYLES],\n tool: [...CHIP_STYLES],\n prompt: [...CHIP_STYLES],\n memory: [...CHIP_STYLES],\n policy: [...CHIP_STYLES],\n context: [...CHIP_STYLES],\n\n // ── Trust badges ──\n track: [...CHIP_STYLES],\n approve: [...CHIP_STYLES],\n sign: [...CHIP_STYLES],\n freeze: [...CHIP_STYLES],\n revision: [...CHIP_STYLES],\n amendment: [...CHIP_STYLES],\n history: [direct(\"color\", \"borderColor\")],\n\n // ── v2.13 ──\n assert: [\n direct(\"color\", \"borderColor\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"border\", \"borderLeft\"),\n ],\n secret: [\n direct(\"color\", \"color\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"blur\", \"filter\"),\n ],\n\n // ── Layout ──\n watermark: [\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n direct(\"opacity\", \"opacity\"),\n ],\n signline: [direct(\"color\", \"color\"), direct(\"width\", \"width\")],\n};\n\n/**\n * Build a CSSProperties-like object from a block's pipe properties.\n * Unknown properties are silently ignored.\n */\nexport function computeKeywordStyles(\n blockType: string,\n properties: Record<string, string>,\n): Record<string, string> {\n const rules = KEYWORD_STYLES[blockType];\n if (!rules) return {};\n\n const styles: Record<string, string> = {};\n\n for (const rule of rules) {\n const value = properties[rule.property];\n if (!value) continue;\n\n if (rule.transform) {\n styles[rule.css] = rule.transform(value);\n } else {\n styles[rule.css] = value;\n }\n }\n\n return styles;\n}\n\n/**\n * Returns which style properties are recognised for a given keyword.\n * Used by editor autocomplete to suggest pipe properties.\n */\nexport function getStyleProperties(blockType: string): StyleProperty[] {\n return (KEYWORD_STYLES[blockType] ?? []).map((r) => r.property);\n}\n","// TipTap extensions for IntentText block types\n// Maps IT keywords to ProseMirror nodes rendered in a Google Docs-like editor\n\nimport { Node, mergeAttributes } from \"@tiptap/core\";\nimport { computeKeywordStyles } from \"./keyword-styles\";\n\n// Helper: build inline style string from pipe properties\nfunction buildStyle(keyword: string, props: Record<string, string>): string {\n const styles = computeKeywordStyles(keyword, props);\n // Word-parity spacing — universal core style props on every block type,\n // mirroring core's STYLE_PROPERTIES (leading/space-before/space-after).\n if (props.leading) styles.lineHeight = props.leading;\n if (props[\"space-before\"]) styles.marginTop = props[\"space-before\"];\n if (props[\"space-after\"]) styles.marginBottom = props[\"space-after\"];\n return Object.entries(styles)\n .map(([k, v]) => `${k.replace(/([A-Z])/g, \"-$1\").toLowerCase()}:${v}`)\n .join(\";\");\n}\n\n// Two-sided row (`end:` property — core renders it on title/section/sub/text):\n// expose the end value as data-it-end so CSS turns the block into a flex\n// split row (`.it-split` parity) with the value as generated content.\nfunction endAttrs(props: Record<string, string>): Record<string, string> {\n return props.end ? { \"data-it-end\": props.end } : {};\n}\n\n// ── Title ─────────────────────────────────────────────────────\nexport const ITTitle = Node.create({\n name: \"itTitle\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n addAttributes() {\n return {\n props: {\n default: \"{}\",\n parseHTML: (el) => el.getAttribute(\"data-props\") || \"{}\",\n },\n };\n },\n\n parseHTML() {\n return [{ tag: 'h1[data-it-type=\"title\"]' }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const props = safeParse(node.attrs.props);\n const attrs = mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"title\",\n class: \"it-doc-title\",\n style: buildStyle(\"title\", props),\n ...endAttrs(props),\n });\n return props.end\n ? [\"h1\", attrs, [\"span\", { class: \"it-split-main\" }, 0]]\n : [\"h1\", attrs, 0];\n },\n});\n\n// ── Summary ───────────────────────────────────────────────────\nexport const ITSummary = Node.create({\n name: \"itSummary\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n addAttributes() {\n return {\n props: { default: \"{}\" },\n };\n },\n\n parseHTML() {\n return [{ tag: 'p[data-it-type=\"summary\"]' }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const props = safeParse(node.attrs.props);\n return [\n \"p\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"summary\",\n class: \"it-doc-summary\",\n style: buildStyle(\"summary\", props),\n }),\n 0,\n ];\n },\n});\n\n// ── Section (H2) ─────────────────────────────────────────────\nexport const ITSection = Node.create({\n name: \"itSection\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n addAttributes() {\n return {\n props: { default: \"{}\" },\n };\n },\n\n parseHTML() {\n return [{ tag: 'h2[data-it-type=\"section\"]' }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const props = safeParse(node.attrs.props);\n const attrs = mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"section\",\n class: \"it-doc-section\",\n style: buildStyle(\"section\", props),\n ...endAttrs(props),\n });\n return props.end\n ? [\"h2\", attrs, [\"span\", { class: \"it-split-main\" }, 0]]\n : [\"h2\", attrs, 0];\n },\n});\n\n// ── Sub (H3) ─────────────────────────────────────────────────\nexport const ITSub = Node.create({\n name: \"itSub\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n addAttributes() {\n return {\n props: { default: \"{}\" },\n };\n },\n\n parseHTML() {\n return [{ tag: 'h3[data-it-type=\"sub\"]' }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const props = safeParse(node.attrs.props);\n const attrs = mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"sub\",\n class: \"it-doc-sub\",\n style: buildStyle(\"sub\", props),\n ...endAttrs(props),\n });\n return props.end\n ? [\"h3\", attrs, [\"span\", { class: \"it-split-main\" }, 0]]\n : [\"h3\", attrs, 0];\n },\n});\n\n// ── Callout (tip, info, warning, danger, success) ────────────\nexport const ITCallout = Node.create({\n name: \"itCallout\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n addAttributes() {\n return {\n variant: {\n default: \"tip\",\n parseHTML: (el) => el.getAttribute(\"data-variant\") || \"tip\",\n renderHTML: (attrs) => ({ \"data-variant\": attrs.variant }),\n },\n props: { default: \"{}\" },\n };\n },\n\n parseHTML() {\n return [{ tag: 'div[data-it-type=\"callout\"]' }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const variant = node.attrs.variant || \"tip\";\n const props = safeParse(node.attrs.props);\n const icons: Record<string, string> = {\n tip: \"tip\",\n info: \"info\",\n warning: \"warning\",\n danger: \"danger\",\n success: \"success\",\n };\n return [\n \"div\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"callout\",\n \"data-variant\": variant,\n class: `it-doc-callout it-doc-callout-${variant}`,\n style: buildStyle(variant, props),\n }),\n [\n \"span\",\n {\n class: `it-doc-callout-icon it-doc-callout-icon-${icons[variant] || \"tip\"}`,\n contenteditable: \"false\",\n },\n \"\",\n ],\n [\"span\", { class: \"it-doc-callout-text\" }, 0],\n ];\n },\n});\n\n// ── Quote ─────────────────────────────────────────────────────\nexport const ITQuote = Node.create({\n name: \"itQuote\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n addAttributes() {\n return {\n by: { default: \"\" },\n props: { default: \"{}\" },\n };\n },\n\n parseHTML() {\n return [{ tag: 'blockquote[data-it-type=\"quote\"]' }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const props = safeParse(node.attrs.props);\n return [\n \"blockquote\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"quote\",\n class: \"it-doc-quote\",\n style: buildStyle(\"quote\", props),\n }),\n 0,\n ];\n },\n});\n\n// ── Code Block ────────────────────────────────────────────────\nexport const ITCode = Node.create({\n name: \"itCode\",\n group: \"block\",\n content: \"text*\",\n marks: \"\",\n code: true,\n defining: true,\n\n addAttributes() {\n return {\n lang: { default: \"\" },\n props: { default: \"{}\" },\n };\n },\n\n parseHTML() {\n return [{ tag: \"pre\" }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const props = safeParse(node.attrs.props);\n return [\n \"pre\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"code\",\n class: \"it-doc-code\",\n \"data-lang\": node.attrs.lang || \"\",\n style: buildStyle(\"code\", props),\n }),\n [\"code\", 0],\n ];\n },\n});\n\n// ── Divider ───────────────────────────────────────────────────\nexport const ITDivider = Node.create({\n name: \"itDivider\",\n group: \"block\",\n atom: true,\n\n parseHTML() {\n return [{ tag: \"hr\" }];\n },\n renderHTML({ HTMLAttributes }) {\n return [\"hr\", mergeAttributes(HTMLAttributes, { class: \"it-doc-divider\" })];\n },\n});\n\n// ── Metadata chip ─────────────────────────────────────────────\n// Document-level metadata/layout lines (page:, meta:, font:, header:, …) shown as\n// a subtle preserved chip instead of raw body text. `raw` holds the exact source\n// line for round-trip.\nexport const ITMeta = Node.create({\n name: \"itMeta\",\n group: \"block\",\n atom: true,\n\n addAttributes() {\n return {\n raw: {\n default: \"\",\n parseHTML: (el) => el.getAttribute(\"data-raw\") || \"\",\n renderHTML: (attrs) => ({ \"data-raw\": attrs.raw }),\n },\n };\n },\n parseHTML() {\n return [{ tag: \"div[data-it-meta]\" }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const raw = String(node.attrs.raw || \"\").replace(/\\s*\\|\\s*/g, \" · \");\n return [\n \"div\",\n mergeAttributes(HTMLAttributes, { \"data-it-meta\": \"\", class: \"it-doc-meta\" }),\n `⚙ ${raw}`,\n ];\n },\n});\n\n// ── Table ─────────────────────────────────────────────────────\n// Read-only display of a pipe table. `rows` is a JSON string of string[][]\n// (first row = headers). Editing the data is done in source mode for now; this\n// node ensures the table renders instead of vanishing in the visual editor.\nexport const ITTable = Node.create({\n name: \"itTable\",\n group: \"block\",\n atom: true,\n\n addAttributes() {\n return {\n rows: {\n default: \"[]\",\n parseHTML: (el) => el.getAttribute(\"data-rows\") || \"[]\",\n renderHTML: (attrs) => ({ \"data-rows\": attrs.rows }),\n },\n };\n },\n parseHTML() {\n return [{ tag: \"table[data-it-table]\" }];\n },\n renderHTML({ HTMLAttributes, node }) {\n let rows: string[][] = [];\n try {\n rows = JSON.parse(node.attrs.rows || \"[]\");\n } catch {\n rows = [];\n }\n const head = rows[0] || [];\n const body = rows.slice(1);\n return [\n \"table\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-table\": \"\",\n class: \"it-doc-table\",\n }),\n [\n \"thead\",\n [\"tr\", ...head.map((c) => [\"th\", tableCellAttrs(c), String(c)])],\n ],\n [\n \"tbody\",\n ...body.map((r) => [\n \"tr\",\n ...r.map((c) => [\"td\", tableCellAttrs(c), String(c)]),\n ]),\n ],\n ];\n },\n});\n\n/** Template cells ({{var}} or each:) get the variable-chip highlight. */\nfunction tableCellAttrs(cell: string): Record<string, string> {\n return /\\{\\{[^}]+\\}\\}|^each:/.test(String(cell).trim())\n ? { class: \"it-doc-var-cell\" }\n : {};\n}\n\n// ── Trust block (sign / seal / approve / freeze / amendment) ──\n// Renders tamper-evidence lines as proper styled chips instead of leaking raw\n// `| at: …` props. The exact source line is preserved in `raw` and re-emitted\n// verbatim on docToSource so the document hash never changes from a round-trip.\nfunction parseTrustLine(raw: string): {\n keyword: string;\n content: string;\n props: Record<string, string>;\n} {\n const colon = raw.indexOf(\":\");\n const keyword = (colon >= 0 ? raw.slice(0, colon) : raw).trim().toLowerCase();\n const rest = colon >= 0 ? raw.slice(colon + 1).trim() : \"\";\n const segs = rest.split(\"|\").map((s) => s.trim());\n const content = segs.shift() || \"\";\n const props: Record<string, string> = {};\n for (const seg of segs) {\n const c = seg.indexOf(\":\");\n if (c > 0) props[seg.slice(0, c).trim().toLowerCase()] = seg.slice(c + 1).trim();\n }\n return { keyword, content, props };\n}\n\nexport const ITTrust = Node.create({\n name: \"itTrust\",\n group: \"block\",\n atom: true,\n\n addAttributes() {\n return {\n raw: {\n default: \"\",\n parseHTML: (el) => el.getAttribute(\"data-raw\") || \"\",\n renderHTML: (attrs) => ({ \"data-raw\": attrs.raw }),\n },\n keyword: {\n default: \"\",\n parseHTML: (el) => el.getAttribute(\"data-trust\") || \"\",\n renderHTML: (attrs) => ({ \"data-trust\": attrs.keyword }),\n },\n };\n },\n parseHTML() {\n return [{ tag: \"div[data-it-trust]\" }];\n },\n renderHTML({ HTMLAttributes, node }) {\n // Ink-first typesetting, exactly mirroring core's print design\n // (document-css.ts .it-approval / .it-signature / .it-sealed-banner):\n // hairlines + small-caps labels, no colored fills - editor display = print.\n const { keyword, content, props } = parseTrustLine(\n String(node.attrs.raw || \"\"),\n );\n const role = props.role || props.title || \"\";\n const date = (props.at || props.date || props.time || \"\").slice(0, 10);\n const parts: (string | (string | object)[])[] = [];\n\n if (keyword === \"seal\" || keyword === \"freeze\") {\n // SEALED band - thin top+bottom rules, mono hash (core .it-sealed-banner).\n const hash =\n (keyword === \"seal\" ? content || props.hash : props.hash) || \"\";\n parts.push([\"span\", { class: \"it-doc-trust__label\" }, \"Sealed document\"]);\n if (date) parts.push([\"span\", { class: \"it-doc-trust__date\" }, date]);\n if (hash)\n parts.push([\n \"code\",\n { class: \"it-doc-trust__hash\" },\n hash.length > 20 ? hash.slice(0, 20) + \"...\" : hash,\n ]);\n } else if (keyword === \"approve\") {\n // Single hairline row: CHECK APPROVED | what | who | date(right) - the\n // check mark comes from CSS ::before, matching core's .it-approval__label.\n const who = props.by || content;\n const what = props.by ? content : \"\";\n parts.push([\"span\", { class: \"it-doc-trust__label\" }, \"Approved\"]);\n if (what) parts.push([\"span\", { class: \"it-doc-trust__what\" }, what]);\n if (who)\n parts.push([\n \"span\",\n { class: \"it-doc-trust__who\" },\n role ? `${who}, ${role}` : who,\n ]);\n if (date) parts.push([\"span\", { class: \"it-doc-trust__date\" }, date]);\n } else if (keyword === \"amend\" || keyword === \"amendment\") {\n parts.push([\"span\", { class: \"it-doc-trust__label\" }, \"Amendment\"]);\n if (content)\n parts.push([\"span\", { class: \"it-doc-trust__what\" }, content]);\n if (date) parts.push([\"span\", { class: \"it-doc-trust__date\" }, date]);\n } else {\n // sign - a signature rule line (core .it-signature): hairline rule on\n // top, name / role / date with a status flag at the line end.\n const name = content || props.by || \"\";\n const valid = !!props.hash;\n parts.push([\"span\", { class: \"it-doc-trust__name\" }, name]);\n if (role) parts.push([\"span\", { class: \"it-doc-trust__role\" }, role]);\n if (date) parts.push([\"span\", { class: \"it-doc-trust__date\" }, date]);\n parts.push([\n \"span\",\n { class: \"it-doc-trust__status\" },\n valid ? \"Signed \\u00b7 verified\" : \"Signed\",\n ]);\n }\n\n return [\n \"div\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-trust\": \"\",\n \"data-trust\": keyword,\n class: `it-doc-trust it-doc-trust--${keyword}`,\n }),\n ...parts,\n ];\n },\n});\n\n// ── Metric / total row ────────────────────────────────────────\n// `metric: Subtotal | value: 16,500 QAR | unit: …` renders as a label-left /\n// value-right row (invoice totals, KPIs). The generic block dropped `value:`\n// entirely. Raw source preserved verbatim for round-trip.\nexport const ITMetric = Node.create({\n name: \"itMetric\",\n group: \"block\",\n atom: true,\n\n addAttributes() {\n return {\n raw: {\n default: \"\",\n parseHTML: (el) => el.getAttribute(\"data-raw\") || \"\",\n renderHTML: (attrs) => ({ \"data-raw\": attrs.raw }),\n },\n };\n },\n parseHTML() {\n return [{ tag: \"div[data-it-metric]\" }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const { content, props } = parseTrustLine(String(node.attrs.raw || \"\"));\n const value = [props.value, props.unit].filter(Boolean).join(\" \");\n // A \"total\"/\"grand total\"/\"balance due\" label reads as the summary line.\n const isTotal = /\\b(total|balance due|amount due|grand)\\b/i.test(content);\n const valueIsVar = /\\{\\{[^}]+\\}\\}/.test(value);\n return [\n \"div\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-metric\": \"\",\n class: `it-doc-metric${isTotal ? \" it-doc-metric--total\" : \"\"}`,\n }),\n [\"span\", { class: \"it-doc-metric__label\" }, content],\n [\n \"span\",\n { class: `it-doc-metric__value${valueIsVar ? \" it-doc-var\" : \"\"}` },\n value,\n ],\n ];\n },\n});\n\n// ── Scoped document style rule ────────────────────────────────\n// `style: section | color: #0a7 | weight: 600` — house styling declared once,\n// document-wide. Shown as a visible chip (target + declarations) so authors can\n// SEE the rule; VisualEditor applies it live to the canvas via documentStyleCSS.\n// Raw line preserved verbatim for round-trip.\nexport const ITStyleRule = Node.create({\n name: \"itStyleRule\",\n group: \"block\",\n atom: true,\n\n addAttributes() {\n return {\n raw: {\n default: \"\",\n parseHTML: (el) => el.getAttribute(\"data-raw\") || \"\",\n renderHTML: (attrs) => ({ \"data-raw\": attrs.raw }),\n },\n };\n },\n parseHTML() {\n return [{ tag: \"div[data-it-style-rule]\" }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const { content, props } = parseTrustLine(String(node.attrs.raw || \"\"));\n const decl = Object.entries(props)\n .map(([k, v]) => `${k}: ${v}`)\n .join(\" · \");\n return [\n \"div\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-style-rule\": \"\",\n class: \"it-doc-stylerule\",\n }),\n [\"span\", { class: \"it-doc-stylerule__icon\" }, \"🎨\"],\n [\"span\", { class: \"it-doc-stylerule__target\" }, content || \"?\"],\n [\"span\", { class: \"it-doc-stylerule__decl\" }, decl],\n ];\n },\n});\n\n// ── Page Break ────────────────────────────────────────────────\nexport const ITBreak = Node.create({\n name: \"itBreak\",\n group: \"block\",\n atom: true,\n\n parseHTML() {\n return [{ tag: 'div[data-it-type=\"break\"]' }];\n },\n renderHTML({ HTMLAttributes }) {\n return [\n \"div\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"break\",\n class: \"it-doc-break\",\n }),\n ];\n },\n});\n\n// ── Generic IT Block (for all other keywords) ─────────────────\n// Renders as a styled chip/card with the keyword shown\nexport const ITGenericBlock = Node.create({\n name: \"itGenericBlock\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n addAttributes() {\n return {\n keyword: { default: \"text\" },\n properties: { default: \"\" },\n props: { default: \"{}\" },\n };\n },\n\n parseHTML() {\n return [{ tag: '[data-it-type=\"generic\"]' }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const kw = node.attrs.keyword;\n const props = safeParse(node.attrs.props);\n const linkTarget = String(\n props.to || props.url || props.href || props.file || \"\",\n ).trim();\n\n if ((kw === \"link\" || kw === \"ref\") && linkTarget) {\n return [\n \"p\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"generic\",\n \"data-keyword\": kw,\n class: `it-doc-generic it-doc-kw-${kw}`,\n style: buildStyle(kw, props),\n }),\n [\n \"a\",\n {\n class: \"it-doc-inline-link\",\n href: linkTarget,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n 0,\n ],\n ];\n }\n\n return [\n \"p\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"generic\",\n \"data-keyword\": kw,\n class: `it-doc-generic it-doc-kw-${kw}`,\n style: buildStyle(kw, props),\n }),\n [\"span\", { class: \"it-doc-generic-content\" }, 0],\n ];\n },\n});\n\n// ── Comment line (// comments in IT source) ───────────────────\nexport const ITComment = Node.create({\n name: \"itComment\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n parseHTML() {\n return [{ tag: 'p[data-it-type=\"comment\"]' }];\n },\n renderHTML({ HTMLAttributes }) {\n return [\n \"p\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"comment\",\n class: \"it-doc-comment\",\n }),\n 0,\n ];\n },\n});\n\n// ── Helpers ────────────────────────────────────────────────────\nfunction safeParse(val: string): Record<string, string> {\n try {\n return typeof val === \"string\" ? JSON.parse(val) : val || {};\n } catch {\n return {};\n }\n}\n","// Block-level core properties as first-class TipTap attributes.\n//\n// Word-parity paragraph controls (line spacing, space before/after) and the\n// two-sided row (`end:`) are CORE `.it` properties — never editor-only styling.\n// This module makes them editable in the visual editor while guaranteeing they\n// serialize back onto the block line (see bridge.ts), so the PDF (rendered from\n// the same source) always matches the screen.\n//\n// - `leading` → core `leading:` → CSS line-height\n// - `spaceBefore` → core `space-before:` → CSS margin-top\n// - `spaceAfter` → core `space-after:` → CSS margin-bottom\n// - `end` → core `end:` → two-sided flex row (`.it-split`)\n//\n// Plain paragraphs (core `text:`/prose) carry these as real node attributes on\n// an extended Paragraph node; IT nodes that already round-trip a `props` JSON\n// attribute (title/section/sub/summary/quote/callout/generic) store them there\n// and render via extensions.ts buildStyle().\n\nimport { Extension } from \"@tiptap/core\";\nimport Paragraph from \"@tiptap/extension-paragraph\";\nimport { mergeAttributes } from \"@tiptap/core\";\nimport type { Editor } from \"@tiptap/core\";\n\n/** Core property keys managed by the paragraph-level commands. */\nexport type BlockPropKey = \"leading\" | \"space-before\" | \"space-after\" | \"end\";\n\n/** Core property key → paragraph attribute name. */\nconst PARA_ATTR: Record<BlockPropKey, string> = {\n leading: \"leading\",\n \"space-before\": \"spaceBefore\",\n \"space-after\": \"spaceAfter\",\n end: \"end\",\n};\n\n// Node types that keep ALL their line properties in a JSON `props` attribute\n// (serialized back by bridge.ts mergeProps). Spacing is portable on all of\n// them — core's STYLE_PROPERTIES applies to every block type.\nconst PROPS_JSON_SPACING = new Set([\n \"itTitle\",\n \"itSummary\",\n \"itSection\",\n \"itSub\",\n \"itQuote\",\n \"itCallout\",\n \"itGenericBlock\",\n]);\n// Core renders `end:` (two-sided rows) on title/section/sub/text/prose only —\n// the editor offers it exactly there so screen and PDF never diverge.\nconst PROPS_JSON_END = new Set([\"itTitle\", \"itSection\", \"itSub\"]);\n\nfunction safeParseProps(val: unknown): Record<string, string> {\n try {\n return typeof val === \"string\" ? JSON.parse(val) : (val as Record<string, string>) || {};\n } catch {\n return {};\n }\n}\n\nfunction supportsKey(typeName: string, key: BlockPropKey): boolean {\n if (typeName === \"paragraph\") return true;\n if (key === \"end\") return PROPS_JSON_END.has(typeName);\n return PROPS_JSON_SPACING.has(typeName);\n}\n\n/**\n * Extended Paragraph: a core `text:`/prose block. Adds the four core block\n * properties as attributes and renders the `end:` value as the second side of\n * a flex split row (matching core's `.it-split` / `.it-split-main` CSS).\n */\nexport const ITParagraph = Paragraph.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n leading: {\n default: null,\n parseHTML: (el) => el.style.lineHeight || null,\n renderHTML: (attrs) =>\n attrs.leading ? { style: `line-height: ${attrs.leading}` } : {},\n },\n spaceBefore: {\n default: null,\n parseHTML: (el) => el.style.marginTop || null,\n renderHTML: (attrs) =>\n attrs.spaceBefore ? { style: `margin-top: ${attrs.spaceBefore}` } : {},\n },\n spaceAfter: {\n default: null,\n parseHTML: (el) => el.style.marginBottom || null,\n renderHTML: (attrs) =>\n attrs.spaceAfter\n ? { style: `margin-bottom: ${attrs.spaceAfter}` }\n : {},\n },\n end: {\n default: null,\n parseHTML: (el) => el.getAttribute(\"data-it-end\"),\n renderHTML: (attrs) =>\n attrs.end ? { \"data-it-end\": attrs.end } : {},\n },\n };\n },\n\n renderHTML({ node, HTMLAttributes }) {\n // Two-sided row: wrap the editable content in `.it-split-main` so it is a\n // single flex item; the `end:` value renders as CSS generated content from\n // data-it-end (non-editable, exactly like core's split-end span).\n if (node.attrs.end) {\n return [\n \"p\",\n mergeAttributes(HTMLAttributes),\n [\"span\", { class: \"it-split-main\" }, 0],\n ];\n }\n return [\"p\", mergeAttributes(HTMLAttributes), 0];\n },\n});\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n blockProps: {\n /**\n * Set (or clear, with null) a core block property on every block in the\n * current selection that supports it. Writes through to the `.it` source\n * via the bridge — paragraph attrs or the node's `props` JSON.\n */\n setBlockProp: (key: BlockPropKey, value: string | null) => ReturnType;\n };\n }\n}\n\nexport const BlockProps = Extension.create({\n name: \"blockProps\",\n\n addCommands() {\n return {\n setBlockProp:\n (key: BlockPropKey, value: string | null) =>\n ({ state, tr, dispatch }) => {\n const { from, to } = state.selection;\n let changed = false;\n state.doc.nodesBetween(from, to, (node, pos) => {\n const name = node.type.name;\n // Don't descend into lists/tables — list items serialize without\n // block props, so styling them would silently not round-trip.\n if (name === \"bulletList\" || name === \"orderedList\") return false;\n if (!node.isBlock || node.isAtom) return false;\n if (!supportsKey(name, key)) return true;\n\n if (name === \"paragraph\") {\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [PARA_ATTR[key]]: value,\n });\n } else {\n const props = safeParseProps(node.attrs.props);\n if (value == null || value === \"\") delete props[key];\n else props[key] = value;\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n props: JSON.stringify(props),\n });\n }\n changed = true;\n return false;\n });\n if (changed && dispatch) dispatch(tr);\n return changed;\n },\n };\n },\n});\n\n/** Read a core block property from the first supporting block in the selection. */\nexport function getBlockProp(\n editor: Editor | null,\n key: BlockPropKey,\n): string | null {\n if (!editor) return null;\n const { state } = editor;\n const { from, to } = state.selection;\n let found: string | null = null;\n state.doc.nodesBetween(from, to, (node) => {\n if (found !== null) return false;\n const name = node.type.name;\n if (!supportsKey(name, key)) return true;\n if (name === \"paragraph\") {\n const v = node.attrs[PARA_ATTR[key]];\n found = v != null ? String(v) : \"\";\n } else {\n found = safeParseProps(node.attrs.props)[key] ?? \"\";\n }\n return false;\n });\n return found;\n}\n","// Shared types for the visual editor\n\n/**\n * Trust actions surfaced by the ribbon's Trust group. The host app decides\n * what each action opens (a seal dialog, a signature flow, a verify panel…) —\n * the editor only reports the intent.\n */\nexport type TrustAction = \"seal\" | \"sign\" | \"verify\";\n\n// Category metadata for UI grouping\nexport interface CategoryInfo {\n label: string;\n icon: string;\n color: string;\n}\n\nexport const CATEGORY_META: Record<string, CategoryInfo> = {\n identity: { label: \"Identity\", icon: \"ID\", color: \"#3b82f6\" },\n content: { label: \"Content\", icon: \"Tx\", color: \"#6b7280\" },\n structure: { label: \"Structure\", icon: \"##\", color: \"#22c55e\" },\n data: { label: \"Data\", icon: \"Dt\", color: \"#a855f7\" },\n agent: { label: \"Agent\", icon: \"Ag\", color: \"#f97316\" },\n trust: { label: \"Trust\", icon: \"Tr\", color: \"#eab308\" },\n layout: { label: \"Layout\", icon: \"Pg\", color: \"#64748b\" },\n};\n\n// Keywords that are read-only in visual mode\nexport const READ_ONLY_KEYWORDS = new Set([\n \"freeze\",\n \"revision\",\n \"history\",\n \"track\",\n]);\n\n// Keywords that support inline content editing\nexport const INLINE_EDITABLE_KEYWORDS = new Set([\n \"text\",\n \"title\",\n \"summary\",\n \"section\",\n \"sub\",\n \"quote\",\n \"tip\",\n \"warning\",\n \"info\",\n \"success\",\n \"danger\",\n \"code\",\n \"def\",\n \"byline\",\n \"epigraph\",\n \"caption\",\n \"footnote\",\n \"dedication\",\n]);\n","// Shared browser print: write an HTML document into a real-size hidden iframe\n// and open the native print dialog (→ Save as PDF). A zero-size iframe prints\n// blank/unstyled in Chrome, so the frame gets A4 dimensions off-screen.\n\nexport function printHtmlViaIframe(html: string): void {\n const iframe = document.createElement(\"iframe\");\n iframe.setAttribute(\"aria-hidden\", \"true\");\n iframe.style.cssText =\n \"position:fixed;right:0;bottom:0;width:210mm;height:297mm;border:0;visibility:hidden;\";\n document.body.appendChild(iframe);\n\n let printed = false;\n const doPrint = () => {\n if (printed) return;\n printed = true;\n try {\n iframe.contentWindow!.focus();\n iframe.contentWindow!.print();\n } finally {\n setTimeout(() => iframe.remove(), 1000);\n }\n };\n iframe.onload = () => window.setTimeout(doPrint, 120);\n\n const idoc = iframe.contentWindow!.document;\n idoc.open();\n idoc.write(html);\n idoc.close();\n // Fallback if onload doesn't fire for a written document.\n if (idoc.readyState === \"complete\") window.setTimeout(doPrint, 250);\n}\n","// Print / export engine for the editor.\n//\n// The UI for these actions lives in the ribbon (DocsToolbar.tsx); host apps can\n// also call exportDocumentPDF / exportDocumentHTML directly — this module owns\n// the WYSIWYG print path and the document export functions they trigger.\n\nimport {\n parseIntentText,\n renderPrint,\n listBuiltinThemes,\n cssContentValue,\n} from \"@dotit/core\";\nimport { getPageGeometry } from \"./page-geometry\";\nimport { printHtmlViaIframe } from \"./print-iframe\";\n\nexport type PrintMode = \"normal\" | \"minimal-ink\";\n\n/** Inject extra CSS before </head> of an HTML document string. */\nfunction injectCss(html: string, css: string): string {\n if (!css) return html;\n return html.includes(\"</head>\")\n ? html.replace(\"</head>\", `<style>${css}</style></head>`)\n : html;\n}\n\nconst MINIMAL_INK_CSS =\n \".it-doc-callout{background:none!important;border:1px solid #ccc!important}\";\n\n// Header/footer CSS `content` value (maps {{page}}/{{pages}} → counters, CSS-escapes).\n// Shared with core's renderPrint so the editor and core build running headers/footers\n// identically — single source of truth.\nconst cssContent = cssContentValue;\n\n/**\n * WYSIWYG print: render the editor's OWN content DOM with its OWN stylesheets, so the\n * PDF looks exactly like the visual editor. Page size / margins / running header+footer\n * come from the document's page:/header:/footer: blocks via @page. Returns null when\n * the visual editor isn't mounted — caller falls back to renderPrint.\n */\nfunction buildWysiwygPrint(content: string, printMode: string): string | null {\n const tiptap = document.querySelector(\".docs-page .tiptap\");\n if (!tiptap) return null;\n\n const clone = tiptap.cloneNode(true) as HTMLElement;\n // Page-break spacers are a screen affordance; print paginates natively via @page.\n clone.querySelectorAll(\"[data-it-spacer]\").forEach((e) => e.remove());\n const bodyHtml = clone.innerHTML;\n\n // Copy the page's stylesheets (the bundled editor CSS + injected theme) verbatim.\n const styles = Array.from(\n document.querySelectorAll('style, link[rel=\"stylesheet\"]'),\n )\n .map((e) => e.outerHTML)\n .join(\"\\n\");\n\n // Use the SAME geometry the on-screen pages use (the doc's page: block parsed\n // by page-geometry.ts) — identical px numbers in @page is what makes the PDF\n // paginate exactly where the editor shows the breaks.\n const g = getPageGeometry(content);\n const sizeCss = g.autoHeight\n ? `${g.width}px auto`\n : `${g.width}px ${g.height}px`;\n const marginCss = `${g.marginTop}px ${g.marginRight}px ${g.marginBottom}px ${g.marginLeft}px`;\n\n let pageCss = `@page{size:${sizeCss};margin:${marginCss};}`;\n if (g.header)\n pageCss += `@page{@top-center{content:${cssContent(g.header)};font:10px -apple-system,sans-serif;color:#9aa0a6;}}`;\n if (g.footer)\n pageCss += `@page{@bottom-center{content:${cssContent(g.footer)};font:10px -apple-system,sans-serif;color:#9aa0a6;}}`;\n\n // Strip the on-screen sheet chrome so only the page content prints.\n const overrides = `\n html,body{margin:0;background:#fff;}\n .docs-page,.docs-page.docs-sheet{box-shadow:none;border-radius:0;margin:0;width:auto;min-height:0;padding:0;background:#fff;}\n .docs-page .tiptap{padding:0;}\n [data-it-spacer]{display:none!important;}\n ${printMode === \"minimal-ink\" ? MINIMAL_INK_CSS : \"\"}\n `;\n\n return `<!doctype html><html><head><meta charset=\"utf-8\">${styles}<style>${pageCss}${overrides}</style></head><body><div class=\"docs-page docs-sheet\"><div class=\"tiptap\">${bodyHtml}</div></div></body></html>`;\n}\n\nfunction download(data: string, filename: string, mime: string) {\n const blob = new Blob([data], { type: mime });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename;\n a.click();\n URL.revokeObjectURL(url);\n}\n\n/** Build the print-ready HTML: WYSIWYG when the visual editor is mounted,\n * core renderPrint otherwise (e.g. a source-mode export). */\nfunction buildPrintHtml(\n content: string,\n theme: string,\n printMode: PrintMode,\n): string {\n let full = buildWysiwygPrint(content, printMode);\n if (!full) {\n const doc = parseIntentText(content);\n full = renderPrint(doc, { theme });\n if (printMode === \"minimal-ink\") full = injectCss(full, MINIMAL_INK_CSS);\n }\n return full;\n}\n\n/** Print / save-as-PDF via the browser's print dialog. Browser-only. */\nexport function exportDocumentPDF(\n content: string,\n theme: string,\n printMode: PrintMode = \"normal\",\n) {\n try {\n printHtmlViaIframe(buildPrintHtml(content, theme, printMode));\n } catch {\n /* ignore */\n }\n}\n\n/** Download the print-ready HTML document. Browser-only. */\nexport function exportDocumentHTML(\n content: string,\n theme: string,\n printMode: PrintMode = \"normal\",\n) {\n try {\n download(\n buildPrintHtml(content, theme, printMode),\n \"document.html\",\n \"text/html\",\n );\n } catch {\n /* ignore */\n }\n}\n\n/** Built-in theme ids — for the ribbon's theme select. */\nexport function builtinThemes(): string[] {\n return listBuiltinThemes() as string[];\n}\n","// The editor ribbon — ONE compact, Google-Docs-style toolbar row with groups:\n//\n// Edit | File (PDF / HTML / theme) | Text | Paragraph | Insert | Trust\n//\n// Every formatting control maps to a CORE `.it` property (size:/align:/leading:/\n// space-before:/space-after:/end:) through bridge.ts, so what you style here is\n// what core prints. Export actions are the WYSIWYG print path from print.ts.\n\nimport { useState, useRef, useEffect, useCallback, useMemo } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n Undo2,\n Redo2,\n Bold,\n Italic,\n Underline,\n Strikethrough,\n Code,\n AlignLeft,\n AlignCenter,\n AlignRight,\n AlignJustify,\n List,\n ListOrdered,\n Minus,\n Plus,\n Palette,\n Highlighter,\n RemoveFormatting,\n ChevronDown,\n Printer,\n FileCode2,\n Droplets,\n Rows3,\n AlignHorizontalSpaceBetween,\n FileLock2,\n PenTool,\n ShieldCheck,\n} from \"lucide-react\";\nimport { LANGUAGE_REGISTRY } from \"@dotit/core\";\nimport { CATEGORY_META } from \"./types\";\nimport { getBlockProp } from \"./block-props\";\nimport {\n exportDocumentPDF,\n exportDocumentHTML,\n builtinThemes,\n} from \"./print\";\nimport type { TrustAction } from \"./types\";\n\ninterface Props {\n editor: Editor | null;\n isRtl?: boolean;\n onToggleRtl?: () => void;\n /** Current .it source — used by the export actions. */\n content: string;\n theme: string;\n onThemeChange: (theme: string) => void;\n /** Trust actions (Seal / Sign / Verify). The group is hidden when omitted. */\n onTrustAction?: (action: TrustAction) => void;\n /** Sealed documents are read-only — formatting groups are disabled. */\n locked?: boolean;\n}\n\n/* ── Style options that map to IT keywords ──────────────────── */\nconst STYLE_OPTIONS = [\n { label: \"Normal text\", node: \"paragraph\" },\n { label: \"Title\", node: \"itTitle\" },\n { label: \"Section\", node: \"itSection\" },\n { label: \"Subsection\", node: \"itSub\" },\n { label: \"Summary\", node: \"itSummary\" },\n { label: \"Quote\", node: \"itQuote\" },\n] as const;\n\ntype InsertOption = {\n label: string;\n keyword: string;\n category: string;\n description: string;\n isReadOnly: boolean;\n};\ntype InsertGroup = { category: string; items: InsertOption[] };\n\nconst READ_ONLY_INSERT_KEYWORDS = new Set([\n \"history\",\n \"revision\",\n \"track\",\n \"freeze\",\n]);\nconst HIDDEN_INSERT_KEYWORDS = new Set([\n \"agent\",\n \"model\",\n \"meta\",\n \"context\",\n \"history\",\n]);\nconst CATEGORY_ORDER = [\n \"identity\",\n \"structure\",\n \"content\",\n \"data\",\n \"trust\",\n \"layout\",\n];\n\nconst FONT_FAMILIES = [\n { label: \"Default\", value: \"\" },\n { label: \"Inter\", value: \"Inter\" },\n { label: \"Arial\", value: \"Arial\" },\n { label: \"Times New Roman\", value: \"Times New Roman\" },\n { label: \"Georgia\", value: \"Georgia\" },\n { label: \"Courier New\", value: \"Courier New\" },\n { label: \"Verdana\", value: \"Verdana\" },\n { label: \"Trebuchet MS\", value: \"Trebuchet MS\" },\n] as const;\n\n// Word-style line spacing presets → core `leading:` (line-height).\nconst LINE_SPACINGS = [\"1\", \"1.15\", \"1.5\", \"2\", \"2.5\", \"3\"] as const;\n// One Word \"spacing step\" → core `space-before:` / `space-after:`.\nconst SPACE_STEP = \"12px\";\n\nconst TEXT_COLORS = [\n \"#000000\",\n \"#434343\",\n \"#666666\",\n \"#999999\",\n \"#b7b7b7\",\n \"#cccccc\",\n \"#d9d9d9\",\n \"#efefef\",\n \"#f3f3f3\",\n \"#ffffff\",\n \"#980000\",\n \"#ff0000\",\n \"#ff9900\",\n \"#ffff00\",\n \"#00ff00\",\n \"#00ffff\",\n \"#4a86e8\",\n \"#0000ff\",\n \"#9900ff\",\n \"#ff00ff\",\n \"#e6b8af\",\n \"#f4cccc\",\n \"#fce5cd\",\n \"#fff2cc\",\n \"#d9ead3\",\n \"#d0e0e3\",\n \"#c9daf8\",\n \"#cfe2f3\",\n \"#d9d2e9\",\n \"#ead1dc\",\n \"#dd7e6b\",\n \"#ea9999\",\n \"#f9cb9c\",\n \"#ffe599\",\n \"#b6d7a8\",\n \"#a2c4c9\",\n \"#a4c2f4\",\n \"#9fc5e8\",\n \"#b4a7d6\",\n \"#d5a6bd\",\n \"#cc4125\",\n \"#e06666\",\n \"#f6b26b\",\n \"#ffd966\",\n \"#93c47d\",\n \"#76a5af\",\n \"#6d9eeb\",\n \"#6fa8dc\",\n \"#8e7cc3\",\n \"#c27ba0\",\n];\n\nconst HIGHLIGHT_COLORS = [\n \"#ffffff\",\n \"#cfe2f3\",\n \"#d9ead3\",\n \"#fff2cc\",\n \"#fce5cd\",\n \"#f4cccc\",\n \"#d9d2e9\",\n \"#ead1dc\",\n \"#d0e0e3\",\n \"#e6b8af\",\n];\n\n/* ── Helper: small icon button ──────────────────────────────── */\nfunction Btn({\n onClick,\n active,\n disabled,\n title,\n children,\n}: {\n onClick: () => void;\n active?: boolean;\n disabled?: boolean;\n title: string;\n children: React.ReactNode;\n}) {\n return (\n <button\n className={`docs-tb-btn${active ? \" active\" : \"\"}`}\n onClick={onClick}\n disabled={disabled}\n title={title}\n >\n {children}\n </button>\n );\n}\n\n/** A ribbon group — one compact Docs-style row (the label is a11y-only). */\nfunction Group({\n label,\n children,\n className = \"\",\n}: {\n label: string;\n children: React.ReactNode;\n className?: string;\n}) {\n return (\n <div\n className={`ribbon-group ${className}`.trim()}\n role=\"group\"\n aria-label={label}\n >\n {children}\n </div>\n );\n}\n\nfunction GroupSep() {\n return <div className=\"ribbon-sep\" />;\n}\n\nexport function DocsToolbar({\n editor,\n isRtl = false,\n onToggleRtl,\n content,\n theme,\n onThemeChange,\n onTrustAction,\n locked = false,\n}: Props) {\n const [styleOpen, setStyleOpen] = useState(false);\n const [insertOpen, setInsertOpen] = useState(false);\n const [fontOpen, setFontOpen] = useState(false);\n const [textColorOpen, setTextColorOpen] = useState(false);\n const [highlightColorOpen, setHighlightColorOpen] = useState(false);\n const [spacingOpen, setSpacingOpen] = useState(false);\n const [inkSaver, setInkSaver] = useState(false);\n\n const styleRef = useRef<HTMLDivElement>(null);\n const insertRef = useRef<HTMLDivElement>(null);\n const fontRef = useRef<HTMLDivElement>(null);\n const textColorRef = useRef<HTMLDivElement>(null);\n const highlightColorRef = useRef<HTMLDivElement>(null);\n const spacingRef = useRef<HTMLDivElement>(null);\n\n // Close all dropdowns on outside click\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n const t = e.target as Node;\n if (styleRef.current && !styleRef.current.contains(t))\n setStyleOpen(false);\n if (insertRef.current && !insertRef.current.contains(t))\n setInsertOpen(false);\n if (fontRef.current && !fontRef.current.contains(t)) setFontOpen(false);\n if (textColorRef.current && !textColorRef.current.contains(t))\n setTextColorOpen(false);\n if (highlightColorRef.current && !highlightColorRef.current.contains(t))\n setHighlightColorOpen(false);\n if (spacingRef.current && !spacingRef.current.contains(t))\n setSpacingOpen(false);\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, []);\n\n const closeAll = () => {\n setStyleOpen(false);\n setInsertOpen(false);\n setFontOpen(false);\n setTextColorOpen(false);\n setHighlightColorOpen(false);\n setSpacingOpen(false);\n };\n\n /* ── Queries ─────────────────────────────────────────────── */\n const getCurrentStyle = useCallback((): string => {\n if (!editor) return \"Normal text\";\n for (const opt of STYLE_OPTIONS) {\n if (opt.node === \"paragraph\" && editor.isActive(\"paragraph\")) {\n const isOther = STYLE_OPTIONS.some(\n (o) => o.node !== \"paragraph\" && editor.isActive(o.node),\n );\n if (!isOther) return opt.label;\n } else if (editor.isActive(opt.node)) {\n return opt.label;\n }\n }\n return \"Normal text\";\n }, [editor]);\n\n const getCurrentFont = useCallback((): string => {\n if (!editor) return \"Default\";\n const family = editor.getAttributes(\"textStyle\")?.fontFamily;\n if (!family) return \"Default\";\n const match = FONT_FAMILIES.find((f) => f.value === family);\n return match ? match.label : \"Default\";\n }, [editor]);\n\n const [fontSize, setFontSize] = useState(11);\n // Re-render on selection moves so active states (align, spacing, end) track the caret.\n const [, setSelTick] = useState(0);\n\n const insertGroups = useMemo<InsertGroup[]>(() => {\n const grouped = new Map<string, InsertOption[]>();\n\n for (const entry of LANGUAGE_REGISTRY) {\n if (entry.status !== \"stable\") continue;\n if (HIDDEN_INSERT_KEYWORDS.has(entry.canonical)) continue;\n if (entry.category === \"agent\") continue;\n\n const category = entry.category;\n const list = grouped.get(category) || [];\n list.push({\n label: entry.canonical,\n keyword: entry.canonical,\n category,\n description: entry.description,\n isReadOnly: READ_ONLY_INSERT_KEYWORDS.has(entry.canonical),\n });\n grouped.set(category, list);\n }\n\n const result: InsertGroup[] = [];\n for (const category of CATEGORY_ORDER) {\n const items = grouped.get(category);\n if (!items || items.length === 0) continue;\n items.sort((a, b) => a.keyword.localeCompare(b.keyword));\n result.push({\n category: CATEGORY_META[category]?.label || category,\n items,\n });\n }\n return result;\n }, []);\n\n // Sync font size + selection tick from editor selection\n useEffect(() => {\n if (!editor) return;\n const updateFontSize = () => {\n const attrs = editor.getAttributes(\"textStyle\");\n if (attrs?.fontSize) {\n const n = parseInt(attrs.fontSize, 10);\n if (!isNaN(n)) setFontSize(n);\n }\n setSelTick((t) => t + 1);\n };\n editor.on(\"selectionUpdate\", updateFontSize);\n editor.on(\"transaction\", updateFontSize);\n return () => {\n editor.off(\"selectionUpdate\", updateFontSize);\n editor.off(\"transaction\", updateFontSize);\n };\n }, [editor]);\n\n /* ── Actions ─────────────────────────────────────────────── */\n const setStyle = useCallback(\n (nodeType: string) => {\n if (!editor) return;\n if (nodeType === \"paragraph\") {\n editor.chain().focus().setParagraph().run();\n } else if (nodeType === \"itQuote\") {\n editor.chain().focus().setNode(\"itQuote\").run();\n } else {\n editor.chain().focus().setNode(nodeType).run();\n }\n closeAll();\n },\n [editor],\n );\n\n const insertBlock = useCallback(\n (keyword: string) => {\n if (!editor) return;\n const chain = editor.chain().focus();\n if (keyword === \"divider\") {\n chain.setNode(\"itDivider\").run();\n } else if (keyword === \"break\") {\n chain.setNode(\"itBreak\").run();\n } else if (keyword === \"code\") {\n chain.setNode(\"itCode\", { lang: \"\" }).run();\n } else if (\n [\"tip\", \"info\", \"warning\", \"danger\", \"success\"].includes(keyword)\n ) {\n chain.setNode(\"itCallout\", { variant: keyword }).run();\n } else {\n chain.setNode(\"itGenericBlock\", { keyword, properties: \"\" }).run();\n }\n closeAll();\n },\n [editor],\n );\n\n // Font size — selection-based; serializes to core `size:` (line-level when the\n // whole line is styled, an inline [text]{ size: … } span otherwise).\n const changeFontSize = useCallback(\n (delta: number) => {\n const next = Math.min(96, Math.max(8, fontSize + delta));\n setFontSize(next);\n editor?.chain().focus().setFontSize(`${next}pt`).run();\n },\n [editor, fontSize],\n );\n\n // Paragraph spacing — writes core `leading:` / `space-before:` / `space-after:`\n // onto every block in the selection (multi-block selections supported).\n const setLeading = useCallback(\n (v: string | null) => {\n editor?.chain().focus().setBlockProp(\"leading\", v).run();\n closeAll();\n },\n [editor],\n );\n\n const toggleSpace = useCallback(\n (key: \"space-before\" | \"space-after\") => {\n if (!editor) return;\n const cur = getBlockProp(editor, key);\n editor\n .chain()\n .focus()\n .setBlockProp(key, cur ? null : SPACE_STEP)\n .run();\n closeAll();\n },\n [editor],\n );\n\n const customSpacing = useCallback(() => {\n if (!editor) return;\n const before = window.prompt(\n \"Space before block (e.g. 12px, 1em — empty for none):\",\n getBlockProp(editor, \"space-before\") || \"\",\n );\n if (before === null) return;\n const after = window.prompt(\n \"Space after block (e.g. 12px, 1em — empty for none):\",\n getBlockProp(editor, \"space-after\") || \"\",\n );\n if (after === null) return;\n editor\n .chain()\n .focus()\n .setBlockProp(\"space-before\", before.trim() || null)\n .setBlockProp(\"space-after\", after.trim() || null)\n .run();\n closeAll();\n }, [editor]);\n\n // Two-sided row — writes the core `end:` property (`text: … | end: …`):\n // content at the line start, value at the line end (flex split, RTL-native).\n const editSplitEnd = useCallback(() => {\n if (!editor) return;\n const cur = getBlockProp(editor, \"end\");\n const next = window.prompt(\n \"Line-end text (shown at the end of the line — empty to remove):\",\n cur || \"\",\n );\n if (next === null) return;\n editor\n .chain()\n .focus()\n .setBlockProp(\"end\", next.trim() || null)\n .run();\n }, [editor]);\n\n const insertSplitRow = useCallback(() => {\n if (!editor) return;\n editor\n .chain()\n .focus()\n .insertContent({\n type: \"paragraph\",\n attrs: { end: \"End text\" },\n content: [{ type: \"text\", text: \"Start text\" }],\n })\n .run();\n closeAll();\n }, [editor]);\n\n /* ── Export (WYSIWYG print path) ─────────────────────────── */\n const themes = useMemo(() => builtinThemes(), []);\n const printMode = inkSaver ? \"minimal-ink\" : \"normal\";\n const doExportPDF = useCallback(\n () => exportDocumentPDF(content, theme, printMode),\n [content, theme, printMode],\n );\n const doExportHTML = useCallback(\n () => exportDocumentHTML(content, theme, printMode),\n [content, theme, printMode],\n );\n\n if (!editor) return null;\n\n const currentLeading = getBlockProp(editor, \"leading\");\n const hasEnd = !!getBlockProp(editor, \"end\");\n\n return (\n <div className=\"docs-toolbar docs-ribbon\">\n {/* ── Edit ─────────────────────────────────────────── */}\n <Group label=\"Edit\">\n <Btn\n onClick={() => editor.chain().focus().undo().run()}\n disabled={locked || !editor.can().undo()}\n title=\"Undo (⌘Z)\"\n >\n <Undo2 size={16} />\n </Btn>\n <Btn\n onClick={() => editor.chain().focus().redo().run()}\n disabled={locked || !editor.can().redo()}\n title=\"Redo (⌘⇧Z)\"\n >\n <Redo2 size={16} />\n </Btn>\n </Group>\n\n <GroupSep />\n\n {/* ── File / Export ────────────────────────────────── */}\n <Group label=\"File\">\n <Btn onClick={doExportPDF} title=\"Print / Export PDF (WYSIWYG)\">\n <Printer size={16} />\n <span className=\"ribbon-btn-text\">PDF</span>\n </Btn>\n <Btn onClick={doExportHTML} title=\"Export HTML\">\n <FileCode2 size={16} />\n <span className=\"ribbon-btn-text\">HTML</span>\n </Btn>\n <Btn\n onClick={() => setInkSaver((v) => !v)}\n active={inkSaver}\n title=\"Minimal ink mode (plain callouts when printing)\"\n >\n <Droplets size={16} />\n </Btn>\n <select\n className=\"ribbon-theme-select\"\n value={theme}\n onChange={(e) => onThemeChange(e.target.value)}\n title=\"Document theme (used by print/export)\"\n >\n {themes.map((t) => (\n <option key={t} value={t}>\n {t.charAt(0).toUpperCase() + t.slice(1)}\n </option>\n ))}\n </select>\n </Group>\n\n <GroupSep />\n\n <div className={locked ? \"ribbon-locked\" : \"ribbon-editing\"}>\n {/* ── Text ─────────────────────────────────────────── */}\n <Group label=\"Text\">\n {/* Font family */}\n <div className=\"docs-tb-dropdown\" ref={fontRef}>\n <button\n className=\"docs-tb-select docs-tb-font-select\"\n onClick={() => {\n closeAll();\n setFontOpen(!fontOpen);\n }}\n >\n <span className=\"docs-tb-select-label\">{getCurrentFont()}</span>\n <ChevronDown size={14} />\n </button>\n {fontOpen && (\n <div className=\"docs-tb-dropdown-menu docs-font-menu\">\n {FONT_FAMILIES.map((f) => (\n <button\n key={f.value || \"default\"}\n className={`docs-tb-dropdown-item${getCurrentFont() === f.label ? \" active\" : \"\"}`}\n style={{ fontFamily: f.value || \"inherit\" }}\n onClick={() => {\n if (f.value) {\n editor.chain().focus().setFontFamily(f.value).run();\n } else {\n editor.chain().focus().unsetFontFamily().run();\n }\n closeAll();\n }}\n >\n {f.label}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Font size → core `size:` */}\n <Btn onClick={() => changeFontSize(-1)} title=\"Decrease font size\">\n <Minus size={14} />\n </Btn>\n <span className=\"docs-tb-fontsize\">{fontSize}</span>\n <Btn onClick={() => changeFontSize(1)} title=\"Increase font size\">\n <Plus size={14} />\n </Btn>\n\n <Btn\n onClick={() => editor.chain().focus().toggleBold().run()}\n active={editor.isActive(\"bold\")}\n title=\"Bold (⌘B)\"\n >\n <Bold size={16} />\n </Btn>\n <Btn\n onClick={() => editor.chain().focus().toggleItalic().run()}\n active={editor.isActive(\"italic\")}\n title=\"Italic (⌘I)\"\n >\n <Italic size={16} />\n </Btn>\n <Btn\n onClick={() => editor.chain().focus().toggleUnderline().run()}\n active={editor.isActive(\"underline\")}\n title=\"Underline (⌘U)\"\n >\n <Underline size={16} />\n </Btn>\n <Btn\n onClick={() => editor.chain().focus().toggleStrike().run()}\n active={editor.isActive(\"strike\")}\n title=\"Strikethrough (⌘⇧X)\"\n >\n <Strikethrough size={16} />\n </Btn>\n\n {/* Text Color */}\n <div\n className=\"docs-tb-dropdown docs-tb-color-dropdown\"\n ref={textColorRef}\n >\n <button\n className=\"docs-tb-btn docs-tb-color-btn\"\n onClick={() => {\n closeAll();\n setTextColorOpen(!textColorOpen);\n }}\n title=\"Text color\"\n >\n <Palette size={16} />\n <span\n className=\"docs-tb-color-indicator\"\n style={{\n background:\n editor.getAttributes(\"textStyle\")?.color || \"#000000\",\n }}\n />\n </button>\n {textColorOpen && (\n <div className=\"docs-tb-dropdown-menu docs-color-grid-menu\">\n <div className=\"docs-color-grid-label\">Text color</div>\n <div className=\"docs-color-grid\">\n {TEXT_COLORS.map((c) => (\n <button\n key={c}\n className=\"docs-color-swatch\"\n style={{ background: c }}\n title={c}\n onClick={() => {\n editor.chain().focus().setColor(c).run();\n closeAll();\n }}\n />\n ))}\n </div>\n <button\n className=\"docs-tb-dropdown-item\"\n onClick={() => {\n editor.chain().focus().unsetColor().run();\n closeAll();\n }}\n >\n <RemoveFormatting size={14} /> Reset\n </button>\n </div>\n )}\n </div>\n\n {/* Highlight Color */}\n <div\n className=\"docs-tb-dropdown docs-tb-color-dropdown\"\n ref={highlightColorRef}\n >\n <button\n className=\"docs-tb-btn docs-tb-color-btn\"\n onClick={() => {\n closeAll();\n setHighlightColorOpen(!highlightColorOpen);\n }}\n title=\"Highlight color\"\n >\n <Highlighter size={16} />\n <span\n className=\"docs-tb-color-indicator\"\n style={{\n background:\n editor.getAttributes(\"highlight\")?.color || \"transparent\",\n }}\n />\n </button>\n {highlightColorOpen && (\n <div className=\"docs-tb-dropdown-menu docs-color-grid-menu\">\n <div className=\"docs-color-grid-label\">Highlight color</div>\n <div className=\"docs-color-grid docs-highlight-grid\">\n {HIGHLIGHT_COLORS.map((c) => (\n <button\n key={c}\n className=\"docs-color-swatch\"\n style={{ background: c }}\n title={c}\n onClick={() => {\n if (c === \"#ffffff\") {\n editor.chain().focus().unsetHighlight().run();\n } else {\n editor\n .chain()\n .focus()\n .toggleHighlight({ color: c })\n .run();\n }\n closeAll();\n }}\n />\n ))}\n </div>\n </div>\n )}\n </div>\n\n <Btn\n onClick={() => editor.chain().focus().toggleCode().run()}\n active={editor.isActive(\"code\")}\n title=\"Inline code\"\n >\n <Code size={16} />\n </Btn>\n <Btn\n onClick={() =>\n editor.chain().focus().unsetAllMarks().clearNodes().run()\n }\n title=\"Clear formatting\"\n >\n <RemoveFormatting size={16} />\n </Btn>\n </Group>\n\n <GroupSep />\n\n {/* ── Paragraph ────────────────────────────────────── */}\n <Group label=\"Paragraph\">\n {/* Block style (Title / Section / …) */}\n <div className=\"docs-tb-dropdown\" ref={styleRef}>\n <button\n className=\"docs-tb-select docs-tb-paragraph-select\"\n onClick={() => {\n closeAll();\n setStyleOpen(!styleOpen);\n }}\n >\n <span className=\"docs-tb-select-label\">{getCurrentStyle()}</span>\n <ChevronDown size={14} />\n </button>\n {styleOpen && (\n <div className=\"docs-tb-dropdown-menu docs-style-menu\">\n {STYLE_OPTIONS.map((opt) => (\n <button\n key={opt.node}\n className={`docs-tb-dropdown-item${getCurrentStyle() === opt.label ? \" active\" : \"\"}`}\n onClick={() => setStyle(opt.node)}\n >\n <span\n className={`docs-style-preview docs-style-${opt.node}`}\n >\n {opt.label}\n </span>\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Alignment → core `align:` */}\n <Btn\n onClick={() => editor.chain().focus().setTextAlign(\"left\").run()}\n active={editor.isActive({ textAlign: \"left\" })}\n title=\"Align left\"\n >\n <AlignLeft size={16} />\n </Btn>\n <Btn\n onClick={() => editor.chain().focus().setTextAlign(\"center\").run()}\n active={editor.isActive({ textAlign: \"center\" })}\n title=\"Align center\"\n >\n <AlignCenter size={16} />\n </Btn>\n <Btn\n onClick={() => editor.chain().focus().setTextAlign(\"right\").run()}\n active={editor.isActive({ textAlign: \"right\" })}\n title=\"Align right\"\n >\n <AlignRight size={16} />\n </Btn>\n <Btn\n onClick={() =>\n editor.chain().focus().setTextAlign(\"justify\").run()\n }\n active={editor.isActive({ textAlign: \"justify\" })}\n title=\"Justify\"\n >\n <AlignJustify size={16} />\n </Btn>\n <Btn\n onClick={() => onToggleRtl?.()}\n active={isRtl}\n title={\n isRtl\n ? \"Switch to LTR (left-to-right)\"\n : \"Switch to RTL (right-to-left)\"\n }\n >\n <span\n style={{\n fontSize: 11,\n fontWeight: 700,\n letterSpacing: -0.5,\n lineHeight: 1,\n }}\n >\n {isRtl ? \"LTR\" : \"RTL\"}\n </span>\n </Btn>\n\n {/* Line & paragraph spacing → core `leading:` / `space-before:` / `space-after:` */}\n <div className=\"docs-tb-dropdown\" ref={spacingRef}>\n <button\n className={`docs-tb-btn${currentLeading ? \" active\" : \"\"}`}\n onClick={() => {\n closeAll();\n setSpacingOpen(!spacingOpen);\n }}\n title=\"Line & paragraph spacing\"\n >\n <Rows3 size={16} />\n <ChevronDown size={12} />\n </button>\n {spacingOpen && (\n <div className=\"docs-tb-dropdown-menu docs-spacing-menu\">\n <div className=\"docs-insert-category\">Line spacing</div>\n <button\n className={`docs-tb-dropdown-item${!currentLeading ? \" active\" : \"\"}`}\n onClick={() => setLeading(null)}\n >\n Default\n </button>\n {LINE_SPACINGS.map((v) => (\n <button\n key={v}\n className={`docs-tb-dropdown-item${currentLeading === v ? \" active\" : \"\"}`}\n onClick={() => setLeading(v)}\n >\n {v === \"1\" ? \"Single\" : v === \"2\" ? \"Double\" : v}\n </button>\n ))}\n <div className=\"docs-insert-divider\" />\n <div className=\"docs-insert-category\">Paragraph spacing</div>\n <button\n className=\"docs-tb-dropdown-item\"\n onClick={() => toggleSpace(\"space-before\")}\n >\n {getBlockProp(editor, \"space-before\")\n ? \"Remove space before block\"\n : \"Add space before block\"}\n </button>\n <button\n className=\"docs-tb-dropdown-item\"\n onClick={() => toggleSpace(\"space-after\")}\n >\n {getBlockProp(editor, \"space-after\")\n ? \"Remove space after block\"\n : \"Add space after block\"}\n </button>\n <button\n className=\"docs-tb-dropdown-item\"\n onClick={customSpacing}\n >\n Custom spacing…\n </button>\n </div>\n )}\n </div>\n\n <Btn\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n active={editor.isActive(\"bulletList\")}\n title=\"Bullet list\"\n >\n <List size={16} />\n </Btn>\n <Btn\n onClick={() => editor.chain().focus().toggleOrderedList().run()}\n active={editor.isActive(\"orderedList\")}\n title=\"Numbered list\"\n >\n <ListOrdered size={16} />\n </Btn>\n </Group>\n\n <GroupSep />\n\n {/* ── Insert ───────────────────────────────────────── */}\n <Group label=\"Insert\">\n <div className=\"docs-tb-dropdown\" ref={insertRef}>\n <button\n className=\"docs-tb-select docs-tb-insert-select\"\n onClick={() => {\n closeAll();\n setInsertOpen(!insertOpen);\n }}\n >\n <Plus size={15} />\n <span>Insert</span>\n <ChevronDown size={14} />\n </button>\n {insertOpen && (\n <div className=\"docs-tb-dropdown-menu docs-insert-menu\">\n <button\n className=\"docs-tb-dropdown-item docs-insert-item\"\n onClick={insertSplitRow}\n title=\"Two-sided row — content at the line start, value at the line end (text: … | end: …)\"\n >\n <span className=\"docs-insert-icon\">\n <AlignHorizontalSpaceBetween size={13} />\n </span>\n <span className=\"docs-insert-label\">two-sided row</span>\n <span className=\"docs-insert-kw\">end:</span>\n </button>\n <div className=\"docs-insert-divider\" />\n {insertGroups.map((group, gi) => (\n <div key={group.category}>\n {gi > 0 && <div className=\"docs-insert-divider\" />}\n <div className=\"docs-insert-category\">{group.category}</div>\n {group.items.map((opt) => (\n <button\n key={opt.keyword}\n className=\"docs-tb-dropdown-item docs-insert-item\"\n onClick={() => insertBlock(opt.keyword)}\n disabled={opt.isReadOnly}\n title={opt.description}\n >\n <span className=\"docs-insert-icon\">\n {CATEGORY_META[opt.category]?.icon || \"•\"}\n </span>\n <span className=\"docs-insert-label\">{opt.label}</span>\n <span className=\"docs-insert-kw\">\n {opt.isReadOnly ? \"locked\" : `.${opt.keyword}`}\n </span>\n </button>\n ))}\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Two-sided row → core `end:` */}\n <Btn\n onClick={editSplitEnd}\n active={hasEnd}\n title=\"Two-sided row — set the text shown at the END of this line (end: property)\"\n >\n <AlignHorizontalSpaceBetween size={16} />\n </Btn>\n </Group>\n </div>\n\n {onTrustAction && (\n <>\n <GroupSep />\n\n {/* ── Trust ────────────────────────────────────── */}\n <Group label=\"Trust\">\n <Btn\n onClick={() => onTrustAction(\"seal\")}\n disabled={locked}\n title={\n locked\n ? \"Document is already sealed\"\n : \"Seal — freeze the document with a tamper-evident hash\"\n }\n >\n <FileLock2 size={16} />\n <span className=\"ribbon-btn-text\">Seal</span>\n </Btn>\n <Btn\n onClick={() => onTrustAction(\"sign\")}\n title=\"Sign — add a signature\"\n >\n <PenTool size={16} />\n <span className=\"ribbon-btn-text\">Sign</span>\n </Btn>\n <Btn\n onClick={() => onTrustAction(\"verify\")}\n title=\"Verify — check the document hash and signatures\"\n >\n <ShieldCheck size={16} />\n <span className=\"ribbon-btn-text\">Verify</span>\n </Btn>\n </Group>\n </>\n )}\n </div>\n );\n}\n","// Horizontal ruler — the Google Docs strip above the page.\n//\n// Read-only display of the page width and margins, in the unit the paper size\n// implies (A-series → cm, Letter/Legal/Tabloid → inches). All numbers come\n// from page-geometry.ts (getPageGeometry of the current document), so the\n// ruler is always EXACTLY as wide as the page sheet and the shaded zones sit\n// exactly on the print margins. Tracks zoom (same scale factor as the page)\n// and the canvas' horizontal scroll (translate), so ticks stay glued to the\n// sheet at any zoom level.\n\nimport { useEffect, useState, useMemo } from \"react\";\nimport type { PageGeometry } from \"./page-geometry\";\n\ninterface RulerProps {\n geometry: PageGeometry;\n zoom: number;\n /** The scrollable canvas element — the ruler mirrors its horizontal scroll. */\n scrollEl: React.RefObject<HTMLDivElement | null>;\n}\n\ninterface Tick {\n /** Position in page px (unscaled). */\n x: number;\n kind: \"minor\" | \"major\";\n label?: string;\n}\n\n/** px per ruler unit at zoom 1 (96dpi: 1in = 96px, 1cm = 96/2.54 px). */\nconst UNIT_PX = { in: 96, cm: 96 / 2.54 } as const;\n/** Minor tick step in units (Docs: quarter-inch / half-centimetre). */\nconst MINOR_STEP = { in: 0.25, cm: 0.5 } as const;\n\nexport function DocsRuler({ geometry, zoom, scrollEl }: RulerProps) {\n const [scrollLeft, setScrollLeft] = useState(0);\n\n // Mirror the canvas' horizontal scroll position.\n useEffect(() => {\n const el = scrollEl.current;\n if (!el) return;\n const onScroll = () => setScrollLeft(el.scrollLeft);\n onScroll();\n el.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => el.removeEventListener(\"scroll\", onScroll);\n }, [scrollEl]);\n\n const ticks = useMemo<Tick[]>(() => {\n const unitPx = UNIT_PX[geometry.unit];\n const step = MINOR_STEP[geometry.unit];\n const out: Tick[] = [];\n const units = geometry.width / unitPx;\n for (let u = 0; u <= units + 1e-6; u += step) {\n const isMajor = Math.abs(u - Math.round(u)) < 1e-6;\n out.push({\n x: u * unitPx,\n kind: isMajor ? \"major\" : \"minor\",\n label: isMajor && u > 0 ? String(Math.round(u)) : undefined,\n });\n }\n return out;\n }, [geometry.width, geometry.unit]);\n\n const w = geometry.width * zoom;\n\n return (\n <div className=\"docs-ruler\" aria-hidden=\"true\">\n <div\n className=\"docs-ruler-track\"\n style={{ width: w, transform: `translateX(${-scrollLeft}px)` }}\n >\n {/* Shaded zones outside the print margins. */}\n <div\n className=\"docs-ruler-margin\"\n style={{ left: 0, width: geometry.marginLeft * zoom }}\n />\n <div\n className=\"docs-ruler-margin\"\n style={{ right: 0, width: geometry.marginRight * zoom }}\n />\n {ticks.map((t, i) =>\n t.label ? (\n <span\n key={i}\n className=\"docs-ruler-num\"\n style={{ left: t.x * zoom }}\n >\n {t.label}\n </span>\n ) : (\n <span\n key={i}\n className={`docs-ruler-tick docs-ruler-tick--${t.kind}`}\n style={{ left: t.x * zoom }}\n />\n ),\n )}\n </div>\n </div>\n );\n}\n","// Document status chrome for the visual editor:\n//\n// - TrustBanner: a professional document-status bar derived from the trust\n// blocks (seal/sign/approve/freeze) — \"🔒 Sealed — signed by Ahmed (CEO) on\n// 2026-06-12 · hash verified ✓\" instead of raw chips. Sealed documents are\n// read-only (VisualEditor flips editable off); the banner says so.\n// - DocPropsBar: a tidy, collapsible header strip for document-level metadata\n// (meta: id/version/owner…, page:, font:, header:, footer:, watermark:),\n// which is otherwise invisible in the page.\n\nimport { useMemo, useState } from \"react\";\nimport { parseIntentText } from \"@dotit/core\";\nimport type { TrustState } from \"./trust-state\";\n\n/* ── Trust status banner ─────────────────────────────────────── */\n\ninterface TrustBannerProps {\n trust: TrustState;\n /** verifyDocument().intact — null when the document is not sealed. */\n intact: boolean | null;\n}\n\nfunction who(by: string, role?: string): string {\n return role ? `${by} (${role})` : by;\n}\n\nexport function TrustBanner({ trust, intact }: TrustBannerProps) {\n if (trust.isSealed) {\n const signer = trust.sealedBy || \"unknown\";\n const role = trust.signatures[trust.signatures.length - 1]?.role;\n return (\n <div className=\"docs-trust-banner docs-trust-banner--sealed\" role=\"status\">\n <span className=\"docs-trust-banner__icon\">🔒</span>\n <span className=\"docs-trust-banner__title\">Sealed</span>\n <span className=\"docs-trust-banner__text\">\n signed by {who(signer, role)}\n {trust.sealedAt ? ` on ${trust.sealedAt}` : \"\"} · read-only\n </span>\n {intact === true && (\n <span className=\"docs-trust-banner__verify docs-trust-banner__verify--ok\">\n hash verified ✓\n </span>\n )}\n {intact === false && (\n <span className=\"docs-trust-banner__verify docs-trust-banner__verify--bad\">\n ⚠ hash mismatch — content changed after sealing\n </span>\n )}\n </div>\n );\n }\n\n if (trust.signatures.length > 0) {\n return (\n <div className=\"docs-trust-banner docs-trust-banner--signed\" role=\"status\">\n <span className=\"docs-trust-banner__icon\">✍</span>\n <span className=\"docs-trust-banner__title\">Signed</span>\n <span className=\"docs-trust-banner__text\">\n by{\" \"}\n {trust.signatures\n .map((s) => `${who(s.by, s.role)}${s.at ? ` on ${s.at}` : \"\"}`)\n .join(\" · \")}\n </span>\n </div>\n );\n }\n\n if (trust.approvals.length > 0) {\n return (\n <div\n className=\"docs-trust-banner docs-trust-banner--approved\"\n role=\"status\"\n >\n <span className=\"docs-trust-banner__icon\">✓</span>\n <span className=\"docs-trust-banner__title\">Approved</span>\n <span className=\"docs-trust-banner__text\">\n by{\" \"}\n {trust.approvals\n .map((a) => `${who(a.by, a.role)}${a.at ? ` on ${a.at}` : \"\"}`)\n .join(\" · \")}\n </span>\n </div>\n );\n }\n\n return null;\n}\n\n/* ── Document properties strip ───────────────────────────────── */\n\ninterface DocProp {\n key: string;\n value: string;\n}\n\nfunction collectDocProps(source: string): DocProp[] {\n let doc;\n try {\n doc = parseIntentText(source);\n } catch {\n return [];\n }\n const props: DocProp[] = [];\n const push = (key: string, value: unknown) => {\n const v = value == null ? \"\" : String(value).trim();\n if (v) props.push({ key, value: v });\n };\n\n for (const block of doc.blocks) {\n switch (block.type) {\n case \"meta\":\n // meta: | id: INV-001 | version: 2 | owner: Ahmed | …\n for (const [k, v] of Object.entries(block.properties || {})) push(k, v);\n break;\n case \"track\":\n push(\"tracked\", block.properties?.id ?? block.content);\n break;\n case \"page\": {\n const orientation = block.properties?.orientation;\n push(\n \"page\",\n [block.content, orientation].filter(Boolean).join(\" · \"),\n );\n break;\n }\n case \"font\":\n push(\n \"font\",\n [\n block.content || block.properties?.family,\n block.properties?.size,\n ]\n .filter(Boolean)\n .join(\" · \"),\n );\n break;\n case \"header\":\n push(\"header\", block.content);\n break;\n case \"footer\":\n push(\"footer\", block.content);\n break;\n case \"watermark\":\n push(\"watermark\", block.content);\n break;\n }\n }\n return props;\n}\n\nexport function DocPropsBar({ source }: { source: string }) {\n const [open, setOpen] = useState(false);\n const props = useMemo(() => collectDocProps(source), [source]);\n\n if (props.length === 0) return null;\n\n // Collapsed: a one-line summary of the leading properties.\n const summary = props\n .slice(0, 4)\n .map((p) => `${p.key}: ${p.value}`)\n .join(\" · \");\n\n return (\n <div className={`docs-props-bar${open ? \" open\" : \"\"}`}>\n <button\n className=\"docs-props-toggle\"\n onClick={() => setOpen((o) => !o)}\n title={open ? \"Hide document properties\" : \"Show document properties\"}\n >\n <span className=\"docs-props-caret\">{open ? \"▾\" : \"▸\"}</span>\n Document properties\n {!open && <span className=\"docs-props-summary\">{summary}</span>}\n </button>\n {open && (\n <div className=\"docs-props-chips\">\n {props.map((p, i) => (\n <span className=\"docs-props-chip\" key={`${p.key}-${i}`}>\n <b>{p.key}</b> {p.value}\n </span>\n ))}\n </div>\n )}\n </div>\n );\n}\n","// Trust state extraction — reads the document's trust blocks (track/approve/\n// sign/freeze/amendment) into a structured lifecycle snapshot. Pure function\n// over the parsed document; the TrustBanner and the sealed read-only behavior\n// are driven from this.\n\nimport type { IntentDocument } from \"@dotit/core\";\n\nexport interface TrustState {\n lifecycle: \"draft\" | \"tracked\" | \"approved\" | \"signed\" | \"sealed\";\n isTracked: boolean;\n trackBlock: { id: string; by: string; at: string } | null;\n approvals: { by: string; role: string; at: string; note?: string }[];\n signatures: { by: string; role: string; at: string }[];\n isSealed: boolean;\n sealedBy: string | null;\n sealedAt: string | null;\n sealHash: string | null;\n amendments: {\n section: string;\n was: string;\n now: string;\n by: string;\n ref: string;\n at: string;\n }[];\n}\n\nfunction prop(\n block: { properties?: Record<string, string | number> } | null,\n key: string,\n fallback = \"\",\n): string {\n const v = block?.properties?.[key];\n return v != null ? String(v) : fallback;\n}\n\nexport function extractTrustState(doc: IntentDocument | null): TrustState {\n const base: TrustState = {\n lifecycle: \"draft\",\n isTracked: false,\n trackBlock: null,\n approvals: [],\n signatures: [],\n isSealed: false,\n sealedBy: null,\n sealedAt: null,\n sealHash: null,\n amendments: [],\n };\n\n if (!doc) return base;\n\n const blocks = doc.blocks;\n\n // Track\n const track = blocks.find((b) => b.type === \"track\");\n if (track) {\n base.isTracked = true;\n base.lifecycle = \"tracked\";\n base.trackBlock = {\n id: prop(track, \"id\", track.content ?? \"\"),\n by: prop(track, \"by\"),\n at: prop(track, \"at\"),\n };\n }\n\n // Approvals\n const approveBlocks = blocks.filter((b) => b.type === \"approve\");\n for (const a of approveBlocks) {\n base.approvals.push({\n by: prop(a, \"by\", a.content ?? \"\"),\n role: prop(a, \"role\"),\n at: prop(a, \"at\"),\n note: prop(a, \"note\") || undefined,\n });\n }\n if (base.approvals.length > 0) base.lifecycle = \"approved\";\n\n // Signatures\n const signBlocks = blocks.filter((b) => b.type === \"sign\");\n for (const s of signBlocks) {\n base.signatures.push({\n by: prop(s, \"by\", s.content ?? \"\"),\n role: prop(s, \"role\"),\n at: prop(s, \"at\"),\n });\n }\n if (base.signatures.length > 0) base.lifecycle = \"signed\";\n\n // Sealed\n const freeze = blocks.find((b) => b.type === \"freeze\");\n if (freeze) {\n base.isSealed = true;\n base.lifecycle = \"sealed\";\n // The sealer's identity lives on the sign: block added during sealing — the\n // freeze: block carries only at/hash/status. Fall back to any freeze content.\n const lastSig = base.signatures[base.signatures.length - 1];\n base.sealedBy = lastSig?.by || prop(freeze, \"by\", freeze.content ?? \"\");\n base.sealedAt = prop(freeze, \"at\") || lastSig?.at || \"\";\n base.sealHash = prop(freeze, \"hash\");\n }\n\n // Amendments\n const amendBlocks = blocks.filter((b) => b.type === \"amendment\");\n for (const am of amendBlocks) {\n base.amendments.push({\n section: prop(am, \"section\", am.content ?? \"\"),\n was: prop(am, \"was\"),\n now: prop(am, \"now\"),\n by: prop(am, \"by\"),\n ref: prop(am, \"ref\"),\n at: prop(am, \"at\"),\n });\n }\n\n return base;\n}\n","// Template placeholder highlighting for the visual editor.\n//\n// Decorates every `{{path.to.value}}` in text content as an inline chip, so\n// template authors SEE their variables at a glance. Pure view decoration —\n// the document text is untouched, so round-trip and merge are unaffected.\n\nimport { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport type { Node as PMNode } from \"@tiptap/pm/model\";\n\nconst key = new PluginKey(\"template-highlight\");\nconst VAR_RE = /\\{\\{[^}]+\\}\\}/g;\n\nfunction buildDecorations(doc: PMNode): DecorationSet {\n const decos: Decoration[] = [];\n doc.descendants((node, pos) => {\n if (!node.isText || !node.text) return;\n VAR_RE.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = VAR_RE.exec(node.text))) {\n decos.push(\n Decoration.inline(pos + m.index, pos + m.index + m[0].length, {\n class: \"it-doc-var\",\n }),\n );\n }\n });\n return DecorationSet.create(doc, decos);\n}\n\nexport const TemplateHighlight = Extension.create({\n name: \"templateHighlight\",\n\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key,\n state: {\n init: (_cfg, state) => buildDecorations(state.doc),\n apply: (tr, old) =>\n tr.docChanged ? buildDecorations(tr.doc) : old,\n },\n props: {\n decorations(state) {\n return key.getState(state);\n },\n },\n }),\n ];\n },\n});\n\n/**\n * Extract the template variables used in `.it` source — unique, in order of\n * first appearance. Runtime print tokens ({{page}}/{{pages}}) and system\n * variables are excluded; they resolve at print/merge time on their own.\n */\nexport function extractTemplateVariables(source: string): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n VAR_RE.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = VAR_RE.exec(source))) {\n const name = m[0].slice(2, -2).trim();\n if (/^(page|pages|date|time|year)$/i.test(name)) continue;\n if (!seen.has(name)) {\n seen.add(name);\n out.push(name);\n }\n }\n return out;\n}\n\n/**\n * Build a sample-data skeleton for a set of variable paths:\n * [\"customer.name\", \"items.0.qty\"] → { customer: { name: \"\" }, items: [{ qty: \"\" }] }\n */\nexport function buildSampleSkeleton(vars: string[]): Record<string, unknown> {\n const root: Record<string, unknown> = {};\n for (const path of vars) {\n const parts = path.split(\".\");\n let cur: Record<string, unknown> = root;\n for (let i = 0; i < parts.length; i++) {\n const p = parts[i];\n const last = i === parts.length - 1;\n // `each:` loop variables bind as item.* — represent as a one-element array\n // under a plural-ish key the author can rename.\n if (last) {\n if (!(p in cur)) cur[p] = \"\";\n } else {\n if (!(p in cur) || typeof cur[p] !== \"object\" || cur[p] === null)\n cur[p] = {};\n cur = cur[p] as Record<string, unknown>;\n }\n }\n }\n return root;\n}\n","import {\n useRef,\n useEffect,\n useLayoutEffect,\n useCallback,\n useState,\n useMemo,\n} from \"react\";\nimport { useEditor, EditorContent } from \"@tiptap/react\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport Placeholder from \"@tiptap/extension-placeholder\";\nimport Underline from \"@tiptap/extension-underline\";\nimport { TextStyle } from \"@tiptap/extension-text-style\";\nimport Color from \"@tiptap/extension-color\";\nimport Highlight from \"@tiptap/extension-highlight\";\nimport TextAlign from \"@tiptap/extension-text-align\";\nimport FontFamily from \"@tiptap/extension-font-family\";\nimport Subscript from \"@tiptap/extension-subscript\";\nimport Superscript from \"@tiptap/extension-superscript\";\nimport { FontSize } from \"./font-size\";\nimport { Pagination } from \"./pagination\";\nimport { sourceToDoc, docToSource, detectUnsupportedStyling } from \"./bridge\";\nimport {\n ITTitle,\n ITSummary,\n ITSection,\n ITSub,\n ITCallout,\n ITQuote,\n ITCode,\n ITDivider,\n ITTable,\n ITMeta,\n ITTrust,\n ITMetric,\n ITStyleRule,\n ITBreak,\n ITGenericBlock,\n ITComment,\n} from \"./extensions\";\nimport { ITParagraph, BlockProps } from \"./block-props\";\nimport { DocsToolbar } from \"./DocsToolbar\";\nimport { DocsRuler } from \"./Ruler\";\nimport { TrustBanner, DocPropsBar } from \"./TrustBanner\";\nimport { extractTrustState } from \"./trust-state\";\nimport {\n getBuiltinTheme,\n generateThemeCSS,\n parseIntentText,\n documentStyleCSS,\n verifyDocument,\n} from \"@dotit/core\";\nimport {\n getPageGeometry,\n resolvePageTokens,\n type PageGeometry,\n} from \"./page-geometry\";\nimport { TemplateHighlight } from \"./template-highlight\";\nimport type { TrustAction } from \"./types\";\n\n/** Grey gap between page cards on the canvas (px). */\nconst PAGE_GAP = 28;\n\n// Where each `style:` target lives in the EDITOR's markup (.it-doc-* classes).\n// documentStyleCSS() does the collection/sanitization — same engine as core's\n// print path — so a rule means exactly the same thing on canvas and on paper.\nconst EDITOR_STYLE_SELECTORS: Record<string, string[]> = {\n title: [\".it-doc-title\"],\n summary: [\".it-doc-summary\"],\n section: [\".it-doc-section\"],\n sub: [\".it-doc-sub\"],\n text: [\"p\"],\n quote: [\".it-doc-quote\"],\n callout: [\".it-doc-callout\"],\n info: [\".it-doc-callout\"],\n table: [\".it-doc-table th\", \".it-doc-table td\"],\n \"table-header\": [\".it-doc-table th\"],\n metric: [\".it-doc-metric\"],\n contact: ['.it-doc-generic[data-keyword=\"contact\"]'],\n divider: [\".it-doc-divider\"],\n};\n\ninterface Props {\n value: string;\n onChange: (source: string) => void;\n theme: string;\n onThemeChange: (theme: string) => void;\n /** Force read-only (sealed documents are read-only regardless). */\n readOnly?: boolean;\n /** Show the formatting ribbon. Default true. */\n showRibbon?: boolean;\n /** Show the trust status banner + document properties strip. Default true. */\n showTrustBanner?: boolean;\n /** Ribbon Trust group (Seal / Sign / Verify). Group is hidden when omitted. */\n onTrustAction?: (action: TrustAction) => void;\n}\n\nexport function VisualEditor({\n value,\n onChange,\n theme,\n onThemeChange,\n readOnly = false,\n showRibbon = true,\n showTrustBanner = true,\n onTrustAction,\n}: Props) {\n const lastSourceRef = useRef<string>(\"\");\n const isInternalUpdate = useRef(false);\n const isHydrating = useRef(true);\n // Styling that can't be saved to .it / won't print through core (regression guard).\n const [unsupported, setUnsupported] = useState<string[]>([]);\n // Live page geometry from the document's own page:/header:/footer: blocks —\n // the same numbers the print path uses (that's what makes the view WYSIWYG).\n const geometryRef = useRef<PageGeometry>(getPageGeometry(\"\"));\n const [pageCount, setPageCount] = useState(1);\n\n const editor = useEditor({\n extensions: [\n Pagination.configure({\n geometry: () => geometryRef.current,\n gap: PAGE_GAP,\n onPages: setPageCount,\n }),\n StarterKit.configure({\n heading: false,\n codeBlock: false,\n blockquote: false,\n horizontalRule: false,\n // Replaced by ITParagraph (core block props: end/leading/space-…).\n paragraph: false,\n }),\n ITParagraph,\n BlockProps,\n Placeholder.configure({\n // Professional behavior: a new empty line shows just the cursor.\n // The hint appears only on a completely empty document.\n placeholder: ({ editor: ed }) =>\n ed.isEmpty ? \"Start typing...\" : \"\",\n }),\n Underline,\n TextStyle,\n Color,\n Highlight.configure({ multicolor: true }),\n TextAlign.configure({\n types: [\"paragraph\", \"itTitle\", \"itSummary\", \"itSection\", \"itSub\"],\n }),\n FontFamily,\n FontSize,\n Subscript,\n Superscript,\n ITTitle,\n ITSummary,\n ITSection,\n ITSub,\n ITCallout,\n ITQuote,\n ITCode,\n ITDivider,\n ITTable,\n ITMeta,\n ITTrust,\n ITMetric,\n ITStyleRule,\n ITBreak,\n ITGenericBlock,\n ITComment,\n TemplateHighlight,\n ],\n content: sourceToDoc(value),\n onUpdate: ({ editor: ed }) => {\n // Avoid rewriting source while editor is still hydrating initial content.\n if (isHydrating.current) return;\n const json = ed.getJSON();\n const source = docToSource(json);\n lastSourceRef.current = source;\n isInternalUpdate.current = true;\n // Fidelity guard: flag any styling that won't survive to .it / core print.\n setUnsupported(detectUnsupportedStyling(json));\n onChange(source);\n },\n editorProps: {\n attributes: {\n class: \"docs-page-content\",\n spellcheck: \"true\",\n },\n },\n });\n\n // Sync external source changes (e.g. from file open, source mode edits)\n useEffect(() => {\n // Mark hydration complete on next tick after mount content is applied.\n const t = window.setTimeout(() => {\n isHydrating.current = false;\n lastSourceRef.current = value;\n }, 0);\n return () => window.clearTimeout(t);\n }, []);\n\n useEffect(() => {\n if (!editor) return;\n if (isInternalUpdate.current) {\n isInternalUpdate.current = false;\n return;\n }\n if (value !== lastSourceRef.current) {\n const json = sourceToDoc(value);\n editor.commands.setContent(json);\n lastSourceRef.current = value;\n }\n }, [value, editor]);\n\n // Host \"insert text/variable\" → insert at the current caret. Dispatch a\n // window CustomEvent(\"it-insert-text\", { detail: \"{{customer.name}}\" }).\n useEffect(() => {\n if (!editor) return;\n const handler = (e: Event) => {\n const text = (e as CustomEvent<string>).detail;\n if (text) editor.chain().focus().insertContent(text).run();\n };\n window.addEventListener(\"it-insert-text\", handler);\n return () => window.removeEventListener(\"it-insert-text\", handler);\n }, [editor]);\n\n // Geometry derived from the document itself (page:/header:/footer: blocks).\n const geometry = useMemo(() => getPageGeometry(value), [value]);\n useEffect(() => {\n geometryRef.current = geometry;\n // Nudge the pagination plugin to re-layout with the new geometry.\n editor?.view.dispatch(editor.state.tr);\n }, [geometry, editor]);\n const pageRef = useRef<HTMLDivElement>(null);\n\n // Word count for the page indicator\n const getWordCount = useCallback(() => {\n if (!editor) return 0;\n return (\n editor.storage.characterCount?.words?.() ??\n editor.getText().split(/\\s+/).filter(Boolean).length\n );\n }, [editor]);\n\n // ── Theme CSS injection ──────────────────────────────────\n const themeCSS = useMemo(() => {\n if (!theme) return \"\";\n try {\n const t = getBuiltinTheme(theme);\n if (!t) return \"\";\n return generateThemeCSS(t).replace(/:root\\{/, \".docs-page{\");\n } catch {\n return \"\";\n }\n }, [theme]);\n\n const docLayoutMeta = useMemo(() => {\n try {\n const doc = parseIntentText(value);\n const header = doc.blocks.find((b) => b.type === \"header\")?.content || \"\";\n const footer = doc.blocks.find((b) => b.type === \"footer\")?.content || \"\";\n const metaBlock = doc.blocks.find((b) => b.type === \"meta\");\n const dir = String(metaBlock?.properties?.dir || \"ltr\").toLowerCase();\n return { header, footer, dir };\n } catch {\n return { header: \"\", footer: \"\", dir: \"ltr\" };\n }\n }, [value]);\n\n // ── Trust state: status banner + sealed read-only ─────────\n const trust = useMemo(() => {\n try {\n return extractTrustState(parseIntentText(value));\n } catch {\n return extractTrustState(null);\n }\n }, [value]);\n\n // Hash check for the banner (\"hash verified ✓\") — only when sealed.\n const sealIntact = useMemo<boolean | null>(() => {\n if (!trust.isSealed) return null;\n try {\n return verifyDocument(value).intact;\n } catch {\n return null;\n }\n }, [value, trust.isSealed]);\n\n // Sealed documents are read-only — the canvas refuses edits and the ribbon's\n // formatting groups are disabled (clear professional indication via banner).\n // Hosts can force the same with the readOnly prop.\n const locked = trust.isSealed || readOnly;\n useEffect(() => {\n if (!editor) return;\n if (editor.isEditable === !locked) return;\n editor.setEditable(!locked);\n }, [editor, locked]);\n\n // Live document styles: apply the doc's `style:` rules to the canvas so the\n // author SEES the house styling while editing (and the WYSIWYG print export\n // inherits it automatically, since it copies the page's <style> elements).\n const docStyleRulesCSS = useMemo(() => {\n try {\n return documentStyleCSS(\n parseIntentText(value),\n EDITOR_STYLE_SELECTORS,\n \".docs-page .tiptap \",\n );\n } catch {\n return \"\";\n }\n }, [value]);\n useEffect(() => {\n let el = document.getElementById(\n \"it-doc-style-rules\",\n ) as HTMLStyleElement | null;\n if (!el) {\n el = document.createElement(\"style\");\n el.id = \"it-doc-style-rules\";\n document.head.appendChild(el);\n }\n el.textContent = docStyleRulesCSS;\n }, [docStyleRulesCSS]);\n\n const toggleRtl = useCallback(() => {\n const isRtl = docLayoutMeta.dir === \"rtl\";\n if (isRtl) {\n // Remove dir: rtl pipe segment; drop line if it becomes empty\n const updated = value\n .split(\"\\n\")\n .map((line) => {\n if (/^meta:/i.test(line.trim())) {\n const cleaned = line.replace(/\\s*\\|\\s*dir:\\s*rtl/gi, \"\").trim();\n return cleaned === \"meta:\" ? null : cleaned;\n }\n return line;\n })\n .filter((l): l is string => l !== null)\n .join(\"\\n\");\n onChange(updated);\n } else {\n const metaMatch = /^meta:.*$/m.exec(value);\n if (metaMatch) {\n onChange(value.replace(/^meta:.*$/m, `${metaMatch[0]} | dir: rtl`));\n } else {\n // Insert after title or summary line, else prepend\n if (/^(title:|summary:)/m.test(value)) {\n onChange(\n value.replace(/^((?:title:|summary:).*)$/m, `$1\\nmeta: | dir: rtl`),\n );\n } else {\n onChange(`meta: | dir: rtl\\n${value}`);\n }\n }\n }\n }, [value, onChange, docLayoutMeta.dir]);\n\n useEffect(() => {\n const id = \"it-editor-theme-css\";\n let el = document.getElementById(id) as HTMLStyleElement | null;\n if (!el) {\n el = document.createElement(\"style\");\n el.id = id;\n document.head.appendChild(el);\n }\n el.textContent = themeCSS;\n }, [themeCSS]);\n\n // ── Zoom ─────────────────────────────────────────────────\n const canvasRef = useRef<HTMLDivElement>(null);\n const [zoom, setZoom] = useState(1);\n const prevZoomRef = useRef(zoom);\n // Store focal point in content-space coordinates for zoom\n const focalRef = useRef<{ cx: number; cy: number } | null>(null);\n\n // Capture focal point at mouse position (for wheel zoom)\n const captureFocalAtMouse = useCallback(\n (e: { clientX: number; clientY: number }) => {\n const el = canvasRef.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n // Mouse position in content-space (scroll + offset within viewport)\n focalRef.current = {\n cx: el.scrollLeft + (e.clientX - rect.left),\n cy: el.scrollTop + (e.clientY - rect.top),\n };\n },\n [],\n );\n\n // Capture focal point at viewport center (for keyboard zoom)\n const captureFocalAtCenter = useCallback(() => {\n const el = canvasRef.current;\n if (!el) return;\n focalRef.current = {\n cx: el.scrollLeft + el.clientWidth / 2,\n cy: el.scrollTop + el.clientHeight / 2,\n };\n }, []);\n\n // After DOM paints with new zoom, restore scroll so focal point is stable\n useLayoutEffect(() => {\n const el = canvasRef.current;\n const focal = focalRef.current;\n const prevZoom = prevZoomRef.current;\n if (!el || !focal || prevZoom === zoom) return;\n const ratio = zoom / prevZoom;\n // The focal point in old content-space maps to focal * ratio in new content-space\n const rect = el.getBoundingClientRect();\n // Where was the focal point relative to the viewport?\n const vpX = focal.cx - el.scrollLeft;\n const vpY = focal.cy - el.scrollTop;\n el.scrollLeft = focal.cx * ratio - vpX;\n el.scrollTop = focal.cy * ratio - vpY;\n focalRef.current = null;\n prevZoomRef.current = zoom;\n }, [zoom]);\n\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (!(e.metaKey || e.ctrlKey)) return;\n if (e.key === \"=\" || e.key === \"+\") {\n e.preventDefault();\n captureFocalAtCenter();\n setZoom((z) => Math.min(2, +(z + 0.1).toFixed(2)));\n } else if (e.key === \"-\") {\n e.preventDefault();\n captureFocalAtCenter();\n setZoom((z) => Math.max(0.25, +(z - 0.1).toFixed(2)));\n } else if (e.key === \"0\") {\n e.preventDefault();\n captureFocalAtCenter();\n setZoom(1);\n }\n };\n window.addEventListener(\"keydown\", handler);\n return () => window.removeEventListener(\"keydown\", handler);\n }, [captureFocalAtCenter]);\n\n useEffect(() => {\n const el = canvasRef.current;\n if (!el) return;\n const handler = (e: WheelEvent) => {\n if (e.ctrlKey || e.metaKey) {\n e.preventDefault();\n const delta = e.deltaY > 0 ? -0.1 : 0.1;\n captureFocalAtMouse(e);\n setZoom((z) => Math.min(2, Math.max(0.25, +(z + delta).toFixed(2))));\n }\n };\n el.addEventListener(\"wheel\", handler, { passive: false });\n return () => el.removeEventListener(\"wheel\", handler);\n }, [captureFocalAtMouse]);\n\n return (\n <div className=\"docs-container\">\n {showRibbon && (\n <DocsToolbar\n editor={editor}\n isRtl={docLayoutMeta.dir === \"rtl\"}\n onToggleRtl={toggleRtl}\n content={value}\n theme={theme}\n onThemeChange={onThemeChange}\n onTrustAction={onTrustAction}\n locked={locked}\n />\n )}\n {showTrustBanner && <TrustBanner trust={trust} intact={sealIntact} />}\n {showTrustBanner && <DocPropsBar source={value} />}\n {unsupported.length > 0 && (\n <div className=\"docs-fidelity-warning\" role=\"status\">\n ⚠ Some formatting ({unsupported.join(\", \")}) can’t be saved to{\" \"}\n <code>.it</code> and won’t appear when printed through the template —\n remove it or use the toolbar’s color/size/style controls instead.\n </div>\n )}\n <DocsRuler geometry={geometry} zoom={zoom} scrollEl={canvasRef} />\n <div className=\"docs-canvas\" ref={canvasRef}>\n <div\n className=\"docs-page-scaler\"\n style={{ width: geometry.width * zoom }}\n >\n <div\n className=\"docs-page-flow\"\n dir={docLayoutMeta.dir}\n style={{\n transform: zoom !== 1 ? `scale(${zoom})` : undefined,\n transformOrigin: \"top left\",\n }}\n >\n {/* One continuous editable sheet, visually cut into Word-like pages.\n The static band below is page 1's top margin + header; the\n Pagination plugin closes every page with its footer band (incl.\n the last) and opens the next with its header band. */}\n <div\n className=\"docs-page docs-sheet\"\n ref={pageRef}\n style={\n {\n width: geometry.width,\n minHeight: geometry.autoHeight ? geometry.width : undefined,\n \"--page-mx-l\": `${geometry.marginLeft}px`,\n \"--page-mx-r\": `${geometry.marginRight}px`,\n } as React.CSSProperties\n }\n >\n <div\n className=\"docs-sheet-header\"\n data-it-spacer=\"\"\n style={{ height: geometry.autoHeight ? undefined : geometry.marginTop }}\n >\n <div className=\"docs-pb-header\">\n <span className=\"docs-pb-text\">\n {geometry.autoHeight\n ? \"\"\n : resolvePageTokens(geometry.header, 1, pageCount)}\n </span>\n </div>\n </div>\n <EditorContent editor={editor} />\n </div>\n </div>\n </div>\n <div className=\"docs-page-footer\">\n {pageCount} {pageCount === 1 ? \"page\" : \"pages\"} &middot;{\" \"}\n {getWordCount()} words\n {zoom !== 1 && (\n <span className=\"zoom-indicator\">\n {\" \"}\n &middot; {Math.round(zoom * 100)}%\n </span>\n )}\n </div>\n </div>\n </div>\n );\n}\n","// IntentTextEditor — the embeddable IntentText visual editor.\n//\n// A controlled React component over `.it` source text: the host owns the\n// document (value/onChange), the editor renders a Word-like WYSIWYG canvas\n// with the formatting ribbon and trust banner. Everything styled here maps to\n// core `.it` properties, so the printed PDF always matches the screen.\n\nimport { useCallback, useState } from \"react\";\nimport { VisualEditor } from \"./VisualEditor\";\nimport type { TrustAction } from \"./types\";\n\nexport interface IntentTextEditorProps {\n /** Current `.it` source text (controlled). */\n value: string;\n /** Called with the updated `.it` source on every edit. */\n onChange: (source: string) => void;\n /**\n * Document theme id (see builtinThemes()). When provided the theme is\n * controlled — pair it with onThemeChange so the ribbon's theme select\n * works. When omitted the editor manages it internally (default\n * \"corporate\").\n */\n theme?: string;\n /** Called when the user picks a theme in the ribbon. */\n onThemeChange?: (theme: string) => void;\n /** Force read-only. Sealed documents are read-only automatically. */\n readOnly?: boolean;\n /** Show the formatting ribbon. Default true. */\n showRibbon?: boolean;\n /** Show the trust status banner + document properties strip. Default true. */\n showTrustBanner?: boolean;\n /**\n * Handle the ribbon's Trust group (Seal / Sign / Verify). The editor only\n * reports the intent — wire it to your own dialogs/flows (e.g. core's\n * sealDocument / verifyDocument). The group is hidden when omitted.\n */\n onTrustAction?: (action: TrustAction) => void;\n}\n\nconst DEFAULT_THEME = \"corporate\";\n\nexport function IntentTextEditor({\n value,\n onChange,\n theme,\n onThemeChange,\n readOnly = false,\n showRibbon = true,\n showTrustBanner = true,\n onTrustAction,\n}: IntentTextEditorProps) {\n // Theme is controlled when the host passes `theme`; self-managed otherwise.\n const [internalTheme, setInternalTheme] = useState(theme ?? DEFAULT_THEME);\n const activeTheme = theme ?? internalTheme;\n const handleThemeChange = useCallback(\n (t: string) => {\n setInternalTheme(t);\n onThemeChange?.(t);\n },\n [onThemeChange],\n );\n\n return (\n <VisualEditor\n value={value}\n onChange={onChange}\n theme={activeTheme}\n onThemeChange={handleThemeChange}\n readOnly={readOnly}\n showRibbon={showRibbon}\n showTrustBanner={showTrustBanner}\n onTrustAction={onTrustAction}\n />\n );\n}\n"],"names":["FontSize","Extension","el","attributes","size","chain","MM","PAPER_MM","PAPER_UNIT","DEFAULT_MARGIN_MM","NARROW_MARGIN_MM","NARROW_WIDTH_MM","parseLength","v","m","parseMargins","raw","fallback","parts","p","getPageGeometry","source","marginRaw","header","footer","doc","parseIntentText","props","b","width","height","autoHeight","unit","named","w","h","defMargin","mt","mr","mb","ml","resolvePageTokens","text","page","pages","paginationKey","PluginKey","bandHtml","kind","resolved","escapeHtml","s","Pagination","opts","Plugin","DecorationSet","tr","old","meta","state","view","raf","lastSig","makeBreak","g","restHeight","makeTail","recompute","dom","domTop","all","blocks","spacerAbove","c","r","breaks","pos","pageStart","lastBottom","i","nodeSize","lastRest","sig","decos","idx","Decoration","set","schedule","CALLOUT_TYPES","META_KEYWORDS","TRUST_KEYWORDS","HEADING_MAP","KEYWORD_ALIASES","MARK_STYLE_KEYS","parseProps","formatProps","exclude","entries","k","textToContent","result","part","inlineNodeMarks","node","marks","ts","MAPPABLE_INLINE","inlineToContent","inline","fallbackText","n","applyPropsAsMarks","content","properties","tsAttrs","family","bg","marksToProps","mark","runToInlineText","child","extractText","t","types","link","hl","hasColorFont","semanticCount","out","SUPPORTED_MARKS","detectUnsupportedStyling","found","walk","inlineToSource","children","align","mergeProps","existingRaw","markProps","existing","key","normalizeKeyword","keyword","lineKeyword","trimmedLine","parsedBlockKeyword","blockType","keywordsMatch","sourceKey","parsedKey","parseInlineProps","rest","seg","fallbackLineToBlock","type","listLineMatch","trimmed","bullet","ordered","makeListItem","sourceToDoc","block","blockToNode","lines","blockIdx","li","mkw","pType","listStart","items","lj","rows","rawBlock","nextParsed","textContent","propsJson","textAlign","attrs","variant","propStr","docToSource","nodeToLines","item","mp","line","nodeToLine","merged","a","blockProps","by","byPart","kw","direct","property","css","TEXT_STYLES","CALLOUT_STYLES","CHIP_STYLES","KEYWORD_STYLES","computeKeywordStyles","rules","styles","rule","value","buildStyle","endAttrs","ITTitle","Node","HTMLAttributes","safeParse","mergeAttributes","ITSummary","ITSection","ITSub","ITCallout","icons","ITQuote","ITCode","ITDivider","ITMeta","ITTable","head","body","tableCellAttrs","cell","parseTrustLine","colon","segs","ITTrust","role","date","hash","who","what","name","valid","ITMetric","isTotal","valueIsVar","ITStyleRule","decl","ITBreak","ITGenericBlock","linkTarget","ITComment","val","PARA_ATTR","PROPS_JSON_SPACING","PROPS_JSON_END","safeParseProps","supportsKey","typeName","ITParagraph","Paragraph","BlockProps","dispatch","from","to","changed","getBlockProp","editor","CATEGORY_META","printHtmlViaIframe","html","iframe","printed","doPrint","idoc","injectCss","MINIMAL_INK_CSS","cssContent","cssContentValue","buildWysiwygPrint","printMode","tiptap","clone","e","bodyHtml","sizeCss","marginCss","pageCss","overrides","download","data","filename","mime","blob","url","buildPrintHtml","theme","full","renderPrint","exportDocumentPDF","exportDocumentHTML","builtinThemes","listBuiltinThemes","STYLE_OPTIONS","READ_ONLY_INSERT_KEYWORDS","HIDDEN_INSERT_KEYWORDS","CATEGORY_ORDER","FONT_FAMILIES","LINE_SPACINGS","SPACE_STEP","TEXT_COLORS","HIGHLIGHT_COLORS","Btn","onClick","active","disabled","title","jsx","Group","label","className","GroupSep","DocsToolbar","isRtl","onToggleRtl","onThemeChange","onTrustAction","locked","styleOpen","setStyleOpen","useState","insertOpen","setInsertOpen","fontOpen","setFontOpen","textColorOpen","setTextColorOpen","highlightColorOpen","setHighlightColorOpen","spacingOpen","setSpacingOpen","inkSaver","setInkSaver","styleRef","useRef","insertRef","fontRef","textColorRef","highlightColorRef","spacingRef","useEffect","handler","closeAll","getCurrentStyle","useCallback","opt","o","getCurrentFont","match","f","fontSize","setFontSize","setSelTick","insertGroups","useMemo","grouped","entry","LANGUAGE_REGISTRY","category","list","updateFontSize","setStyle","nodeType","insertBlock","changeFontSize","delta","next","setLeading","toggleSpace","cur","customSpacing","before","after","editSplitEnd","insertSplitRow","themes","doExportPDF","doExportHTML","currentLeading","hasEnd","jsxs","Undo2","Redo2","Printer","FileCode2","Droplets","ChevronDown","Minus","Plus","Bold","Italic","Underline","Strikethrough","Palette","RemoveFormatting","Highlighter","Code","AlignLeft","AlignCenter","AlignRight","AlignJustify","Rows3","List","ListOrdered","AlignHorizontalSpaceBetween","group","gi","Fragment","FileLock2","PenTool","ShieldCheck","UNIT_PX","MINOR_STEP","DocsRuler","geometry","zoom","scrollEl","scrollLeft","setScrollLeft","onScroll","ticks","unitPx","step","units","u","isMajor","TrustBanner","trust","intact","signer","collectDocProps","push","orientation","DocPropsBar","open","setOpen","summary","prop","extractTrustState","base","track","approveBlocks","signBlocks","freeze","amendBlocks","am","VAR_RE","buildDecorations","TemplateHighlight","_cfg","extractTemplateVariables","seen","buildSampleSkeleton","vars","root","path","PAGE_GAP","EDITOR_STYLE_SELECTORS","VisualEditor","onChange","readOnly","showRibbon","showTrustBanner","lastSourceRef","isInternalUpdate","isHydrating","unsupported","setUnsupported","geometryRef","pageCount","setPageCount","useEditor","StarterKit","Placeholder","ed","TextStyle","Color","Highlight","TextAlign","FontFamily","Subscript","Superscript","json","pageRef","getWordCount","themeCSS","getBuiltinTheme","generateThemeCSS","docLayoutMeta","metaBlock","dir","sealIntact","verifyDocument","docStyleRulesCSS","documentStyleCSS","toggleRtl","updated","cleaned","l","metaMatch","id","canvasRef","setZoom","prevZoomRef","focalRef","captureFocalAtMouse","rect","captureFocalAtCenter","useLayoutEffect","focal","prevZoom","ratio","vpX","vpY","z","EditorContent","DEFAULT_THEME","IntentTextEditor","internalTheme","setInternalTheme","activeTheme","handleThemeChange"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/font-size.ts","../src/page-geometry.ts","../src/pagination.ts","../src/bridge.ts","../src/keyword-styles.ts","../src/extensions.ts","../src/block-props.ts","../src/types.ts","../src/print-iframe.ts","../src/print.ts","../src/TrustControl.tsx","../src/DocsToolbar.tsx","../src/Ruler.tsx","../src/TrustBanner.tsx","../src/trust-state.ts","../src/template-highlight.ts","../src/line-keymap.ts","../src/VisualEditor.tsx","../src/IntentTextEditor.tsx"],"sourcesContent":["import { Extension } from \"@tiptap/core\";\nimport \"@tiptap/extension-text-style\";\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n fontSize: {\n setFontSize: (size: string) => ReturnType;\n unsetFontSize: () => ReturnType;\n };\n }\n}\n\nexport const FontSize = Extension.create({\n name: \"fontSize\",\n\n addOptions() {\n return { types: [\"textStyle\"] };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n fontSize: {\n default: null,\n parseHTML: (el) =>\n (el as HTMLElement).style.fontSize?.replace(/['\"]+/g, \"\") || null,\n renderHTML: (attributes) => {\n if (!attributes.fontSize) return {};\n return { style: `font-size: ${attributes.fontSize}` };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setFontSize:\n (size) =>\n ({ chain }) =>\n chain().setMark(\"textStyle\", { fontSize: size }).run(),\n unsetFontSize:\n () =>\n ({ chain }) =>\n chain()\n .setMark(\"textStyle\", { fontSize: null })\n .removeEmptyTextStyle()\n .run(),\n };\n },\n});\n","// Single source of truth for page geometry in the visual editor.\n//\n// The SAME `page:` block drives core's @page print CSS and this on-screen\n// geometry, so the editor view and the printed PDF paginate identically —\n// that's what makes the editor WYSIWYG. All values are CSS px at 96dpi\n// (1mm = 96/25.4 px), kept as floats to avoid drift across many pages.\n\nimport { parseIntentText } from \"@dotit/core\";\n\nexport const MM = 96 / 25.4;\n\n/** Named paper sizes in mm — keep in sync with core's PAPER_SIZES. */\nconst PAPER_MM: Record<string, [number, number]> = {\n A4: [210, 297],\n A5: [148, 210],\n A3: [297, 420],\n Letter: [215.9, 279.4],\n Legal: [215.9, 355.6],\n Tabloid: [279.4, 431.8],\n};\n\n/** Ruler unit per named paper size — metric sheets read in cm, US sheets in inches. */\nconst PAPER_UNIT: Record<string, \"cm\" | \"in\"> = {\n A4: \"cm\",\n A5: \"cm\",\n A3: \"cm\",\n LETTER: \"in\",\n LEGAL: \"in\",\n TABLOID: \"in\",\n};\n\n/** Default print margin — MUST match core renderPrint's default (20mm). */\nconst DEFAULT_MARGIN_MM = 20;\n/** Narrow pages (receipts) default tight margins — matches core (≤120mm → 4mm). */\nconst NARROW_MARGIN_MM = 4;\nconst NARROW_WIDTH_MM = 120;\n\nexport interface PageGeometry {\n /** Page width in px. */\n width: number;\n /** Page height in px — Infinity when height is `auto` (continuous receipt). */\n height: number;\n /** True when the page grows with content (e.g. `80mm auto`): no pagination. */\n autoHeight: boolean;\n marginTop: number;\n marginRight: number;\n marginBottom: number;\n marginLeft: number;\n /** Height available for content on one page (height - vertical margins). */\n contentHeight: number;\n /** Header text ('' if none). Supports {{page}}/{{pages}} tokens. */\n header: string;\n /** Footer text ('' if none). Supports {{page}}/{{pages}} tokens. */\n footer: string;\n /** Ruler unit derived from the page size (A-series → cm, Letter/Legal → in). */\n unit: \"cm\" | \"in\";\n}\n\nfunction parseLength(v: string): number | null {\n const m = /^(-?\\d+(?:\\.\\d+)?)\\s*(mm|cm|in|px|pt)?$/.exec(v.trim());\n if (!m) return null;\n const n = parseFloat(m[1]);\n switch (m[2] || \"mm\") {\n case \"mm\":\n return n * MM;\n case \"cm\":\n return n * 10 * MM;\n case \"in\":\n return n * 96;\n case \"pt\":\n return (n / 72) * 96;\n case \"px\":\n return n;\n default:\n return null;\n }\n}\n\n/** Parse a CSS-style margin shorthand (1–4 values) into [t, r, b, l] px. */\nfunction parseMargins(raw: string, fallback: number): [number, number, number, number] {\n const parts = raw.trim().split(/\\s+/).map(parseLength);\n if (parts.some((p) => p === null) || parts.length === 0)\n return [fallback, fallback, fallback, fallback];\n const v = parts as number[];\n if (v.length === 1) return [v[0], v[0], v[0], v[0]];\n if (v.length === 2) return [v[0], v[1], v[0], v[1]];\n if (v.length === 3) return [v[0], v[1], v[2], v[1]];\n return [v[0], v[1], v[2], v[3]];\n}\n\n/** Compute the page geometry from `.it` source (its page:/header:/footer: blocks). */\nexport function getPageGeometry(source: string): PageGeometry {\n let size = \"A4\";\n let marginRaw: string | undefined;\n let header = \"\";\n let footer = \"\";\n try {\n const doc = parseIntentText(source);\n const page = doc.blocks.find((b) => b.type === \"page\");\n const props = (page?.properties || {}) as Record<string, string>;\n if (props.size) size = String(props.size);\n marginRaw = (props.margin ?? props.margins) as string | undefined;\n header =\n doc.blocks.find((b) => b.type === \"header\")?.content ||\n String(props.header || \"\");\n footer =\n doc.blocks.find((b) => b.type === \"footer\")?.content ||\n String(props.footer || \"\");\n } catch {\n /* defaults */\n }\n\n // Resolve page size: named, or \"<w> <h>\" (h may be `auto`).\n let width = PAPER_MM.A4[0] * MM;\n let height: number = PAPER_MM.A4[1] * MM;\n let autoHeight = false;\n let unit: \"cm\" | \"in\" = \"cm\";\n const named = PAPER_MM[size] || PAPER_MM[size.toUpperCase?.() as string];\n if (named) {\n width = named[0] * MM;\n height = named[1] * MM;\n unit = PAPER_UNIT[size.toUpperCase()] || \"cm\";\n } else {\n const parts = size.trim().split(/\\s+/);\n const w = parts[0] ? parseLength(parts[0]) : null;\n if (w) width = w;\n // Custom sizes declared in inches read in inches; everything else metric.\n if (/(\\d)\\s*in\\b/.test(size)) unit = \"in\";\n if (parts[1] === \"auto\") {\n autoHeight = true;\n height = Infinity;\n } else {\n const h = parts[1] ? parseLength(parts[1]) : null;\n if (h) height = h;\n }\n }\n\n const defMargin =\n (width <= NARROW_WIDTH_MM * MM ? NARROW_MARGIN_MM : DEFAULT_MARGIN_MM) * MM;\n const [mt, mr, mb, ml] = marginRaw\n ? parseMargins(marginRaw, defMargin)\n : [defMargin, defMargin, defMargin, defMargin];\n\n return {\n width,\n height,\n autoHeight,\n marginTop: mt,\n marginRight: mr,\n marginBottom: mb,\n marginLeft: ml,\n contentHeight: autoHeight ? Infinity : height - mt - mb,\n header,\n footer,\n unit,\n };\n}\n\n/**\n * Set (or replace) the `margin:` property on the document's `page:` block.\n * Idempotent: replaces any existing margin/margins prop rather than appending,\n * so repeated ruler drags never accumulate duplicate pipe segments. Inserts a\n * `page:` block (after the meta/title preamble) when the document has none.\n */\nexport function setPageMargin(source: string, marginValue: string): string {\n const lines = source.split(\"\\n\");\n const pageIdx = lines.findIndex((l) => /^\\s*page\\s*:/i.test(l));\n if (pageIdx >= 0) {\n // Strip existing margin/margins segments, then append the new one.\n let line = lines[pageIdx]\n .replace(/\\s*\\|\\s*margins?\\s*:[^|]*/gi, \"\")\n .replace(/\\s+$/, \"\");\n line = `${line} | margin: ${marginValue}`;\n lines[pageIdx] = line;\n return lines.join(\"\\n\");\n }\n // No page block — insert one after the leading meta/title/summary preamble.\n const insertAt = lines.findIndex(\n (l) => l.trim() && !/^\\s*(meta|title|summary)\\s*:/i.test(l),\n );\n const pageLine = `page: A4 | margin: ${marginValue}`;\n if (insertAt <= 0) return `${pageLine}\\n${source}`;\n lines.splice(insertAt, 0, pageLine);\n return lines.join(\"\\n\");\n}\n\n/** Resolve {{page}}/{{pages}} tokens for on-screen display. */\nexport function resolvePageTokens(\n text: string,\n page: number,\n pages: number,\n): string {\n return text\n .replace(/\\{\\{\\s*page\\s*\\}\\}/g, String(page))\n .replace(/\\{\\{\\s*pages\\s*\\}\\}/g, String(pages));\n}\n","// Word-like page pagination for the visual editor.\n//\n// One continuous contenteditable sheet is visually cut into real pages:\n// at each page boundary a non-editable spacer widget renders\n// [filler to the page bottom + footer band] [page gap] [header band]\n// and a terminal spacer closes the LAST page with its filler + footer band,\n// so every page — first, middle, last — shows its header/footer and keeps its\n// exact print height. Content is never hidden or clipped (the old masking bug);\n// the caret stays in document order.\n//\n// Geometry comes from page-geometry.ts (the document's own `page:` block) — the\n// same numbers core's @page print CSS uses, which is what makes the editor view\n// match the printed PDF page-for-page.\n\nimport { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport type { PageGeometry } from \"./page-geometry\";\nimport { resolvePageTokens } from \"./page-geometry\";\n\nexport interface PaginationOptions {\n /** Live geometry — read on every layout pass so doc edits apply instantly. */\n geometry: () => PageGeometry;\n /** Grey gap between page cards (px). */\n gap: number;\n /** Called with the resulting page count after each layout pass. */\n onPages?: (pages: number) => void;\n}\n\nconst paginationKey = new PluginKey(\"pagination\");\n\n// Renders exactly what print's @page margin box shows: the resolved text,\n// horizontally centered, vertically centered in the margin area. No extra\n// auto page number — print shows one only when the footer contains {{page}}.\nfunction bandHtml(\n kind: \"header\" | \"footer\",\n text: string,\n page: number,\n pages: number,\n): string {\n const resolved = resolvePageTokens(text, page, pages);\n return `<div class=\"docs-pb-${kind}\">\n <span class=\"docs-pb-text\">${escapeHtml(resolved)}</span>\n </div>`;\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\");\n}\n\nexport const Pagination = Extension.create<PaginationOptions>({\n name: \"pagination\",\n\n addOptions() {\n return {\n geometry: () =>\n ({\n width: 794,\n height: 1122.52,\n autoHeight: false,\n marginTop: 75.59,\n marginRight: 75.59,\n marginBottom: 75.59,\n marginLeft: 75.59,\n contentHeight: 971.34,\n header: \"\",\n footer: \"\",\n }) as PageGeometry,\n gap: 28,\n onPages: undefined,\n };\n },\n\n addProseMirrorPlugins() {\n const opts = this.options;\n\n return [\n new Plugin({\n key: paginationKey,\n state: {\n init: () => DecorationSet.empty,\n apply(tr, old) {\n const meta = tr.getMeta(paginationKey);\n if (meta) return meta as DecorationSet;\n return old.map(tr.mapping, tr.doc);\n },\n },\n props: {\n decorations(state) {\n return paginationKey.getState(state);\n },\n },\n view(view) {\n let raf = 0;\n let lastSig = \"\";\n\n // Interior break: close page N (filler + footer), gap, open page N+1 (header).\n const makeBreak = (\n g: PageGeometry,\n restHeight: number,\n page: number,\n pages: number,\n ): HTMLElement => {\n const el = document.createElement(\"div\");\n el.className = \"docs-page-spacer\";\n el.contentEditable = \"false\";\n el.setAttribute(\"data-it-spacer\", \"\");\n el.style.setProperty(\"--pb-mx-l\", `${g.marginLeft}px`);\n el.style.setProperty(\"--pb-mx-r\", `${g.marginRight}px`);\n el.innerHTML = `\n <div class=\"docs-pb-fill\" style=\"height:${restHeight}px\"></div>\n <div class=\"docs-pb-margin docs-pb-margin-bottom\" style=\"height:${g.marginBottom}px\">\n ${bandHtml(\"footer\", g.footer, page, pages)}\n </div>\n <div class=\"docs-pb-gap\" style=\"height:${opts.gap}px\"></div>\n <div class=\"docs-pb-margin docs-pb-margin-top\" style=\"height:${g.marginTop}px\">\n ${bandHtml(\"header\", g.header, page + 1, pages)}\n </div>`;\n return el;\n };\n\n // Terminal spacer: close the LAST page so it is exactly page-height and\n // shows its footer like every other page.\n const makeTail = (\n g: PageGeometry,\n restHeight: number,\n page: number,\n pages: number,\n ): HTMLElement => {\n const el = document.createElement(\"div\");\n el.className = \"docs-page-spacer docs-page-tail\";\n el.contentEditable = \"false\";\n el.setAttribute(\"data-it-spacer\", \"\");\n el.style.setProperty(\"--pb-mx-l\", `${g.marginLeft}px`);\n el.style.setProperty(\"--pb-mx-r\", `${g.marginRight}px`);\n el.innerHTML = `\n <div class=\"docs-pb-fill\" style=\"height:${restHeight}px\"></div>\n <div class=\"docs-pb-margin docs-pb-margin-bottom\" style=\"height:${g.marginBottom}px\">\n ${bandHtml(\"footer\", g.footer, page, pages)}\n </div>`;\n return el;\n };\n\n const recompute = () => {\n const g = opts.geometry();\n const dom = view.dom as HTMLElement;\n const doc = view.state.doc;\n\n // Continuous mode (e.g. `80mm auto` receipts): no pagination at all.\n if (g.autoHeight) {\n if (lastSig !== \"auto\") {\n lastSig = \"auto\";\n view.dispatch(\n view.state.tr.setMeta(paginationKey, DecorationSet.empty),\n );\n opts.onPages?.(1);\n }\n return;\n }\n\n // Pass 1 — measure where the breaks fall, using RECT positions so\n // CSS margin collapsing is accounted for exactly (summing heights +\n // margins overestimates and drifts off the print engine's breaks).\n // Spacer heights above each block are subtracted to recover each\n // block's \"natural\" position — stable across re-layouts.\n const domTop = dom.getBoundingClientRect().top;\n const all = Array.from(dom.children) as HTMLElement[];\n const blocks: { natTop: number; natBottom: number }[] = [];\n let spacerAbove = 0;\n for (const c of all) {\n if (c.hasAttribute?.(\"data-it-spacer\")) {\n spacerAbove += c.offsetHeight;\n continue;\n }\n const r = c.getBoundingClientRect();\n blocks.push({\n natTop: r.top - domTop - spacerAbove,\n natBottom: r.bottom - domTop - spacerAbove,\n });\n }\n\n const breaks: { pos: number; rest: number }[] = [];\n let pos = 0;\n let pageStart = blocks.length ? blocks[0].natTop : 0;\n let lastBottom = pageStart;\n for (let i = 0; i < blocks.length && i < doc.childCount; i++) {\n const b = blocks[i];\n const nodeSize = doc.child(i).nodeSize;\n if (\n b.natTop > pageStart && // never break before the page's first block\n b.natBottom - pageStart > g.contentHeight\n ) {\n breaks.push({\n pos,\n rest: Math.max(0, g.contentHeight - (b.natTop - pageStart)),\n });\n pageStart = b.natTop;\n }\n lastBottom = b.natBottom;\n pos += nodeSize;\n }\n const pages = breaks.length + 1;\n const lastRest = Math.max(\n 0,\n g.contentHeight - (lastBottom - pageStart),\n );\n\n const sig =\n breaks.map((b) => `${b.pos}:${Math.round(b.rest)}`).join(\",\") +\n `|${Math.round(lastRest)}|${pages}|${g.header}|${g.footer}|${Math.round(g.contentHeight)}`;\n if (sig === lastSig) return;\n lastSig = sig;\n\n // Pass 2 — build decorations with the final page count (so {{pages}}\n // and per-page numbers are correct).\n const decos: Decoration[] = breaks.map((b, idx) =>\n Decoration.widget(\n b.pos,\n () => makeBreak(g, b.rest, idx + 1, pages),\n { side: -1, key: `pb-${idx + 1}-${Math.round(b.rest)}` },\n ),\n );\n decos.push(\n Decoration.widget(\n doc.content.size,\n () => makeTail(g, lastRest, pages, pages),\n { side: 1, key: `pb-tail-${pages}-${Math.round(lastRest)}` },\n ),\n );\n\n const set = DecorationSet.create(view.state.doc, decos);\n view.dispatch(view.state.tr.setMeta(paginationKey, set));\n opts.onPages?.(pages);\n };\n\n const schedule = () => {\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(recompute);\n };\n\n schedule();\n return {\n update: schedule,\n destroy: () => cancelAnimationFrame(raf),\n };\n },\n }),\n ];\n },\n});\n","// Bridge: IntentText source ↔ TipTap JSON document\n// Converts .it source text to TipTap-compatible JSON and back\n\nimport { parseIntentText } from \"@dotit/core\";\nimport type { JSONContent } from \"@tiptap/core\";\n\n/** A TipTap mark on a text node. */\ntype Mark = {\n type: string;\n attrs?: Record<string, unknown>;\n [k: string]: unknown;\n};\n\n// IT keywords that map to dedicated TipTap nodes\nconst CALLOUT_TYPES = new Set([\"tip\", \"info\", \"warning\", \"danger\", \"success\"]);\n// Document-level metadata / layout keywords — shown as a chip, not body content.\nconst META_KEYWORDS = new Set([\n \"page\",\n \"meta\",\n \"font\",\n \"header\",\n \"footer\",\n \"watermark\",\n]);\n// Tamper-evidence / history keywords — rendered as styled trust chips, with the\n// exact source line preserved verbatim for round-trip (the document hash must not\n// change from editing in the visual editor).\nconst TRUST_KEYWORDS = new Set([\n \"sign\",\n \"seal\",\n \"approve\",\n \"freeze\",\n \"amend\",\n \"amendment\",\n]);\nconst HEADING_MAP: Record<string, string> = {\n title: \"itTitle\",\n section: \"itSection\",\n sub: \"itSub\",\n};\n\nconst KEYWORD_ALIASES: Record<string, string> = {\n note: \"text\",\n \"body-text\": \"text\",\n};\n\n// Style keys managed through TipTap marks/attributes.\n// These are extracted FROM marks on doc→source, and applied AS marks on source→doc.\n// Canonical keys match core's STYLE_PROPERTIES (family/bg/italic), so styling done\n// in the editor renders identically through core. Legacy editor keys (style/font/\n// bgcolor) are kept so older documents still round-trip.\nconst MARK_STYLE_KEYS = new Set([\n \"weight\",\n \"italic\",\n \"underline\",\n \"strike\",\n \"color\",\n \"family\",\n \"size\",\n \"bg\",\n \"valign\",\n \"align\",\n // legacy aliases\n \"style\",\n \"font\",\n \"bgcolor\",\n]);\n\n/* ── Helpers ─────────────────────────────────────────────────── */\n\n/** Parse the JSON-encoded props attribute. */\nfunction parseProps(raw: unknown): Record<string, string> {\n if (!raw || raw === \"{}\") return {};\n try {\n return typeof raw === \"string\"\n ? JSON.parse(raw)\n : (raw as Record<string, string>) || {};\n } catch {\n return {};\n }\n}\n\n/** Format a props object as ' | key: val | key2: val2' (or ''). */\nfunction formatProps(\n props: Record<string, string>,\n exclude?: Set<string>,\n): string {\n const entries = Object.entries(props).filter(\n ([k, v]) => v !== undefined && v !== \"\" && (!exclude || !exclude.has(k)),\n );\n if (entries.length === 0) return \"\";\n return \" | \" + entries.map(([k, v]) => `${k}: ${v}`).join(\" | \");\n}\n\n/**\n * Convert text string to TipTap content nodes.\n * Literal \\n (backslash-n) in the source becomes hardBreak nodes.\n */\nfunction textToContent(text: string): JSONContent[] {\n if (!text) return [];\n const parts = text.split(\"\\\\n\");\n const result: JSONContent[] = [];\n parts.forEach((part, i) => {\n if (part) result.push({ type: \"text\", text: part });\n if (i < parts.length - 1) result.push({ type: \"hardBreak\" });\n });\n return result;\n}\n\n/** A core inline AST node (subset we map to TipTap marks). */\ntype InlineNode = {\n type: string;\n value?: string;\n href?: string;\n props?: Record<string, string>;\n};\n\n/** Map one core inline node to the TipTap marks it should carry (or null = plain). */\nfunction inlineNodeMarks(node: InlineNode): Mark[] | null {\n switch (node.type) {\n case \"bold\":\n return [{ type: \"bold\" }];\n case \"italic\":\n return [{ type: \"italic\" }];\n case \"strike\":\n return [{ type: \"strike\" }];\n case \"code\":\n return [{ type: \"code\" }];\n case \"highlight\":\n return [{ type: \"highlight\" }];\n case \"styled\": {\n const p = node.props || {};\n const marks: Mark[] = [];\n const ts: Record<string, string> = {};\n if (p.weight && p.weight !== \"normal\") marks.push({ type: \"bold\" });\n if (p.italic === \"true\") marks.push({ type: \"italic\" });\n if (p.underline === \"true\") marks.push({ type: \"underline\" });\n if (p.strike === \"true\") marks.push({ type: \"strike\" });\n if (p.color) ts.color = p.color;\n if (p.family) ts.fontFamily = p.family;\n if (p.size) ts.fontSize = p.size;\n if (Object.keys(ts).length) marks.push({ type: \"textStyle\", attrs: ts });\n if (p.bg) marks.push({ type: \"highlight\", attrs: { color: p.bg } });\n if (p.valign === \"sub\") marks.push({ type: \"subscript\" });\n if (p.valign === \"super\") marks.push({ type: \"superscript\" });\n return marks.length ? marks : null;\n }\n default:\n return null; // text, mention, tag, date, label, link → plain text\n }\n}\n\n// Inline node types that map cleanly to TipTap marks (and thus round-trip exactly).\n// Other node types (label, mention, tag, date, link, note, quote, code, footnote)\n// carry delimiters that can't be reconstructed from the AST alone, so a line\n// containing any of them is kept literal (textToContent) — preserving the source.\nconst MAPPABLE_INLINE = new Set([\n \"text\",\n \"bold\",\n \"italic\",\n \"strike\",\n \"highlight\",\n \"styled\",\n]);\n\n/**\n * Build TipTap content from core's inline AST, so inline marks AND styled spans\n * (`[text]{…}`) become real TipTap marks (partial styling survives the round-trip).\n * If the line mixes in delimiter-bearing nodes (mentions, tags, links, code, …) or\n * has nothing to mark, keep it literal so those tokens round-trip unchanged.\n */\nfunction inlineToContent(\n inline: InlineNode[] | undefined,\n fallbackText: string,\n): JSONContent[] {\n if (\n !inline ||\n inline.length === 0 ||\n inline.every((n) => n.type === \"text\") ||\n !inline.every((n) => MAPPABLE_INLINE.has(n.type))\n ) {\n return textToContent(fallbackText);\n }\n const result: JSONContent[] = [];\n for (const node of inline) {\n const marks = inlineNodeMarks(node);\n const value = node.value ?? \"\";\n // Preserve literal \\n as hardBreaks even inside styled runs.\n const parts = value.split(\"\\\\n\");\n parts.forEach((part, i) => {\n if (part)\n result.push(marks ? { type: \"text\", text: part, marks } : { type: \"text\", text: part });\n if (i < parts.length - 1) result.push({ type: \"hardBreak\" });\n });\n }\n return result.length ? result : textToContent(fallbackText);\n}\n\n/**\n * Apply IT properties as TipTap marks on text content nodes.\n * E.g. weight:bold → bold mark, color:#f00 → textStyle{color}, etc.\n */\nfunction applyPropsAsMarks(\n content: JSONContent[],\n properties: Record<string, string | number> | undefined,\n): JSONContent[] {\n if (!properties || content.length === 0) return content;\n\n const marks: Mark[] = [];\n const tsAttrs: Record<string, string> = {};\n\n const p = properties;\n // Canonical core keys (family/bg/italic), with legacy editor keys as fallback.\n const family = p.family ?? p.font;\n const bg = p.bg ?? p.bgcolor;\n if (String(p.weight || \"\").toLowerCase() === \"bold\")\n marks.push({ type: \"bold\" });\n if (String(p.italic || \"\") === \"true\" || String(p.style || \"\").toLowerCase() === \"italic\")\n marks.push({ type: \"italic\" });\n if (String(p.underline || \"\") === \"true\") marks.push({ type: \"underline\" });\n if (String(p.strike || \"\") === \"true\") marks.push({ type: \"strike\" });\n if (String(p.valign || \"\") === \"sub\") marks.push({ type: \"subscript\" });\n if (String(p.valign || \"\") === \"super\") marks.push({ type: \"superscript\" });\n if (p.color) tsAttrs.color = String(p.color);\n if (family) tsAttrs.fontFamily = String(family);\n if (p.size) tsAttrs.fontSize = String(p.size);\n if (bg) marks.push({ type: \"highlight\", attrs: { color: String(bg) } });\n\n if (Object.keys(tsAttrs).length > 0)\n marks.push({ type: \"textStyle\", attrs: tsAttrs });\n\n if (marks.length === 0) return content;\n\n return content.map((n) =>\n n.type === \"text\"\n ? { ...n, marks: [...((n.marks || []) as Mark[]), ...marks] }\n : n,\n );\n}\n\n/** One text run's marks → the IT style props they map to (line-level vocabulary). */\nfunction marksToProps(marks: Mark[] | undefined): Record<string, string> {\n const props: Record<string, string> = {};\n for (const mark of marks || []) {\n switch (mark.type) {\n case \"bold\":\n props.weight = \"bold\";\n break;\n case \"italic\":\n props.italic = \"true\";\n break;\n case \"underline\":\n props.underline = \"true\";\n break;\n case \"strike\":\n props.strike = \"true\";\n break;\n case \"textStyle\":\n if (mark.attrs?.color) props.color = String(mark.attrs.color);\n if (mark.attrs?.fontFamily) props.family = String(mark.attrs.fontFamily);\n if (mark.attrs?.fontSize) props.size = String(mark.attrs.fontSize);\n break;\n case \"highlight\":\n if (mark.attrs?.color) props.bg = String(mark.attrs.color);\n break;\n case \"subscript\":\n props.valign = \"sub\";\n break;\n case \"superscript\":\n props.valign = \"super\";\n break;\n }\n }\n return props;\n}\n\n/**\n * Serialize ONE text run (with its marks) to .it inline syntax:\n * - no marks → raw text\n * - a single semantic mark → the mark char (*bold* _italic_ ~strike~ `code` ^hl^)\n * - link → [text](href)\n * - color/font/size, or combined marks → a styled span [text]{ k: v; k: v }\n * This is what lets partial styling round-trip (vs. flattening to the whole line).\n */\nfunction runToInlineText(child: JSONContent): string {\n if (child.type === \"hardBreak\") return \"\\\\n\";\n if (child.type !== \"text\") return extractText(child);\n const t = child.text || \"\";\n if (!t) return \"\";\n const marks = (child.marks || []) as Mark[];\n if (!marks.length) return t;\n\n const types = new Set(marks.map((m) => m.type));\n const link = marks.find((m) => m.type === \"link\");\n if (link?.attrs?.href) return `[${t}](${link.attrs.href})`;\n\n const ts = marks.find((m) => m.type === \"textStyle\")?.attrs || {};\n const hl = marks.find((m) => m.type === \"highlight\")?.attrs || {};\n const hasColorFont = !!(ts.color || ts.fontFamily || ts.fontSize || hl.color);\n const semanticCount = [\"bold\", \"italic\", \"strike\", \"underline\", \"code\"].filter(\n (k) => types.has(k),\n ).length;\n\n // Single semantic mark with no color/font and no combining → tidy mark char.\n if (!hasColorFont && semanticCount === 1 && !types.has(\"underline\")) {\n if (types.has(\"bold\")) return `*${t}*`;\n if (types.has(\"italic\")) return `_${t}_`;\n if (types.has(\"strike\")) return `~${t}~`;\n if (types.has(\"code\")) return `\\`${t}\\``;\n }\n if (!hasColorFont && semanticCount === 0 && types.has(\"highlight\") && !hl.color)\n return `^${t}^`;\n\n // Everything else (color/font/size, combined marks, underline) → styled span.\n const props = marksToProps(marks);\n const out: string[] = [];\n if (props.color) out.push(`color: ${props.color}`);\n if (props.family) out.push(`family: ${props.family}`);\n if (props.size) out.push(`size: ${props.size}`);\n if (props.weight) out.push(`weight: ${props.weight}`);\n if (props.italic === \"true\") out.push(`italic: true`);\n if (props.underline) out.push(`underline: true`);\n if (props.strike) out.push(`strike: true`);\n if (props.bg) out.push(`bg: ${props.bg}`);\n if (props.valign) out.push(`valign: ${props.valign}`);\n return out.length ? `[${t}]{ ${out.join(\"; \")} }` : t;\n}\n\n/**\n * Serialize a block's inline content to .it text, plus any block-level style props.\n * Whole-line case (a single uniformly-styled text run) → clean line-level props;\n * partial styling (multiple runs / mixed marks) → inline marks + styled spans.\n * `align` is always block-level.\n */\n/** Mark types the serializer can faithfully represent in `.it` (→ core-renderable). */\nconst SUPPORTED_MARKS = new Set([\n \"bold\",\n \"italic\",\n \"underline\",\n \"strike\",\n \"code\",\n \"highlight\",\n \"textStyle\",\n \"link\",\n \"subscript\",\n \"superscript\",\n]);\n\n/**\n * Fidelity guard: walk a TipTap doc for mark types the serializer can't represent\n * in `.it` (so they'd be lost on save and wouldn't print through core). Returns the\n * sorted unique unsupported mark types. Normally empty — every toolbar mark is\n * supported and TipTap drops unregistered marks on paste — so this catches\n * regressions (a new mark added without a serializer) rather than everyday use.\n */\nexport function detectUnsupportedStyling(node: JSONContent): string[] {\n const found = new Set<string>();\n const walk = (n: JSONContent) => {\n for (const m of (n.marks || []) as { type: string }[]) {\n if (!SUPPORTED_MARKS.has(m.type)) found.add(m.type);\n }\n for (const c of n.content || []) walk(c);\n };\n walk(node);\n return [...found].sort();\n}\n\nfunction inlineToSource(node: JSONContent): {\n text: string;\n props: Record<string, string>;\n} {\n const children = node.content || [];\n const align: Record<string, string> =\n node.attrs?.textAlign && node.attrs.textAlign !== \"left\"\n ? { align: String(node.attrs.textAlign) }\n : {};\n\n // Whole-line: exactly one text run → keep its style as line-level props.\n if (children.length === 1 && children[0].type === \"text\") {\n return {\n text: children[0].text || \"\",\n props: { ...marksToProps(children[0].marks as Mark[]), ...align },\n };\n }\n // Partial styling → marks/spans inline, no block-level style props.\n return { text: children.map(runToInlineText).join(\"\"), props: { ...align } };\n}\n\n/**\n * Extract plain text content from a TipTap node (no marks).\n * HardBreak nodes become literal \\n (backslash-n). Used for code blocks.\n */\nfunction extractText(node: JSONContent): string {\n if (!node.content) return \"\";\n return node.content\n .map((child) => {\n if (child.type === \"text\") return child.text || \"\";\n if (child.type === \"hardBreak\") return \"\\\\n\";\n return extractText(child);\n })\n .join(\"\");\n}\n\n/**\n * Merge mark-derived style props with existing (non-style) props.\n * Mark props override existing style keys; non-style keys are preserved.\n */\nfunction mergeProps(\n existingRaw: unknown,\n markProps: Record<string, string>,\n exclude?: Set<string>,\n): Record<string, string> {\n const existing = parseProps(existingRaw);\n // Remove mark-managed keys from existing (they'll come from marks)\n for (const key of MARK_STYLE_KEYS) delete existing[key];\n // Also remove any explicitly excluded keys\n if (exclude) for (const key of exclude) delete existing[key];\n return { ...existing, ...markProps };\n}\n\nfunction normalizeKeyword(keyword: string): string {\n const k = keyword.toLowerCase();\n return KEYWORD_ALIASES[k] || k;\n}\n\nfunction lineKeyword(trimmedLine: string): string | null {\n if (trimmedLine === \"---\") return \"divider\";\n const m = trimmedLine.match(/^([a-zA-Z][\\w-]*):/);\n if (!m) return null;\n return normalizeKeyword(m[1]);\n}\n\nfunction parsedBlockKeyword(blockType: string): string {\n return normalizeKeyword(blockType);\n}\n\nfunction keywordsMatch(sourceKey: string, parsedKey: string): boolean {\n if (sourceKey === parsedKey) return true;\n // Some callout aliases normalize to info in parser output.\n if (\n sourceKey === \"info\" &&\n [\"tip\", \"warning\", \"danger\", \"success\"].includes(parsedKey)\n ) {\n return true;\n }\n if (\n parsedKey === \"info\" &&\n [\"tip\", \"warning\", \"danger\", \"success\"].includes(sourceKey)\n ) {\n return true;\n }\n return false;\n}\n\nfunction parseInlineProps(rest: string): {\n content: string;\n properties: Record<string, string>;\n} {\n if (!rest) return { content: \"\", properties: {} };\n const parts = rest.split(\" | \");\n let content = parts[0] || \"\";\n const properties: Record<string, string> = {};\n\n for (let i = 1; i < parts.length; i++) {\n const seg = parts[i];\n const m = seg.match(/^([a-zA-Z_][\\w-]*)\\s*:\\s*(.*)$/);\n if (!m) {\n // Keep literal text segments that are not valid IT pipe props.\n content += ` | ${seg}`;\n continue;\n }\n properties[m[1]] = m[2];\n }\n\n return { content, properties };\n}\n\nfunction fallbackLineToBlock(trimmedLine: string): {\n type: string;\n content?: string;\n properties?: Record<string, string>;\n inline?: InlineNode[];\n} | null {\n if (trimmedLine === \"---\") return { type: \"divider\" };\n const m = trimmedLine.match(/^([a-zA-Z][\\w-]*):\\s*(.*)$/);\n if (!m) return null;\n\n const type = normalizeKeyword(m[1]);\n const rest = m[2] || \"\";\n const { content, properties } = parseInlineProps(rest);\n // Parse the content's inline marks/spans (*bold*, [text]{…}) via core so they\n // become TipTap marks. Core preserves {{vars}}, so templates are unaffected.\n let inline: InlineNode[] | undefined;\n try {\n inline = parseIntentText(`text: ${content}`).blocks[0]\n ?.inline as InlineNode[] | undefined;\n } catch {\n inline = undefined;\n }\n return { type, content, properties, inline };\n}\n\n/* ── Source → Doc ─────────────────────────────────────────── */\n\n/**\n * Convert IntentText source to TipTap JSON content\n */\n/** Match a bullet (`- x` / `* x`) or ordered (`1. x`) list line → its item text. */\nfunction listLineMatch(\n trimmed: string,\n): { ordered: boolean; text: string } | null {\n const bullet = trimmed.match(/^[-*]\\s+(.*)$/);\n if (bullet) return { ordered: false, text: bullet[1] };\n const ordered = trimmed.match(/^\\d+\\.\\s+(.*)$/);\n if (ordered) return { ordered: true, text: ordered[1] };\n return null;\n}\n\n/** A TipTap listItem wrapping a single paragraph of the item text. */\nfunction makeListItem(text: string): JSONContent {\n return {\n type: \"listItem\",\n content: [{ type: \"paragraph\", content: textToContent(text) }],\n };\n}\n\nexport function sourceToDoc(source: string): JSONContent {\n if (!source.trim()) {\n return {\n type: \"doc\",\n content: [{ type: \"paragraph\" }],\n };\n }\n\n const doc = parseIntentText(source);\n const content: JSONContent[] = [];\n\n for (const block of doc.blocks) {\n const node = blockToNode(block);\n if (node) content.push(node);\n }\n\n // Also handle comment lines (// ...) that the parser might skip\n const lines = source.split(\"\\n\");\n let blockIdx = 0;\n const result: JSONContent[] = [];\n\n for (let li = 0; li < lines.length; li++) {\n const line = lines[li];\n const trimmed = line.trim();\n\n // Skip empty lines\n if (!trimmed) continue;\n\n // Document-level metadata / layout blocks (page:, meta:, font:, header:,\n // footer:, watermark:) are not body content. Render them as a subtle preserved\n // chip (not raw \"| size: A4\" text) and keep the exact source line for\n // round-trip. Consume the matching parsed block to keep the stream aligned.\n {\n const mkw = lineKeyword(trimmed);\n if (mkw && META_KEYWORDS.has(mkw)) {\n result.push({ type: \"itMeta\", attrs: { raw: trimmed } });\n const pType = doc.blocks[blockIdx]?.type;\n if (pType && keywordsMatch(mkw, parsedBlockKeyword(pType))) blockIdx++;\n continue;\n }\n // Trust / history blocks → styled chip, exact source preserved.\n if (mkw && TRUST_KEYWORDS.has(mkw)) {\n result.push({ type: \"itTrust\", attrs: { raw: trimmed, keyword: mkw } });\n const pType = doc.blocks[blockIdx]?.type;\n if (pType && keywordsMatch(mkw, parsedBlockKeyword(pType))) blockIdx++;\n continue;\n }\n // Metric / total → label-left / value-right row, exact source preserved.\n if (mkw === \"metric\") {\n result.push({ type: \"itMetric\", attrs: { raw: trimmed } });\n const pType = doc.blocks[blockIdx]?.type;\n if (pType && keywordsMatch(mkw, parsedBlockKeyword(pType))) blockIdx++;\n continue;\n }\n // Scoped document style rule → visible chip; the rule itself is applied\n // live to the canvas by VisualEditor (documentStyleCSS). Raw preserved.\n if (mkw === \"style\") {\n result.push({ type: \"itStyleRule\", attrs: { raw: trimmed } });\n const pType = doc.blocks[blockIdx]?.type;\n if (pType && keywordsMatch(mkw, parsedBlockKeyword(pType))) blockIdx++;\n continue;\n }\n }\n\n // Group a run of bullet/ordered list lines into one TipTap list node, so\n // lists round-trip as list-items (not generic blocks). docToSource emits\n // `- item` / `N. item` for these.\n const listStart = listLineMatch(trimmed);\n if (listStart) {\n const ordered = listStart.ordered;\n const items: JSONContent[] = [];\n let lj = li;\n while (lj < lines.length) {\n const t = lines[lj].trim();\n const m = t ? listLineMatch(t) : null;\n if (!m || m.ordered !== ordered) break;\n items.push(makeListItem(m.text));\n // If this list item is a top-level block (not a section child), it also\n // sits in `content` — consume it so the trailing append doesn't dupe it.\n const pType = doc.blocks[blockIdx]?.type;\n if (pType === \"list-item\" || pType === \"step-item\") blockIdx++;\n lj++;\n }\n result.push({\n type: ordered ? \"orderedList\" : \"bulletList\",\n content: items,\n });\n li = lj - 1; // -1: the for-loop will increment\n continue;\n }\n\n // Group a run of `| a | b | c |` pipe-table lines into one itTable node, so\n // tables render instead of vanishing. The table is a section child (not a\n // top-level block), so we do NOT touch blockIdx. docToSource emits the\n // `| ... |` lines back.\n if (\n trimmed.startsWith(\"|\") &&\n trimmed.endsWith(\"|\") &&\n (trimmed.match(/\\|/g) || []).length >= 3\n ) {\n const rows: string[][] = [];\n let lj = li;\n while (lj < lines.length) {\n const t = lines[lj].trim();\n if (!(t.startsWith(\"|\") && t.endsWith(\"|\"))) break;\n rows.push(\n t\n .slice(1, -1)\n .split(\"|\")\n .map((c) => c.trim()),\n );\n lj++;\n }\n result.push({ type: \"itTable\", attrs: { rows: JSON.stringify(rows) } });\n li = lj - 1;\n continue;\n }\n\n // Comment lines\n if (trimmed.startsWith(\"//\")) {\n result.push({\n type: \"itComment\",\n content: trimmed.slice(2).trim()\n ? [{ type: \"text\", text: trimmed.slice(2).trim() }]\n : [],\n });\n continue;\n }\n\n // Code block fence — skip, handled by parser\n if (trimmed.startsWith(\"```\")) continue;\n\n const sourceKey = lineKeyword(trimmed);\n\n // Keep text/template lines literal to avoid parser normalization\n // (e.g. markdown marker stripping or placeholder mutation).\n if (sourceKey && (sourceKey === \"text\" || trimmed.includes(\"{{\"))) {\n const rawBlock = fallbackLineToBlock(trimmed);\n if (rawBlock) {\n const node = blockToNode(rawBlock);\n if (node) result.push(node);\n\n // Consume matching parsed block to keep parser index aligned.\n if (blockIdx < doc.blocks.length) {\n const parsedKey = parsedBlockKeyword(doc.blocks[blockIdx].type);\n if (keywordsMatch(sourceKey, parsedKey)) {\n blockIdx++;\n }\n }\n continue;\n }\n }\n\n // If parser produced a block, only consume it when keyword matches current line.\n if (blockIdx < content.length && sourceKey) {\n const nextParsed = doc.blocks[blockIdx];\n const parsedKey = parsedBlockKeyword(nextParsed.type);\n if (keywordsMatch(sourceKey, parsedKey)) {\n result.push(content[blockIdx]);\n blockIdx++;\n continue;\n }\n }\n\n // Fallback: parse line directly so raw source lines are never dropped.\n const rawBlock = fallbackLineToBlock(trimmed);\n if (rawBlock) {\n const node = blockToNode(rawBlock);\n if (node) result.push(node);\n continue;\n }\n\n // Final fallback: keep parser progression if nothing else matched.\n if (blockIdx < content.length) {\n result.push(content[blockIdx]);\n blockIdx++;\n }\n }\n\n // If we missed any blocks, append them\n while (blockIdx < content.length) {\n result.push(content[blockIdx]);\n blockIdx++;\n }\n\n return {\n type: \"doc\",\n content: result.length > 0 ? result : [{ type: \"paragraph\" }],\n };\n}\n\nfunction blockToNode(block: {\n type: string;\n content?: string;\n properties?: Record<string, string | number>;\n inline?: InlineNode[];\n}): JSONContent | null {\n const { type, content, properties, inline } = block;\n const text = content || \"\";\n\n // Build content from the inline AST (so *bold*, [text]{…} spans → real marks),\n // then layer any line-level style props (whole-line styling) as marks on top.\n let textContent = inlineToContent(inline, text);\n textContent = applyPropsAsMarks(textContent, properties);\n\n // Serialize all props to JSON string for TipTap attrs (used by extensions.ts buildStyle)\n const propsJson = properties\n ? JSON.stringify(\n Object.fromEntries(\n Object.entries(properties).map(([k, v]) => [k, String(v)]),\n ),\n )\n : \"{}\";\n\n // textAlign from 'align' property (for TipTap TextAlign extension)\n const textAlign = properties?.align ? String(properties.align) : undefined;\n\n // Title, Section, Sub → dedicated heading nodes\n if (type in HEADING_MAP) {\n return {\n type: HEADING_MAP[type],\n attrs: { props: propsJson, ...(textAlign && { textAlign }) },\n content: textContent.length ? textContent : undefined,\n };\n }\n\n // Summary\n if (type === \"summary\") {\n return {\n type: \"itSummary\",\n attrs: { props: propsJson, ...(textAlign && { textAlign }) },\n content: textContent.length ? textContent : undefined,\n };\n }\n\n // Text / body-text → paragraph. Core block properties (end/leading/\n // space-before/space-after) become real paragraph attributes so the\n // visual editor renders them AND serializes them back (see block-props.ts).\n if (type === \"text\" || type === \"body-text\") {\n const attrs: Record<string, string> = {};\n if (textAlign) attrs.textAlign = textAlign;\n if (properties?.end) attrs.end = String(properties.end);\n if (properties?.leading) attrs.leading = String(properties.leading);\n if (properties?.[\"space-before\"])\n attrs.spaceBefore = String(properties[\"space-before\"]);\n if (properties?.[\"space-after\"])\n attrs.spaceAfter = String(properties[\"space-after\"]);\n return {\n type: \"paragraph\",\n ...(Object.keys(attrs).length && { attrs }),\n content: textContent.length ? textContent : undefined,\n };\n }\n\n // Callouts\n if (CALLOUT_TYPES.has(type)) {\n const variant =\n type === \"info\" ? String(properties?.type || \"info\").toLowerCase() : type;\n const safeVariant = CALLOUT_TYPES.has(variant) ? variant : \"info\";\n\n return {\n type: \"itCallout\",\n attrs: { variant: safeVariant, props: propsJson },\n content: textContent.length ? textContent : undefined,\n };\n }\n\n // Quote\n if (type === \"quote\") {\n return {\n type: \"itQuote\",\n attrs: {\n by: properties?.by ? String(properties.by) : \"\",\n props: propsJson,\n ...(textAlign && { textAlign }),\n },\n content: textContent.length ? textContent : undefined,\n };\n }\n\n // Code (no marks on code blocks)\n if (type === \"code\") {\n return {\n type: \"itCode\",\n attrs: {\n lang: properties?.lang ? String(properties.lang) : \"\",\n props: propsJson,\n },\n content: text ? [{ type: \"text\", text }] : undefined,\n };\n }\n\n // Divider\n if (type === \"divider\") {\n return { type: \"itDivider\" };\n }\n\n // Break (page break)\n if (type === \"break\") {\n return { type: \"itBreak\" };\n }\n\n // All other keywords → generic block\n const propStr = properties\n ? Object.entries(properties)\n .filter(([, v]) => v !== undefined && v !== \"\")\n .map(([k, v]) => `${k}: ${v}`)\n .join(\" | \")\n : \"\";\n\n return {\n type: \"itGenericBlock\",\n attrs: { keyword: type, properties: propStr, props: propsJson },\n content: textContent.length ? textContent : undefined,\n };\n}\n\n/* ── Doc → Source ─────────────────────────────────────────── */\n\n/**\n * Convert TipTap JSON back to IntentText source\n */\nexport function docToSource(doc: JSONContent): string {\n if (!doc.content) return \"\";\n\n const lines: string[] = [];\n\n for (const node of doc.content) {\n lines.push(...nodeToLines(node));\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Convert a single TipTap node to one or more IT source lines. */\nfunction nodeToLines(node: JSONContent): string[] {\n // Lists → canonical `.it` bullet syntax so they round-trip as list-items, not\n // text. `- item` parses back to a list-item; `N. item` to a step-item.\n if (node.type === \"bulletList\" && node.content) {\n return node.content.flatMap((item) => {\n if (!item.content) return [];\n return item.content.map((child) => {\n const { text: t, props: mp } = inlineToSource(child);\n return `- ${t}${formatProps(mp)}`;\n });\n });\n }\n if (node.type === \"orderedList\" && node.content) {\n let idx = 1;\n return node.content.flatMap((item) => {\n if (!item.content) return [];\n return item.content.map((child) => {\n const { text: t, props: mp } = inlineToSource(child);\n return `${idx++}. ${t}${formatProps(mp)}`;\n });\n });\n }\n\n const line = nodeToLine(node);\n return line !== null ? [line] : [];\n}\n\nfunction nodeToLine(node: JSONContent): string | null {\n const { text, props: markProps } = inlineToSource(node);\n\n switch (node.type) {\n case \"itTitle\": {\n const merged = mergeProps(node.attrs?.props, markProps);\n return `title: ${text}${formatProps(merged)}`;\n }\n\n case \"itSummary\": {\n const merged = mergeProps(node.attrs?.props, markProps);\n return `summary: ${text}${formatProps(merged)}`;\n }\n\n case \"itSection\": {\n const merged = mergeProps(node.attrs?.props, markProps);\n return `section: ${text}${formatProps(merged)}`;\n }\n\n case \"itSub\": {\n const merged = mergeProps(node.attrs?.props, markProps);\n return `sub: ${text}${formatProps(merged)}`;\n }\n\n case \"paragraph\": {\n // Core block properties stored as paragraph attributes (block-props.ts)\n // → written back onto the line so PDF output matches the screen.\n const a = node.attrs || {};\n const blockProps: Record<string, string> = {};\n if (a.end) blockProps.end = String(a.end);\n if (a.leading) blockProps.leading = String(a.leading);\n if (a.spaceBefore) blockProps[\"space-before\"] = String(a.spaceBefore);\n if (a.spaceAfter) blockProps[\"space-after\"] = String(a.spaceAfter);\n return `text: ${text}${formatProps({ ...blockProps, ...markProps })}`;\n }\n\n case \"itCallout\": {\n const variant = node.attrs?.variant || \"tip\";\n const merged = mergeProps(\n node.attrs?.props,\n markProps,\n new Set([\"variant\"]),\n );\n if (variant === \"info\") {\n return `info: ${text}${formatProps(merged)}`;\n }\n return `info: ${text} | type: ${variant}${formatProps(merged, new Set([\"type\"]))}`;\n }\n\n case \"itQuote\": {\n const by = node.attrs?.by;\n const byPart = by ? ` | by: ${by}` : \"\";\n const merged = mergeProps(node.attrs?.props, markProps, new Set([\"by\"]));\n return `quote: ${text}${byPart}${formatProps(merged)}`;\n }\n\n case \"itCode\": {\n const lang = node.attrs?.lang || \"\";\n // Code is literal — never apply inline marks/spans.\n return `\\`\\`\\`${lang}\\n${extractText(node)}\\n\\`\\`\\``;\n }\n\n case \"itDivider\":\n return \"divider:\";\n\n case \"itTable\": {\n let rows: string[][] = [];\n try {\n rows = JSON.parse(node.attrs?.rows || \"[]\");\n } catch {\n rows = [];\n }\n return rows.map((r) => `| ${r.join(\" | \")} |`).join(\"\\n\");\n }\n\n case \"itMeta\":\n return node.attrs?.raw || \"\";\n\n case \"itTrust\":\n return node.attrs?.raw || \"\";\n\n case \"itMetric\":\n return node.attrs?.raw || \"\";\n\n case \"itStyleRule\":\n return node.attrs?.raw || \"\";\n\n case \"itBreak\":\n return \"break:\";\n\n case \"itComment\":\n return text ? `// ${text}` : \"//\";\n\n case \"itGenericBlock\": {\n const kw = node.attrs?.keyword || \"text\";\n const merged = mergeProps(node.attrs?.props, markProps);\n return `${kw}: ${text}${formatProps(merged)}`;\n }\n\n default:\n return text ? `text: ${text}${formatProps(markProps)}` : null;\n }\n}\n","// Keyword Style Map — Maps IT pipe properties to CSS\n// When user writes: text: Hello | align: center | color: #555\n// The editor applies matching CSS styles in real time.\n// Unknown properties are silently ignored and preserved.\n\nexport type StyleProperty =\n | \"align\"\n | \"color\"\n | \"bgcolor\"\n | \"size\"\n | \"weight\"\n | \"style\"\n | \"border\"\n | \"padding\"\n | \"indent\"\n | \"opacity\"\n | \"radius\"\n | \"shadow\"\n | \"width\"\n | \"height\"\n | \"spacing\"\n | \"columns\"\n | \"font\"\n | \"leading\"\n | \"striped\"\n | \"icon\"\n | \"blur\"\n | \"angle\"\n | \"family\"\n | \"margins\";\n\ninterface StyleRule {\n property: StyleProperty;\n css: string; // CSS property name\n transform?: (v: string) => string; // optional value transform\n}\n\n// Build style map: keyword → array of rules\nfunction direct(property: StyleProperty, css: string): StyleRule {\n return { property, css };\n}\n\n// Common property sets reused across keywords\nconst TEXT_STYLES: StyleRule[] = [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n direct(\"weight\", \"fontWeight\"),\n { property: \"style\", css: \"fontStyle\" },\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"padding\", \"padding\"),\n direct(\"indent\", \"paddingLeft\"),\n direct(\"opacity\", \"opacity\"),\n];\n\nconst CALLOUT_STYLES: StyleRule[] = [\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"color\", \"color\"),\n direct(\"border\", \"borderLeft\"),\n];\n\nconst CHIP_STYLES: StyleRule[] = [\n direct(\"color\", \"borderColor\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n];\n\nexport const KEYWORD_STYLES: Record<string, StyleRule[]> = {\n // ── Identity ──\n title: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n direct(\"weight\", \"fontWeight\"),\n direct(\"font\", \"fontFamily\"),\n ],\n summary: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n { property: \"style\", css: \"fontStyle\" },\n ],\n\n // ── Structure ──\n section: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n direct(\"weight\", \"fontWeight\"),\n direct(\"border\", \"borderBottom\"),\n direct(\"spacing\", \"marginTop\"),\n ],\n sub: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n direct(\"weight\", \"fontWeight\"),\n ],\n divider: [\n { property: \"style\", css: \"borderStyle\" },\n direct(\"color\", \"borderColor\"),\n direct(\"width\", \"borderTopWidth\"),\n direct(\"spacing\", \"margin\"),\n ],\n\n // ── Content ──\n text: [...TEXT_STYLES],\n tip: [...CALLOUT_STYLES],\n info: [...CALLOUT_STYLES],\n warning: [...CALLOUT_STYLES],\n danger: [...CALLOUT_STYLES],\n success: [...CALLOUT_STYLES],\n quote: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n { property: \"style\", css: \"fontStyle\" },\n direct(\"border\", \"borderLeft\"),\n direct(\"padding\", \"paddingLeft\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n ],\n cite: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n { property: \"style\", css: \"fontStyle\" },\n ],\n def: [\n direct(\"color\", \"color\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"border\", \"borderLeft\"),\n direct(\"padding\", \"paddingLeft\"),\n ],\n caption: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n { property: \"style\", css: \"fontStyle\" },\n ],\n footnote: [direct(\"color\", \"color\"), direct(\"size\", \"fontSize\")],\n byline: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n { property: \"style\", css: \"fontStyle\" },\n direct(\"weight\", \"fontWeight\"),\n ],\n epigraph: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n { property: \"style\", css: \"fontStyle\" },\n direct(\"padding\", \"padding\"),\n ],\n dedication: [\n direct(\"align\", \"textAlign\"),\n direct(\"color\", \"color\"),\n { property: \"style\", css: \"fontStyle\" },\n direct(\"padding\", \"padding\"),\n ],\n\n // ── Media ──\n image: [\n direct(\"width\", \"width\"),\n direct(\"height\", \"height\"),\n direct(\"radius\", \"borderRadius\"),\n direct(\"border\", \"border\"),\n direct(\"opacity\", \"opacity\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n {\n property: \"shadow\",\n css: \"boxShadow\",\n transform: () => \"0 4px 12px rgba(0,0,0,0.15)\",\n },\n ],\n figure: [\n direct(\"width\", \"width\"),\n direct(\"align\", \"textAlign\"),\n direct(\"border\", \"border\"),\n direct(\"padding\", \"padding\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n {\n property: \"shadow\",\n css: \"boxShadow\",\n transform: () => \"0 4px 12px rgba(0,0,0,0.15)\",\n },\n ],\n link: [direct(\"color\", \"color\"), direct(\"weight\", \"fontWeight\")],\n ref: [direct(\"color\", \"color\"), { property: \"style\", css: \"fontStyle\" }],\n embed: [\n direct(\"width\", \"width\"),\n direct(\"height\", \"height\"),\n direct(\"border\", \"border\"),\n direct(\"radius\", \"borderRadius\"),\n ],\n\n // ── Data ──\n metric: [\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n direct(\"align\", \"textAlign\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"border\", \"border\"),\n direct(\"padding\", \"padding\"),\n ],\n columns: [\n direct(\"border\", \"border\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"padding\", \"padding\"),\n direct(\"size\", \"fontSize\"),\n direct(\"align\", \"textAlign\"),\n ],\n row: [\n direct(\"border\", \"border\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"padding\", \"padding\"),\n direct(\"size\", \"fontSize\"),\n direct(\"align\", \"textAlign\"),\n ],\n input: [\n direct(\"color\", \"color\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"border\", \"borderLeft\"),\n direct(\"size\", \"fontSize\"),\n ],\n output: [\n direct(\"color\", \"color\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"border\", \"borderLeft\"),\n direct(\"size\", \"fontSize\"),\n ],\n\n // ── Code ──\n code: [\n direct(\"size\", \"fontSize\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"color\", \"color\"),\n direct(\"padding\", \"padding\"),\n direct(\"radius\", \"borderRadius\"),\n direct(\"border\", \"border\"),\n ],\n\n // ── Contact ──\n contact: [\n direct(\"color\", \"color\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"border\", \"border\"),\n direct(\"padding\", \"padding\"),\n direct(\"size\", \"fontSize\"),\n ],\n deadline: [\n direct(\"color\", \"color\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"weight\", \"fontWeight\"),\n direct(\"size\", \"fontSize\"),\n ],\n\n // ── Agent workflow chips ──\n step: [...CHIP_STYLES],\n decision: [...CHIP_STYLES],\n gate: [...CHIP_STYLES],\n trigger: [...CHIP_STYLES],\n loop: [...CHIP_STYLES],\n parallel: [...CHIP_STYLES],\n call: [...CHIP_STYLES],\n wait: [...CHIP_STYLES],\n checkpoint: [...CHIP_STYLES],\n error: [...CHIP_STYLES],\n result: [...CHIP_STYLES],\n audit: [...CHIP_STYLES],\n signal: [...CHIP_STYLES],\n handoff: [...CHIP_STYLES],\n retry: [...CHIP_STYLES],\n progress: [...CHIP_STYLES],\n tool: [...CHIP_STYLES],\n prompt: [...CHIP_STYLES],\n memory: [...CHIP_STYLES],\n policy: [...CHIP_STYLES],\n context: [...CHIP_STYLES],\n\n // ── Trust badges ──\n track: [...CHIP_STYLES],\n approve: [...CHIP_STYLES],\n sign: [...CHIP_STYLES],\n freeze: [...CHIP_STYLES],\n revision: [...CHIP_STYLES],\n amendment: [...CHIP_STYLES],\n history: [direct(\"color\", \"borderColor\")],\n\n // ── v2.13 ──\n assert: [\n direct(\"color\", \"borderColor\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"border\", \"borderLeft\"),\n ],\n secret: [\n direct(\"color\", \"color\"),\n direct(\"bgcolor\", \"backgroundColor\"),\n direct(\"blur\", \"filter\"),\n ],\n\n // ── Layout ──\n watermark: [\n direct(\"color\", \"color\"),\n direct(\"size\", \"fontSize\"),\n direct(\"opacity\", \"opacity\"),\n ],\n signline: [direct(\"color\", \"color\"), direct(\"width\", \"width\")],\n};\n\n/**\n * Build a CSSProperties-like object from a block's pipe properties.\n * Unknown properties are silently ignored.\n */\nexport function computeKeywordStyles(\n blockType: string,\n properties: Record<string, string>,\n): Record<string, string> {\n const rules = KEYWORD_STYLES[blockType];\n if (!rules) return {};\n\n const styles: Record<string, string> = {};\n\n for (const rule of rules) {\n const value = properties[rule.property];\n if (!value) continue;\n\n if (rule.transform) {\n styles[rule.css] = rule.transform(value);\n } else {\n styles[rule.css] = value;\n }\n }\n\n return styles;\n}\n\n/**\n * Returns which style properties are recognised for a given keyword.\n * Used by editor autocomplete to suggest pipe properties.\n */\nexport function getStyleProperties(blockType: string): StyleProperty[] {\n return (KEYWORD_STYLES[blockType] ?? []).map((r) => r.property);\n}\n","// TipTap extensions for IntentText block types\n// Maps IT keywords to ProseMirror nodes rendered in a Google Docs-like editor\n\nimport { Node, mergeAttributes } from \"@tiptap/core\";\nimport { computeKeywordStyles } from \"./keyword-styles\";\n\n// Helper: build inline style string from pipe properties\nfunction buildStyle(keyword: string, props: Record<string, string>): string {\n const styles = computeKeywordStyles(keyword, props);\n // Word-parity spacing — universal core style props on every block type,\n // mirroring core's STYLE_PROPERTIES (leading/space-before/space-after).\n if (props.leading) styles.lineHeight = props.leading;\n if (props[\"space-before\"]) styles.marginTop = props[\"space-before\"];\n if (props[\"space-after\"]) styles.marginBottom = props[\"space-after\"];\n return Object.entries(styles)\n .map(([k, v]) => `${k.replace(/([A-Z])/g, \"-$1\").toLowerCase()}:${v}`)\n .join(\";\");\n}\n\n// Two-sided row (`end:` property — core renders it on title/section/sub/text):\n// expose the end value as data-it-end so CSS turns the block into a flex\n// split row (`.it-split` parity) with the value as generated content.\nfunction endAttrs(props: Record<string, string>): Record<string, string> {\n return props.end ? { \"data-it-end\": props.end } : {};\n}\n\n// ── Title ─────────────────────────────────────────────────────\nexport const ITTitle = Node.create({\n name: \"itTitle\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n addAttributes() {\n return {\n props: {\n default: \"{}\",\n parseHTML: (el) => el.getAttribute(\"data-props\") || \"{}\",\n },\n };\n },\n\n parseHTML() {\n return [{ tag: 'h1[data-it-type=\"title\"]' }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const props = safeParse(node.attrs.props);\n const attrs = mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"title\",\n class: \"it-doc-title\",\n style: buildStyle(\"title\", props),\n ...endAttrs(props),\n });\n return props.end\n ? [\"h1\", attrs, [\"span\", { class: \"it-split-main\" }, 0]]\n : [\"h1\", attrs, 0];\n },\n});\n\n// ── Summary ───────────────────────────────────────────────────\nexport const ITSummary = Node.create({\n name: \"itSummary\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n addAttributes() {\n return {\n props: { default: \"{}\" },\n };\n },\n\n parseHTML() {\n return [{ tag: 'p[data-it-type=\"summary\"]' }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const props = safeParse(node.attrs.props);\n return [\n \"p\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"summary\",\n class: \"it-doc-summary\",\n style: buildStyle(\"summary\", props),\n }),\n 0,\n ];\n },\n});\n\n// ── Section (H2) ─────────────────────────────────────────────\nexport const ITSection = Node.create({\n name: \"itSection\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n addAttributes() {\n return {\n props: { default: \"{}\" },\n };\n },\n\n parseHTML() {\n return [{ tag: 'h2[data-it-type=\"section\"]' }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const props = safeParse(node.attrs.props);\n const attrs = mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"section\",\n class: \"it-doc-section\",\n style: buildStyle(\"section\", props),\n ...endAttrs(props),\n });\n return props.end\n ? [\"h2\", attrs, [\"span\", { class: \"it-split-main\" }, 0]]\n : [\"h2\", attrs, 0];\n },\n});\n\n// ── Sub (H3) ─────────────────────────────────────────────────\nexport const ITSub = Node.create({\n name: \"itSub\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n addAttributes() {\n return {\n props: { default: \"{}\" },\n };\n },\n\n parseHTML() {\n return [{ tag: 'h3[data-it-type=\"sub\"]' }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const props = safeParse(node.attrs.props);\n const attrs = mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"sub\",\n class: \"it-doc-sub\",\n style: buildStyle(\"sub\", props),\n ...endAttrs(props),\n });\n return props.end\n ? [\"h3\", attrs, [\"span\", { class: \"it-split-main\" }, 0]]\n : [\"h3\", attrs, 0];\n },\n});\n\n// ── Callout (tip, info, warning, danger, success) ────────────\nexport const ITCallout = Node.create({\n name: \"itCallout\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n addAttributes() {\n return {\n variant: {\n default: \"tip\",\n parseHTML: (el) => el.getAttribute(\"data-variant\") || \"tip\",\n renderHTML: (attrs) => ({ \"data-variant\": attrs.variant }),\n },\n props: { default: \"{}\" },\n };\n },\n\n parseHTML() {\n return [{ tag: 'div[data-it-type=\"callout\"]' }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const variant = node.attrs.variant || \"tip\";\n const props = safeParse(node.attrs.props);\n const icons: Record<string, string> = {\n tip: \"tip\",\n info: \"info\",\n warning: \"warning\",\n danger: \"danger\",\n success: \"success\",\n };\n return [\n \"div\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"callout\",\n \"data-variant\": variant,\n class: `it-doc-callout it-doc-callout-${variant}`,\n style: buildStyle(variant, props),\n }),\n [\n \"span\",\n {\n class: `it-doc-callout-icon it-doc-callout-icon-${icons[variant] || \"tip\"}`,\n contenteditable: \"false\",\n },\n \"\",\n ],\n [\"span\", { class: \"it-doc-callout-text\" }, 0],\n ];\n },\n});\n\n// ── Quote ─────────────────────────────────────────────────────\nexport const ITQuote = Node.create({\n name: \"itQuote\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n addAttributes() {\n return {\n by: { default: \"\" },\n props: { default: \"{}\" },\n };\n },\n\n parseHTML() {\n return [{ tag: 'blockquote[data-it-type=\"quote\"]' }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const props = safeParse(node.attrs.props);\n return [\n \"blockquote\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"quote\",\n class: \"it-doc-quote\",\n style: buildStyle(\"quote\", props),\n }),\n 0,\n ];\n },\n});\n\n// ── Code Block ────────────────────────────────────────────────\nexport const ITCode = Node.create({\n name: \"itCode\",\n group: \"block\",\n content: \"text*\",\n marks: \"\",\n code: true,\n defining: true,\n\n addAttributes() {\n return {\n lang: { default: \"\" },\n props: { default: \"{}\" },\n };\n },\n\n parseHTML() {\n return [{ tag: \"pre\" }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const props = safeParse(node.attrs.props);\n return [\n \"pre\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"code\",\n class: \"it-doc-code\",\n \"data-lang\": node.attrs.lang || \"\",\n style: buildStyle(\"code\", props),\n }),\n [\"code\", 0],\n ];\n },\n});\n\n// ── Divider ───────────────────────────────────────────────────\nexport const ITDivider = Node.create({\n name: \"itDivider\",\n group: \"block\",\n atom: true,\n\n parseHTML() {\n return [{ tag: \"hr\" }];\n },\n renderHTML({ HTMLAttributes }) {\n return [\"hr\", mergeAttributes(HTMLAttributes, { class: \"it-doc-divider\" })];\n },\n});\n\n// ── Metadata chip ─────────────────────────────────────────────\n// Document-level metadata/layout lines (page:, meta:, font:, header:, …) shown as\n// a subtle preserved chip instead of raw body text. `raw` holds the exact source\n// line for round-trip.\nexport const ITMeta = Node.create({\n name: \"itMeta\",\n group: \"block\",\n atom: true,\n\n addAttributes() {\n return {\n raw: {\n default: \"\",\n parseHTML: (el) => el.getAttribute(\"data-raw\") || \"\",\n renderHTML: (attrs) => ({ \"data-raw\": attrs.raw }),\n },\n };\n },\n parseHTML() {\n return [{ tag: \"div[data-it-meta]\" }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const raw = String(node.attrs.raw || \"\").replace(/\\s*\\|\\s*/g, \" · \");\n return [\n \"div\",\n mergeAttributes(HTMLAttributes, { \"data-it-meta\": \"\", class: \"it-doc-meta\" }),\n `⚙ ${raw}`,\n ];\n },\n});\n\n// ── Table ─────────────────────────────────────────────────────\n// Pipe table. `rows` is a JSON string of string[][] (first row = headers).\n// An atom node (so the table is one round-trippable unit), but a NodeView makes\n// every cell `contenteditable`: users click into headers/rows and edit the text\n// directly. Each edit writes the updated grid back to the `rows` attr, so\n// docToSource re-emits `| a | b |` lines with the new content. Enter/Tab are\n// swallowed inside cells so they don't break the document structure.\nfunction parseRows(raw: string): string[][] {\n try {\n const v = JSON.parse(raw || \"[]\");\n return Array.isArray(v) ? v : [];\n } catch {\n return [];\n }\n}\n\nexport const ITTable = Node.create({\n name: \"itTable\",\n group: \"block\",\n atom: true,\n selectable: true,\n\n addAttributes() {\n return {\n rows: {\n default: \"[]\",\n parseHTML: (el) => el.getAttribute(\"data-rows\") || \"[]\",\n renderHTML: (attrs) => ({ \"data-rows\": attrs.rows }),\n },\n };\n },\n parseHTML() {\n return [{ tag: \"table[data-it-table]\" }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const rows = parseRows(node.attrs.rows);\n const head = rows[0] || [];\n const body = rows.slice(1);\n return [\n \"table\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-table\": \"\",\n class: \"it-doc-table\",\n }),\n [\n \"thead\",\n [\"tr\", ...head.map((c) => [\"th\", tableCellAttrs(c), String(c)])],\n ],\n [\n \"tbody\",\n ...body.map((r) => [\n \"tr\",\n ...r.map((c) => [\"td\", tableCellAttrs(c), String(c)]),\n ]),\n ],\n ];\n },\n\n addNodeView() {\n return ({ node, editor, getPos }) => {\n const table = document.createElement(\"table\");\n table.className = \"it-doc-table\";\n table.setAttribute(\"data-it-table\", \"\");\n const thead = document.createElement(\"thead\");\n const tbody = document.createElement(\"tbody\");\n table.append(thead, tbody);\n\n let rows = parseRows(node.attrs.rows);\n\n // Push the in-DOM cell text back into the node's `rows` attr.\n const commit = () => {\n const next: string[][] = [];\n table.querySelectorAll(\"tr\").forEach((tr) => {\n const r: string[] = [];\n tr.querySelectorAll(\"th,td\").forEach((c) =>\n r.push((c.textContent || \"\").trim()),\n );\n next.push(r);\n });\n const json = JSON.stringify(next);\n if (json === node.attrs.rows) return;\n rows = next;\n if (typeof getPos === \"function\") {\n const pos = getPos();\n if (pos == null) return;\n const tr = editor.view.state.tr.setNodeAttribute(pos, \"rows\", json);\n editor.view.dispatch(tr);\n }\n };\n\n const makeCell = (tag: \"th\" | \"td\", text: string) => {\n const cell = document.createElement(tag);\n cell.textContent = text;\n const editable = editor.isEditable;\n cell.contentEditable = editable ? \"true\" : \"false\";\n if (/\\{\\{[^}]+\\}\\}|^each:/.test(String(text).trim()))\n cell.className = \"it-doc-var-cell\";\n cell.addEventListener(\"blur\", commit);\n cell.addEventListener(\"keydown\", (e) => {\n // Keep cell text single-line; Enter/Tab must not split the document.\n if (e.key === \"Enter\") {\n e.preventDefault();\n (e.target as HTMLElement).blur();\n }\n });\n return cell;\n };\n\n const render = (grid: string[][]) => {\n thead.innerHTML = \"\";\n tbody.innerHTML = \"\";\n const head = grid[0] || [];\n const htr = document.createElement(\"tr\");\n head.forEach((c) => htr.appendChild(makeCell(\"th\", String(c))));\n thead.appendChild(htr);\n grid.slice(1).forEach((row) => {\n const tr = document.createElement(\"tr\");\n row.forEach((c) => tr.appendChild(makeCell(\"td\", String(c))));\n tbody.appendChild(tr);\n });\n };\n render(rows);\n\n return {\n dom: table,\n // Re-render only when the attr changed from OUTSIDE this view (e.g.\n // source-mode edit), not from our own commit, to keep the caret stable.\n update(updated) {\n if (updated.type.name !== \"itTable\") return false;\n if (updated.attrs.rows !== JSON.stringify(rows)) {\n rows = parseRows(updated.attrs.rows);\n render(rows);\n }\n return true;\n },\n // The cells own the selection while editing; let ProseMirror ignore\n // mutations inside the contenteditable cells.\n ignoreMutation: () => true,\n };\n };\n },\n});\n\n/** Template cells ({{var}} or each:) get the variable-chip highlight. */\nfunction tableCellAttrs(cell: string): Record<string, string> {\n return /\\{\\{[^}]+\\}\\}|^each:/.test(String(cell).trim())\n ? { class: \"it-doc-var-cell\" }\n : {};\n}\n\n// ── Trust block (sign / seal / approve / freeze / amendment) ──\n// Renders tamper-evidence lines as proper styled chips instead of leaking raw\n// `| at: …` props. The exact source line is preserved in `raw` and re-emitted\n// verbatim on docToSource so the document hash never changes from a round-trip.\nfunction parseTrustLine(raw: string): {\n keyword: string;\n content: string;\n props: Record<string, string>;\n} {\n const colon = raw.indexOf(\":\");\n const keyword = (colon >= 0 ? raw.slice(0, colon) : raw).trim().toLowerCase();\n const rest = colon >= 0 ? raw.slice(colon + 1).trim() : \"\";\n const segs = rest.split(\"|\").map((s) => s.trim());\n const content = segs.shift() || \"\";\n const props: Record<string, string> = {};\n for (const seg of segs) {\n const c = seg.indexOf(\":\");\n if (c > 0) props[seg.slice(0, c).trim().toLowerCase()] = seg.slice(c + 1).trim();\n }\n return { keyword, content, props };\n}\n\nexport const ITTrust = Node.create({\n name: \"itTrust\",\n group: \"block\",\n atom: true,\n\n addAttributes() {\n return {\n raw: {\n default: \"\",\n parseHTML: (el) => el.getAttribute(\"data-raw\") || \"\",\n renderHTML: (attrs) => ({ \"data-raw\": attrs.raw }),\n },\n keyword: {\n default: \"\",\n parseHTML: (el) => el.getAttribute(\"data-trust\") || \"\",\n renderHTML: (attrs) => ({ \"data-trust\": attrs.keyword }),\n },\n };\n },\n parseHTML() {\n return [{ tag: \"div[data-it-trust]\" }];\n },\n renderHTML({ HTMLAttributes, node }) {\n // Ink-first typesetting, exactly mirroring core's print design\n // (document-css.ts .it-approval / .it-signature / .it-sealed-banner):\n // hairlines + small-caps labels, no colored fills - editor display = print.\n const { keyword, content, props } = parseTrustLine(\n String(node.attrs.raw || \"\"),\n );\n const role = props.role || props.title || \"\";\n const date = (props.at || props.date || props.time || \"\").slice(0, 10);\n const parts: (string | (string | object)[])[] = [];\n\n if (keyword === \"seal\" || keyword === \"freeze\") {\n // SEALED band - thin top+bottom rules, mono hash (core .it-sealed-banner).\n const hash =\n (keyword === \"seal\" ? content || props.hash : props.hash) || \"\";\n parts.push([\"span\", { class: \"it-doc-trust__label\" }, \"Sealed document\"]);\n if (date) parts.push([\"span\", { class: \"it-doc-trust__date\" }, date]);\n if (hash)\n parts.push([\n \"code\",\n { class: \"it-doc-trust__hash\" },\n hash.length > 20 ? hash.slice(0, 20) + \"...\" : hash,\n ]);\n } else if (keyword === \"approve\") {\n // Single hairline row: CHECK APPROVED | what | who | date(right) - the\n // check mark comes from CSS ::before, matching core's .it-approval__label.\n const who = props.by || content;\n const what = props.by ? content : \"\";\n parts.push([\"span\", { class: \"it-doc-trust__label\" }, \"Approved\"]);\n if (what) parts.push([\"span\", { class: \"it-doc-trust__what\" }, what]);\n if (who)\n parts.push([\n \"span\",\n { class: \"it-doc-trust__who\" },\n role ? `${who}, ${role}` : who,\n ]);\n if (date) parts.push([\"span\", { class: \"it-doc-trust__date\" }, date]);\n } else if (keyword === \"amend\" || keyword === \"amendment\") {\n parts.push([\"span\", { class: \"it-doc-trust__label\" }, \"Amendment\"]);\n if (content)\n parts.push([\"span\", { class: \"it-doc-trust__what\" }, content]);\n if (date) parts.push([\"span\", { class: \"it-doc-trust__date\" }, date]);\n } else {\n // sign - a signature rule line (core .it-signature): hairline rule on\n // top, name / role / date with a status flag at the line end.\n const name = content || props.by || \"\";\n const valid = !!props.hash;\n parts.push([\"span\", { class: \"it-doc-trust__name\" }, name]);\n if (role) parts.push([\"span\", { class: \"it-doc-trust__role\" }, role]);\n if (date) parts.push([\"span\", { class: \"it-doc-trust__date\" }, date]);\n parts.push([\n \"span\",\n { class: \"it-doc-trust__status\" },\n valid ? \"Signed \\u00b7 verified\" : \"Signed\",\n ]);\n }\n\n return [\n \"div\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-trust\": \"\",\n \"data-trust\": keyword,\n class: `it-doc-trust it-doc-trust--${keyword}`,\n }),\n ...parts,\n ];\n },\n});\n\n// ── Metric / total row ────────────────────────────────────────\n// `metric: Subtotal | value: 16,500 QAR | unit: …` renders as a label-left /\n// value-right row (invoice totals, KPIs). The generic block dropped `value:`\n// entirely. Raw source preserved verbatim for round-trip.\nexport const ITMetric = Node.create({\n name: \"itMetric\",\n group: \"block\",\n atom: true,\n\n addAttributes() {\n return {\n raw: {\n default: \"\",\n parseHTML: (el) => el.getAttribute(\"data-raw\") || \"\",\n renderHTML: (attrs) => ({ \"data-raw\": attrs.raw }),\n },\n };\n },\n parseHTML() {\n return [{ tag: \"div[data-it-metric]\" }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const { content, props } = parseTrustLine(String(node.attrs.raw || \"\"));\n const value = [props.value, props.unit].filter(Boolean).join(\" \");\n // A \"total\"/\"grand total\"/\"balance due\" label reads as the summary line.\n const isTotal = /\\b(total|balance due|amount due|grand)\\b/i.test(content);\n const valueIsVar = /\\{\\{[^}]+\\}\\}/.test(value);\n return [\n \"div\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-metric\": \"\",\n class: `it-doc-metric${isTotal ? \" it-doc-metric--total\" : \"\"}`,\n }),\n [\"span\", { class: \"it-doc-metric__label\" }, content],\n [\n \"span\",\n { class: `it-doc-metric__value${valueIsVar ? \" it-doc-var\" : \"\"}` },\n value,\n ],\n ];\n },\n});\n\n// ── Scoped document style rule ────────────────────────────────\n// `style: section | color: #0a7 | weight: 600` — house styling declared once,\n// document-wide. Shown as a visible chip (target + declarations) so authors can\n// SEE the rule; VisualEditor applies it live to the canvas via documentStyleCSS.\n// Raw line preserved verbatim for round-trip.\nexport const ITStyleRule = Node.create({\n name: \"itStyleRule\",\n group: \"block\",\n atom: true,\n\n addAttributes() {\n return {\n raw: {\n default: \"\",\n parseHTML: (el) => el.getAttribute(\"data-raw\") || \"\",\n renderHTML: (attrs) => ({ \"data-raw\": attrs.raw }),\n },\n };\n },\n parseHTML() {\n return [{ tag: \"div[data-it-style-rule]\" }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const { content, props } = parseTrustLine(String(node.attrs.raw || \"\"));\n const decl = Object.entries(props)\n .map(([k, v]) => `${k}: ${v}`)\n .join(\" · \");\n return [\n \"div\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-style-rule\": \"\",\n class: \"it-doc-stylerule\",\n }),\n [\"span\", { class: \"it-doc-stylerule__icon\" }, \"🎨\"],\n [\"span\", { class: \"it-doc-stylerule__target\" }, content || \"?\"],\n [\"span\", { class: \"it-doc-stylerule__decl\" }, decl],\n ];\n },\n});\n\n// ── Page Break ────────────────────────────────────────────────\nexport const ITBreak = Node.create({\n name: \"itBreak\",\n group: \"block\",\n atom: true,\n\n parseHTML() {\n return [{ tag: 'div[data-it-type=\"break\"]' }];\n },\n renderHTML({ HTMLAttributes }) {\n return [\n \"div\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"break\",\n class: \"it-doc-break\",\n }),\n ];\n },\n});\n\n// ── Generic IT Block (for all other keywords) ─────────────────\n// Renders as a styled chip/card with the keyword shown\nexport const ITGenericBlock = Node.create({\n name: \"itGenericBlock\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n addAttributes() {\n return {\n keyword: { default: \"text\" },\n properties: { default: \"\" },\n props: { default: \"{}\" },\n };\n },\n\n parseHTML() {\n return [{ tag: '[data-it-type=\"generic\"]' }];\n },\n renderHTML({ HTMLAttributes, node }) {\n const kw = node.attrs.keyword;\n const props = safeParse(node.attrs.props);\n const linkTarget = String(\n props.to || props.url || props.href || props.file || \"\",\n ).trim();\n\n if ((kw === \"link\" || kw === \"ref\") && linkTarget) {\n return [\n \"p\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"generic\",\n \"data-keyword\": kw,\n class: `it-doc-generic it-doc-kw-${kw}`,\n style: buildStyle(kw, props),\n }),\n [\n \"a\",\n {\n class: \"it-doc-inline-link\",\n href: linkTarget,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n 0,\n ],\n ];\n }\n\n return [\n \"p\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"generic\",\n \"data-keyword\": kw,\n class: `it-doc-generic it-doc-kw-${kw}`,\n style: buildStyle(kw, props),\n }),\n [\"span\", { class: \"it-doc-generic-content\" }, 0],\n ];\n },\n});\n\n// ── Comment line (// comments in IT source) ───────────────────\nexport const ITComment = Node.create({\n name: \"itComment\",\n group: \"block\",\n content: \"inline*\",\n defining: true,\n\n parseHTML() {\n return [{ tag: 'p[data-it-type=\"comment\"]' }];\n },\n renderHTML({ HTMLAttributes }) {\n return [\n \"p\",\n mergeAttributes(HTMLAttributes, {\n \"data-it-type\": \"comment\",\n class: \"it-doc-comment\",\n }),\n 0,\n ];\n },\n});\n\n// ── Helpers ────────────────────────────────────────────────────\nfunction safeParse(val: string): Record<string, string> {\n try {\n return typeof val === \"string\" ? JSON.parse(val) : val || {};\n } catch {\n return {};\n }\n}\n","// Block-level core properties as first-class TipTap attributes.\n//\n// Word-parity paragraph controls (line spacing, space before/after) and the\n// two-sided row (`end:`) are CORE `.it` properties — never editor-only styling.\n// This module makes them editable in the visual editor while guaranteeing they\n// serialize back onto the block line (see bridge.ts), so the PDF (rendered from\n// the same source) always matches the screen.\n//\n// - `leading` → core `leading:` → CSS line-height\n// - `spaceBefore` → core `space-before:` → CSS margin-top\n// - `spaceAfter` → core `space-after:` → CSS margin-bottom\n// - `end` → core `end:` → two-sided flex row (`.it-split`)\n//\n// Plain paragraphs (core `text:`/prose) carry these as real node attributes on\n// an extended Paragraph node; IT nodes that already round-trip a `props` JSON\n// attribute (title/section/sub/summary/quote/callout/generic) store them there\n// and render via extensions.ts buildStyle().\n\nimport { Extension } from \"@tiptap/core\";\nimport Paragraph from \"@tiptap/extension-paragraph\";\nimport { mergeAttributes } from \"@tiptap/core\";\nimport type { Editor } from \"@tiptap/core\";\n\n/** Core property keys managed by the paragraph-level commands. */\nexport type BlockPropKey = \"leading\" | \"space-before\" | \"space-after\" | \"end\";\n\n/** Core property key → paragraph attribute name. */\nconst PARA_ATTR: Record<BlockPropKey, string> = {\n leading: \"leading\",\n \"space-before\": \"spaceBefore\",\n \"space-after\": \"spaceAfter\",\n end: \"end\",\n};\n\n// Node types that keep ALL their line properties in a JSON `props` attribute\n// (serialized back by bridge.ts mergeProps). Spacing is portable on all of\n// them — core's STYLE_PROPERTIES applies to every block type.\nconst PROPS_JSON_SPACING = new Set([\n \"itTitle\",\n \"itSummary\",\n \"itSection\",\n \"itSub\",\n \"itQuote\",\n \"itCallout\",\n \"itGenericBlock\",\n]);\n// Core renders `end:` (two-sided rows) on title/section/sub/text/prose only —\n// the editor offers it exactly there so screen and PDF never diverge.\nconst PROPS_JSON_END = new Set([\"itTitle\", \"itSection\", \"itSub\"]);\n\nfunction safeParseProps(val: unknown): Record<string, string> {\n try {\n return typeof val === \"string\" ? JSON.parse(val) : (val as Record<string, string>) || {};\n } catch {\n return {};\n }\n}\n\nfunction supportsKey(typeName: string, key: BlockPropKey): boolean {\n if (typeName === \"paragraph\") return true;\n if (key === \"end\") return PROPS_JSON_END.has(typeName);\n return PROPS_JSON_SPACING.has(typeName);\n}\n\n/**\n * Extended Paragraph: a core `text:`/prose block. Adds the four core block\n * properties as attributes and renders the `end:` value as the second side of\n * a flex split row (matching core's `.it-split` / `.it-split-main` CSS).\n */\nexport const ITParagraph = Paragraph.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n leading: {\n default: null,\n parseHTML: (el) => el.style.lineHeight || null,\n renderHTML: (attrs) =>\n attrs.leading ? { style: `line-height: ${attrs.leading}` } : {},\n },\n spaceBefore: {\n default: null,\n parseHTML: (el) => el.style.marginTop || null,\n renderHTML: (attrs) =>\n attrs.spaceBefore ? { style: `margin-top: ${attrs.spaceBefore}` } : {},\n },\n spaceAfter: {\n default: null,\n parseHTML: (el) => el.style.marginBottom || null,\n renderHTML: (attrs) =>\n attrs.spaceAfter\n ? { style: `margin-bottom: ${attrs.spaceAfter}` }\n : {},\n },\n end: {\n default: null,\n parseHTML: (el) => el.getAttribute(\"data-it-end\"),\n renderHTML: (attrs) =>\n attrs.end ? { \"data-it-end\": attrs.end } : {},\n },\n };\n },\n\n renderHTML({ node, HTMLAttributes }) {\n // Two-sided row: wrap the editable content in `.it-split-main` so it is a\n // single flex item; the `end:` value renders as CSS generated content from\n // data-it-end (non-editable, exactly like core's split-end span).\n if (node.attrs.end) {\n return [\n \"p\",\n mergeAttributes(HTMLAttributes),\n [\"span\", { class: \"it-split-main\" }, 0],\n ];\n }\n return [\"p\", mergeAttributes(HTMLAttributes), 0];\n },\n});\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n blockProps: {\n /**\n * Set (or clear, with null) a core block property on every block in the\n * current selection that supports it. Writes through to the `.it` source\n * via the bridge — paragraph attrs or the node's `props` JSON.\n */\n setBlockProp: (key: BlockPropKey, value: string | null) => ReturnType;\n };\n }\n}\n\nexport const BlockProps = Extension.create({\n name: \"blockProps\",\n\n addCommands() {\n return {\n setBlockProp:\n (key: BlockPropKey, value: string | null) =>\n ({ state, tr, dispatch }) => {\n const { from, to } = state.selection;\n let changed = false;\n state.doc.nodesBetween(from, to, (node, pos) => {\n const name = node.type.name;\n // Don't descend into lists/tables — list items serialize without\n // block props, so styling them would silently not round-trip.\n if (name === \"bulletList\" || name === \"orderedList\") return false;\n if (!node.isBlock || node.isAtom) return false;\n if (!supportsKey(name, key)) return true;\n\n if (name === \"paragraph\") {\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [PARA_ATTR[key]]: value,\n });\n } else {\n const props = safeParseProps(node.attrs.props);\n if (value == null || value === \"\") delete props[key];\n else props[key] = value;\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n props: JSON.stringify(props),\n });\n }\n changed = true;\n return false;\n });\n if (changed && dispatch) dispatch(tr);\n return changed;\n },\n };\n },\n});\n\n/** Read a core block property from the first supporting block in the selection. */\nexport function getBlockProp(\n editor: Editor | null,\n key: BlockPropKey,\n): string | null {\n if (!editor) return null;\n const { state } = editor;\n const { from, to } = state.selection;\n let found: string | null = null;\n state.doc.nodesBetween(from, to, (node) => {\n if (found !== null) return false;\n const name = node.type.name;\n if (!supportsKey(name, key)) return true;\n if (name === \"paragraph\") {\n const v = node.attrs[PARA_ATTR[key]];\n found = v != null ? String(v) : \"\";\n } else {\n found = safeParseProps(node.attrs.props)[key] ?? \"\";\n }\n return false;\n });\n return found;\n}\n","// Shared types for the visual editor\n\n/**\n * Trust actions surfaced by the ribbon's Trust group. The host app decides\n * what each action opens (a seal dialog, a signature flow, a verify panel…) —\n * the editor only reports the intent.\n */\nexport type TrustAction = \"seal\" | \"sign\" | \"verify\";\n\n// Category metadata for UI grouping\nexport interface CategoryInfo {\n label: string;\n icon: string;\n color: string;\n}\n\nexport const CATEGORY_META: Record<string, CategoryInfo> = {\n identity: { label: \"Identity\", icon: \"ID\", color: \"#3b82f6\" },\n content: { label: \"Content\", icon: \"Tx\", color: \"#6b7280\" },\n structure: { label: \"Structure\", icon: \"##\", color: \"#22c55e\" },\n data: { label: \"Data\", icon: \"Dt\", color: \"#a855f7\" },\n agent: { label: \"Agent\", icon: \"Ag\", color: \"#f97316\" },\n trust: { label: \"Trust\", icon: \"Tr\", color: \"#eab308\" },\n layout: { label: \"Layout\", icon: \"Pg\", color: \"#64748b\" },\n};\n\n// Keywords that are read-only in visual mode\nexport const READ_ONLY_KEYWORDS = new Set([\n \"freeze\",\n \"revision\",\n \"history\",\n \"track\",\n]);\n\n// Keywords that support inline content editing\nexport const INLINE_EDITABLE_KEYWORDS = new Set([\n \"text\",\n \"title\",\n \"summary\",\n \"section\",\n \"sub\",\n \"quote\",\n \"tip\",\n \"warning\",\n \"info\",\n \"success\",\n \"danger\",\n \"code\",\n \"def\",\n \"byline\",\n \"epigraph\",\n \"caption\",\n \"footnote\",\n \"dedication\",\n]);\n","// Shared browser print: write an HTML document into a real-size hidden iframe\n// and open the native print dialog (→ Save as PDF). A zero-size iframe prints\n// blank/unstyled in Chrome, so the frame gets A4 dimensions off-screen.\n\nexport function printHtmlViaIframe(html: string): void {\n const iframe = document.createElement(\"iframe\");\n iframe.setAttribute(\"aria-hidden\", \"true\");\n iframe.style.cssText =\n \"position:fixed;right:0;bottom:0;width:210mm;height:297mm;border:0;visibility:hidden;\";\n document.body.appendChild(iframe);\n\n let printed = false;\n const doPrint = () => {\n if (printed) return;\n printed = true;\n try {\n iframe.contentWindow!.focus();\n iframe.contentWindow!.print();\n } finally {\n setTimeout(() => iframe.remove(), 1000);\n }\n };\n iframe.onload = () => window.setTimeout(doPrint, 120);\n\n const idoc = iframe.contentWindow!.document;\n idoc.open();\n idoc.write(html);\n idoc.close();\n // Fallback if onload doesn't fire for a written document.\n if (idoc.readyState === \"complete\") window.setTimeout(doPrint, 250);\n}\n","// Print / export engine for the editor.\n//\n// The UI for these actions lives in the ribbon (DocsToolbar.tsx); host apps can\n// also call exportDocumentPDF / exportDocumentHTML directly — this module owns\n// the WYSIWYG print path and the document export functions they trigger.\n\nimport {\n parseIntentText,\n renderPrint,\n listBuiltinThemes,\n cssContentValue,\n} from \"@dotit/core\";\nimport { getPageGeometry } from \"./page-geometry\";\nimport { printHtmlViaIframe } from \"./print-iframe\";\n\nexport type PrintMode = \"normal\" | \"minimal-ink\";\n\n/** Inject extra CSS before </head> of an HTML document string. */\nfunction injectCss(html: string, css: string): string {\n if (!css) return html;\n return html.includes(\"</head>\")\n ? html.replace(\"</head>\", `<style>${css}</style></head>`)\n : html;\n}\n\nconst MINIMAL_INK_CSS =\n \".it-doc-callout{background:none!important;border:1px solid #ccc!important}\";\n\n// Header/footer CSS `content` value (maps {{page}}/{{pages}} → counters, CSS-escapes).\n// Shared with core's renderPrint so the editor and core build running headers/footers\n// identically — single source of truth.\nconst cssContent = cssContentValue;\n\n/**\n * WYSIWYG print: render the editor's OWN content DOM with its OWN stylesheets, so the\n * PDF looks exactly like the visual editor. Page size / margins / running header+footer\n * come from the document's page:/header:/footer: blocks via @page. Returns null when\n * the visual editor isn't mounted — caller falls back to renderPrint.\n */\nfunction buildWysiwygPrint(content: string, printMode: string): string | null {\n const tiptap = document.querySelector(\".docs-page .tiptap\");\n if (!tiptap) return null;\n\n const clone = tiptap.cloneNode(true) as HTMLElement;\n // Page-break spacers are a screen affordance; print paginates natively via @page.\n clone.querySelectorAll(\"[data-it-spacer]\").forEach((e) => e.remove());\n // Comments (// lines) are an editing affordance only — never print them.\n clone\n .querySelectorAll('.it-doc-comment, [data-it-type=\"comment\"]')\n .forEach((e) => e.remove());\n const bodyHtml = clone.innerHTML;\n\n // Copy the page's stylesheets (the bundled editor CSS + injected theme) verbatim.\n const styles = Array.from(\n document.querySelectorAll('style, link[rel=\"stylesheet\"]'),\n )\n .map((e) => e.outerHTML)\n .join(\"\\n\");\n\n // Use the SAME geometry the on-screen pages use (the doc's page: block parsed\n // by page-geometry.ts) — identical px numbers in @page is what makes the PDF\n // paginate exactly where the editor shows the breaks.\n const g = getPageGeometry(content);\n const sizeCss = g.autoHeight\n ? `${g.width}px auto`\n : `${g.width}px ${g.height}px`;\n const marginCss = `${g.marginTop}px ${g.marginRight}px ${g.marginBottom}px ${g.marginLeft}px`;\n\n let pageCss = `@page{size:${sizeCss};margin:${marginCss};}`;\n if (g.header)\n pageCss += `@page{@top-center{content:${cssContent(g.header)};font:10px -apple-system,sans-serif;color:#9aa0a6;}}`;\n if (g.footer)\n pageCss += `@page{@bottom-center{content:${cssContent(g.footer)};font:10px -apple-system,sans-serif;color:#9aa0a6;}}`;\n\n // Strip the on-screen sheet chrome so only the page content prints.\n const overrides = `\n html,body{margin:0;background:#fff;}\n .docs-page,.docs-page.docs-sheet{box-shadow:none;border-radius:0;margin:0;width:auto;min-height:0;padding:0;background:#fff;}\n .docs-page .tiptap{padding:0;}\n [data-it-spacer]{display:none!important;}\n ${printMode === \"minimal-ink\" ? MINIMAL_INK_CSS : \"\"}\n `;\n\n return `<!doctype html><html><head><meta charset=\"utf-8\">${styles}<style>${pageCss}${overrides}</style></head><body><div class=\"docs-page docs-sheet\"><div class=\"tiptap\">${bodyHtml}</div></div></body></html>`;\n}\n\nfunction download(data: string, filename: string, mime: string) {\n const blob = new Blob([data], { type: mime });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename;\n a.click();\n URL.revokeObjectURL(url);\n}\n\n/** Build the print-ready HTML: WYSIWYG when the visual editor is mounted,\n * core renderPrint otherwise (e.g. a source-mode export). */\nfunction buildPrintHtml(\n content: string,\n theme: string,\n printMode: PrintMode,\n): string {\n let full = buildWysiwygPrint(content, printMode);\n if (!full) {\n const doc = parseIntentText(content);\n full = renderPrint(doc, { theme });\n if (printMode === \"minimal-ink\") full = injectCss(full, MINIMAL_INK_CSS);\n }\n return full;\n}\n\n/** Print / save-as-PDF via the browser's print dialog. Browser-only. */\nexport function exportDocumentPDF(\n content: string,\n theme: string,\n printMode: PrintMode = \"normal\",\n) {\n try {\n printHtmlViaIframe(buildPrintHtml(content, theme, printMode));\n } catch {\n /* ignore */\n }\n}\n\n/** Download the raw `.it` source as a file. This is the editor's \"Save\".\n * Derives a filename from the document's meta id / title when available. */\nexport function downloadItFile(content: string, filename?: string) {\n try {\n let name = filename;\n if (!name) {\n try {\n const doc = parseIntentText(content);\n const meta = doc.blocks.find((b) => b.type === \"meta\");\n const id = meta?.properties?.id;\n const title =\n doc.blocks.find((b) => b.type === \"title\")?.content || \"\";\n const base = String(id || title || \"document\")\n .trim()\n .replace(/[^\\w\\-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 60) || \"document\";\n name = `${base}.it`;\n } catch {\n name = \"document.it\";\n }\n }\n download(content, name, \"text/plain;charset=utf-8\");\n } catch {\n /* ignore */\n }\n}\n\n/** Download the print-ready HTML document. Browser-only. */\nexport function exportDocumentHTML(\n content: string,\n theme: string,\n printMode: PrintMode = \"normal\",\n) {\n try {\n download(\n buildPrintHtml(content, theme, printMode),\n \"document.html\",\n \"text/html\",\n );\n } catch {\n /* ignore */\n }\n}\n\n/** Built-in theme ids — for the ribbon's theme select. */\nexport function builtinThemes(): string[] {\n return listBuiltinThemes() as string[];\n}\n","// TrustControl — the single, self-explanatory trust menu in the ribbon.\n//\n// One button shows the document's current STATE; clicking opens a small popover\n// with exactly the actions that make sense for that state:\n//\n// Draft → [Sign] [Seal]\n// Signed by N → [Sign] [Seal] (lists who signed)\n// 🔒 Sealed → [Verify] [Unseal] (verified ✓, hash on expand)\n//\n// Every action calls a core 1.2.0 API that is idempotent on the source string,\n// so repeat clicks never corrupt the document. Rapid clicks are debounced.\n\nimport { useState, useRef, useEffect, useCallback } from \"react\";\nimport {\n signDocument,\n sealDocument,\n unsealDocument,\n verifyDocument,\n isSealed as coreIsSealed,\n} from \"@dotit/core\";\nimport { ShieldCheck, PenTool, FileLock2, LockOpen, ChevronDown } from \"lucide-react\";\nimport type { TrustState } from \"./trust-state\";\n\ninterface Props {\n /** Current .it source. */\n content: string;\n /** Apply a new source produced by a trust action. */\n onChange: (source: string) => void;\n /** Trust snapshot (drives the button label + which actions show). */\n trust: TrustState;\n /** verifyDocument().intact — null when not sealed. */\n intact: boolean | null;\n}\n\nconst SIGNER_KEY = \"dotit.editor.lastSigner\";\nconst ROLE_KEY = \"dotit.editor.lastRole\";\n\nexport function TrustControl({ content, onChange, trust, intact }: Props) {\n const [open, setOpen] = useState(false);\n const [signing, setSigning] = useState(false);\n const [signer, setSigner] = useState(\n () => localStorage.getItem(SIGNER_KEY) || \"\",\n );\n const [role, setRole] = useState(() => localStorage.getItem(ROLE_KEY) || \"\");\n const [busy, setBusy] = useState(false);\n const rootRef = useRef<HTMLDivElement>(null);\n const lastClickRef = useRef(0);\n\n // Debounce: ignore a second click within 400ms (the core APIs are already\n // idempotent — this just stops the UI flicker from frantic double-clicks).\n const debounced = useCallback((fn: () => void) => {\n const now = Date.now();\n if (now - lastClickRef.current < 400) return;\n lastClickRef.current = now;\n fn();\n }, []);\n\n useEffect(() => {\n if (!open) return;\n const onDown = (e: MouseEvent) => {\n if (rootRef.current && !rootRef.current.contains(e.target as Node)) {\n setOpen(false);\n setSigning(false);\n }\n };\n document.addEventListener(\"mousedown\", onDown);\n return () => document.removeEventListener(\"mousedown\", onDown);\n }, [open]);\n\n const sealed = trust.isSealed || coreIsSealed(content);\n\n const doSign = useCallback(() => {\n const name = signer.trim();\n if (!name) return;\n setBusy(true);\n try {\n const res = signDocument(content, {\n signer: name,\n role: role.trim() || undefined,\n });\n // Idempotent: res.note === \"already-signed\" → source unchanged, no spam.\n if (res.source && res.source !== content) onChange(res.source);\n localStorage.setItem(SIGNER_KEY, name);\n if (role.trim()) localStorage.setItem(ROLE_KEY, role.trim());\n } finally {\n setBusy(false);\n setSigning(false);\n setOpen(false);\n }\n }, [content, onChange, signer, role]);\n\n const doSeal = useCallback(() => {\n const name =\n signer.trim() || trust.signatures[0]?.by || \"Document owner\";\n setBusy(true);\n try {\n const res = sealDocument(content, {\n signer: name,\n role: role.trim() || trust.signatures[0]?.role || undefined,\n });\n // Idempotent: error \"already-sealed\" → leave source as-is.\n if (res.source && res.source !== content && !res.error) {\n onChange(res.source);\n }\n } finally {\n setBusy(false);\n setOpen(false);\n }\n }, [content, onChange, signer, role, trust.signatures]);\n\n const doUnseal = useCallback(() => {\n setBusy(true);\n try {\n // unsealDocument returns the new source string directly.\n const next = unsealDocument(content);\n if (typeof next === \"string\" && next !== content) onChange(next);\n } finally {\n setBusy(false);\n setOpen(false);\n }\n }, [content, onChange]);\n\n const [verifyResult, setVerifyResult] = useState<ReturnType<\n typeof verifyDocument\n > | null>(null);\n const doVerify = useCallback(() => {\n try {\n setVerifyResult(verifyDocument(content));\n } catch {\n setVerifyResult(null);\n }\n }, [content]);\n\n // ── Button face: state at a glance ──────────────────────────\n let faceIcon = <PenTool size={15} />;\n let faceLabel = \"Draft\";\n let faceClass = \"trust-face--draft\";\n if (sealed) {\n faceIcon = <FileLock2 size={15} />;\n faceLabel = intact === false ? \"Sealed · changed!\" : \"Sealed\";\n faceClass =\n intact === false ? \"trust-face--broken\" : \"trust-face--sealed\";\n } else if (trust.signatures.length > 0) {\n faceIcon = <ShieldCheck size={15} />;\n faceLabel = `Signed · ${trust.signatures.length}`;\n faceClass = \"trust-face--signed\";\n }\n\n return (\n <div className=\"trust-control\" ref={rootRef}>\n <button\n className={`docs-tb-btn trust-face ${faceClass}`}\n onClick={() => {\n setOpen((o) => !o);\n setSigning(false);\n if (sealed) doVerify();\n }}\n title=\"Document trust — sign, seal, verify\"\n >\n <span className=\"trust-face__icon\">{faceIcon}</span>\n <span className=\"ribbon-btn-text\">{faceLabel}</span>\n {sealed && intact === true && (\n <span className=\"trust-face__ok\" title=\"Hash verified\">\n ✓\n </span>\n )}\n <ChevronDown size={12} />\n </button>\n\n {open && (\n <div className=\"trust-popover\">\n {/* Current state line */}\n <div className=\"trust-popover__state\">\n {sealed ? (\n <>\n <strong>🔒 Sealed — read-only</strong>\n <div className=\"trust-popover__meta\">\n {trust.sealedBy && <>by {trust.sealedBy}</>}\n {trust.sealedAt && <> on {trust.sealedAt}</>}\n </div>\n </>\n ) : trust.signatures.length > 0 ? (\n <>\n <strong>Signed</strong>\n <div className=\"trust-popover__meta\">\n {trust.signatures\n .map((s) => (s.role ? `${s.by} (${s.role})` : s.by))\n .join(\" · \")}\n </div>\n </>\n ) : (\n <>\n <strong>Draft</strong>\n <div className=\"trust-popover__meta\">\n Not signed or sealed yet.\n </div>\n </>\n )}\n </div>\n\n <div className=\"trust-popover__divider\" />\n\n {/* Actions for the current state */}\n {sealed ? (\n <>\n <div className=\"trust-popover__verify\">\n {verifyResult ? (\n verifyResult.intact ? (\n <span className=\"trust-verify--ok\">\n ✓ Verified — content matches the seal\n </span>\n ) : (\n <span className=\"trust-verify--bad\">\n ⚠ Hash mismatch — content changed after sealing\n </span>\n )\n ) : null}\n {verifyResult?.hash && (\n <details className=\"trust-popover__hash\">\n <summary>Show hash</summary>\n <code>{verifyResult.hash}</code>\n </details>\n )}\n </div>\n <button\n className=\"trust-popover__action\"\n onClick={() => debounced(doVerify)}\n disabled={busy}\n >\n <ShieldCheck size={14} /> Re-verify\n </button>\n <button\n className=\"trust-popover__action trust-popover__action--warn\"\n onClick={() => debounced(doUnseal)}\n disabled={busy}\n title=\"Remove the freeze lock (keeps signatures) and make the document editable again\"\n >\n <LockOpen size={14} /> Unseal (make editable)\n </button>\n </>\n ) : signing ? (\n <div className=\"trust-sign-form\">\n <input\n className=\"trust-sign-input\"\n placeholder=\"Your name\"\n value={signer}\n autoFocus\n onChange={(e) => setSigner(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") doSign();\n if (e.key === \"Escape\") setSigning(false);\n }}\n />\n <input\n className=\"trust-sign-input\"\n placeholder=\"Role (optional, e.g. CEO)\"\n value={role}\n onChange={(e) => setRole(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") doSign();\n if (e.key === \"Escape\") setSigning(false);\n }}\n />\n <div className=\"trust-sign-actions\">\n <button\n className=\"trust-popover__action trust-popover__action--primary\"\n onClick={doSign}\n disabled={busy || !signer.trim()}\n >\n <PenTool size={14} /> Add signature\n </button>\n <button\n className=\"trust-popover__action\"\n onClick={() => setSigning(false)}\n >\n Cancel\n </button>\n </div>\n </div>\n ) : (\n <>\n <button\n className=\"trust-popover__action\"\n onClick={() => setSigning(true)}\n disabled={busy}\n title=\"Add a signature line (does not freeze the document)\"\n >\n <PenTool size={14} /> Sign\n </button>\n <button\n className=\"trust-popover__action trust-popover__action--primary\"\n onClick={() => debounced(doSeal)}\n disabled={busy}\n title=\"Freeze the document with a tamper-evident hash. It becomes read-only until unsealed.\"\n >\n <FileLock2 size={14} /> Seal (freeze)\n </button>\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n","// The editor ribbon — ONE compact, Google-Docs-style toolbar row with groups:\n//\n// Edit | File (PDF / HTML / theme) | Text | Paragraph | Insert | Trust\n//\n// Every formatting control maps to a CORE `.it` property (size:/align:/leading:/\n// space-before:/space-after:/end:) through bridge.ts, so what you style here is\n// what core prints. Export actions are the WYSIWYG print path from print.ts.\n\nimport { useState, useRef, useEffect, useCallback, useMemo } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n Undo2,\n Redo2,\n Bold,\n Italic,\n Underline,\n Strikethrough,\n Code,\n AlignLeft,\n AlignCenter,\n AlignRight,\n AlignJustify,\n List,\n ListOrdered,\n Minus,\n Plus,\n Palette,\n Highlighter,\n RemoveFormatting,\n ChevronDown,\n Printer,\n Download,\n Droplets,\n Rows3,\n AlignHorizontalSpaceBetween,\n} from \"lucide-react\";\nimport { LANGUAGE_REGISTRY } from \"@dotit/core\";\nimport { CATEGORY_META } from \"./types\";\nimport { getBlockProp } from \"./block-props\";\nimport {\n exportDocumentPDF,\n downloadItFile,\n builtinThemes,\n} from \"./print\";\nimport { TrustControl } from \"./TrustControl\";\nimport type { TrustState } from \"./trust-state\";\nimport type { TrustAction } from \"./types\";\n\ninterface Props {\n editor: Editor | null;\n isRtl?: boolean;\n onToggleRtl?: () => void;\n /** Current .it source — used by the export actions. */\n content: string;\n /** Apply a new source (used by the self-contained trust control). */\n onChange?: (source: string) => void;\n theme: string;\n onThemeChange: (theme: string) => void;\n /**\n * Optional host override for the Trust control. When omitted the editor's own\n * self-contained TrustControl handles sign/seal/verify/unseal via core.\n */\n onTrustAction?: (action: TrustAction) => void;\n /** Trust snapshot — drives the built-in TrustControl. */\n trust?: TrustState;\n /** verifyDocument().intact — null when not sealed. */\n sealIntact?: boolean | null;\n /** Sealed documents are read-only — formatting groups are disabled. */\n locked?: boolean;\n}\n\n/* ── Style options that map to IT keywords ──────────────────── */\nconst STYLE_OPTIONS = [\n { label: \"Normal text\", node: \"paragraph\" },\n { label: \"Title\", node: \"itTitle\" },\n { label: \"Section\", node: \"itSection\" },\n { label: \"Subsection\", node: \"itSub\" },\n { label: \"Summary\", node: \"itSummary\" },\n { label: \"Quote\", node: \"itQuote\" },\n] as const;\n\ntype InsertOption = {\n label: string;\n keyword: string;\n category: string;\n description: string;\n isReadOnly: boolean;\n};\ntype InsertGroup = { category: string; items: InsertOption[] };\n\nconst READ_ONLY_INSERT_KEYWORDS = new Set([\n \"history\",\n \"revision\",\n \"track\",\n \"freeze\",\n]);\nconst HIDDEN_INSERT_KEYWORDS = new Set([\n \"agent\",\n \"model\",\n \"meta\",\n \"context\",\n \"history\",\n]);\nconst CATEGORY_ORDER = [\n \"identity\",\n \"structure\",\n \"content\",\n \"data\",\n \"trust\",\n \"layout\",\n];\n\nconst FONT_FAMILIES = [\n { label: \"Default\", value: \"\" },\n { label: \"Inter\", value: \"Inter\" },\n { label: \"Arial\", value: \"Arial\" },\n { label: \"Times New Roman\", value: \"Times New Roman\" },\n { label: \"Georgia\", value: \"Georgia\" },\n { label: \"Courier New\", value: \"Courier New\" },\n { label: \"Verdana\", value: \"Verdana\" },\n { label: \"Trebuchet MS\", value: \"Trebuchet MS\" },\n] as const;\n\n// Word-style line spacing presets → core `leading:` (line-height).\nconst LINE_SPACINGS = [\"1\", \"1.15\", \"1.5\", \"2\", \"2.5\", \"3\"] as const;\n// One Word \"spacing step\" → core `space-before:` / `space-after:`.\nconst SPACE_STEP = \"12px\";\n\nconst TEXT_COLORS = [\n \"#000000\",\n \"#434343\",\n \"#666666\",\n \"#999999\",\n \"#b7b7b7\",\n \"#cccccc\",\n \"#d9d9d9\",\n \"#efefef\",\n \"#f3f3f3\",\n \"#ffffff\",\n \"#980000\",\n \"#ff0000\",\n \"#ff9900\",\n \"#ffff00\",\n \"#00ff00\",\n \"#00ffff\",\n \"#4a86e8\",\n \"#0000ff\",\n \"#9900ff\",\n \"#ff00ff\",\n \"#e6b8af\",\n \"#f4cccc\",\n \"#fce5cd\",\n \"#fff2cc\",\n \"#d9ead3\",\n \"#d0e0e3\",\n \"#c9daf8\",\n \"#cfe2f3\",\n \"#d9d2e9\",\n \"#ead1dc\",\n \"#dd7e6b\",\n \"#ea9999\",\n \"#f9cb9c\",\n \"#ffe599\",\n \"#b6d7a8\",\n \"#a2c4c9\",\n \"#a4c2f4\",\n \"#9fc5e8\",\n \"#b4a7d6\",\n \"#d5a6bd\",\n \"#cc4125\",\n \"#e06666\",\n \"#f6b26b\",\n \"#ffd966\",\n \"#93c47d\",\n \"#76a5af\",\n \"#6d9eeb\",\n \"#6fa8dc\",\n \"#8e7cc3\",\n \"#c27ba0\",\n];\n\nconst HIGHLIGHT_COLORS = [\n \"#ffffff\",\n \"#cfe2f3\",\n \"#d9ead3\",\n \"#fff2cc\",\n \"#fce5cd\",\n \"#f4cccc\",\n \"#d9d2e9\",\n \"#ead1dc\",\n \"#d0e0e3\",\n \"#e6b8af\",\n];\n\n/* ── Helper: small icon button ──────────────────────────────── */\nfunction Btn({\n onClick,\n active,\n disabled,\n title,\n children,\n}: {\n onClick: () => void;\n active?: boolean;\n disabled?: boolean;\n title: string;\n children: React.ReactNode;\n}) {\n return (\n <button\n className={`docs-tb-btn${active ? \" active\" : \"\"}`}\n onClick={onClick}\n disabled={disabled}\n title={title}\n >\n {children}\n </button>\n );\n}\n\n/** A ribbon group — one compact Docs-style row (the label is a11y-only). */\nfunction Group({\n label,\n children,\n className = \"\",\n}: {\n label: string;\n children: React.ReactNode;\n className?: string;\n}) {\n return (\n <div\n className={`ribbon-group ${className}`.trim()}\n role=\"group\"\n aria-label={label}\n >\n {children}\n </div>\n );\n}\n\nfunction GroupSep() {\n return <div className=\"ribbon-sep\" />;\n}\n\nexport function DocsToolbar({\n editor,\n isRtl = false,\n onToggleRtl,\n content,\n onChange,\n theme,\n onThemeChange,\n onTrustAction,\n trust,\n sealIntact = null,\n locked = false,\n}: Props) {\n const [styleOpen, setStyleOpen] = useState(false);\n const [insertOpen, setInsertOpen] = useState(false);\n const [fontOpen, setFontOpen] = useState(false);\n const [textColorOpen, setTextColorOpen] = useState(false);\n const [highlightColorOpen, setHighlightColorOpen] = useState(false);\n const [spacingOpen, setSpacingOpen] = useState(false);\n const [inkSaver, setInkSaver] = useState(false);\n\n const styleRef = useRef<HTMLDivElement>(null);\n const insertRef = useRef<HTMLDivElement>(null);\n const fontRef = useRef<HTMLDivElement>(null);\n const textColorRef = useRef<HTMLDivElement>(null);\n const highlightColorRef = useRef<HTMLDivElement>(null);\n const spacingRef = useRef<HTMLDivElement>(null);\n\n // Close all dropdowns on outside click\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n const t = e.target as Node;\n if (styleRef.current && !styleRef.current.contains(t))\n setStyleOpen(false);\n if (insertRef.current && !insertRef.current.contains(t))\n setInsertOpen(false);\n if (fontRef.current && !fontRef.current.contains(t)) setFontOpen(false);\n if (textColorRef.current && !textColorRef.current.contains(t))\n setTextColorOpen(false);\n if (highlightColorRef.current && !highlightColorRef.current.contains(t))\n setHighlightColorOpen(false);\n if (spacingRef.current && !spacingRef.current.contains(t))\n setSpacingOpen(false);\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, []);\n\n const closeAll = () => {\n setStyleOpen(false);\n setInsertOpen(false);\n setFontOpen(false);\n setTextColorOpen(false);\n setHighlightColorOpen(false);\n setSpacingOpen(false);\n };\n\n /* ── Queries ─────────────────────────────────────────────── */\n const getCurrentStyle = useCallback((): string => {\n if (!editor) return \"Normal text\";\n for (const opt of STYLE_OPTIONS) {\n if (opt.node === \"paragraph\" && editor.isActive(\"paragraph\")) {\n const isOther = STYLE_OPTIONS.some(\n (o) => o.node !== \"paragraph\" && editor.isActive(o.node),\n );\n if (!isOther) return opt.label;\n } else if (editor.isActive(opt.node)) {\n return opt.label;\n }\n }\n return \"Normal text\";\n }, [editor]);\n\n const getCurrentFont = useCallback((): string => {\n if (!editor) return \"Default\";\n const family = editor.getAttributes(\"textStyle\")?.fontFamily;\n if (!family) return \"Default\";\n const match = FONT_FAMILIES.find((f) => f.value === family);\n return match ? match.label : \"Default\";\n }, [editor]);\n\n const [fontSize, setFontSize] = useState(11);\n // Re-render on selection moves so active states (align, spacing, end) track the caret.\n const [, setSelTick] = useState(0);\n\n const insertGroups = useMemo<InsertGroup[]>(() => {\n const grouped = new Map<string, InsertOption[]>();\n\n for (const entry of LANGUAGE_REGISTRY) {\n if (entry.status !== \"stable\") continue;\n if (HIDDEN_INSERT_KEYWORDS.has(entry.canonical)) continue;\n if (entry.category === \"agent\") continue;\n\n const category = entry.category;\n const list = grouped.get(category) || [];\n list.push({\n label: entry.canonical,\n keyword: entry.canonical,\n category,\n description: entry.description,\n isReadOnly: READ_ONLY_INSERT_KEYWORDS.has(entry.canonical),\n });\n grouped.set(category, list);\n }\n\n const result: InsertGroup[] = [];\n for (const category of CATEGORY_ORDER) {\n const items = grouped.get(category);\n if (!items || items.length === 0) continue;\n items.sort((a, b) => a.keyword.localeCompare(b.keyword));\n result.push({\n category: CATEGORY_META[category]?.label || category,\n items,\n });\n }\n return result;\n }, []);\n\n // Sync font size + selection tick from editor selection\n useEffect(() => {\n if (!editor) return;\n const updateFontSize = () => {\n const attrs = editor.getAttributes(\"textStyle\");\n if (attrs?.fontSize) {\n const n = parseInt(attrs.fontSize, 10);\n if (!isNaN(n)) setFontSize(n);\n }\n setSelTick((t) => t + 1);\n };\n editor.on(\"selectionUpdate\", updateFontSize);\n editor.on(\"transaction\", updateFontSize);\n return () => {\n editor.off(\"selectionUpdate\", updateFontSize);\n editor.off(\"transaction\", updateFontSize);\n };\n }, [editor]);\n\n /* ── Actions ─────────────────────────────────────────────── */\n const setStyle = useCallback(\n (nodeType: string) => {\n if (!editor) return;\n if (nodeType === \"paragraph\") {\n editor.chain().focus().setParagraph().run();\n } else if (nodeType === \"itQuote\") {\n editor.chain().focus().setNode(\"itQuote\").run();\n } else {\n editor.chain().focus().setNode(nodeType).run();\n }\n closeAll();\n },\n [editor],\n );\n\n const insertBlock = useCallback(\n (keyword: string) => {\n if (!editor) return;\n const chain = editor.chain().focus();\n if (keyword === \"divider\") {\n chain.setNode(\"itDivider\").run();\n } else if (keyword === \"break\") {\n chain.setNode(\"itBreak\").run();\n } else if (keyword === \"code\") {\n chain.setNode(\"itCode\", { lang: \"\" }).run();\n } else if (\n [\"tip\", \"info\", \"warning\", \"danger\", \"success\"].includes(keyword)\n ) {\n chain.setNode(\"itCallout\", { variant: keyword }).run();\n } else {\n chain.setNode(\"itGenericBlock\", { keyword, properties: \"\" }).run();\n }\n closeAll();\n },\n [editor],\n );\n\n // Font size — selection-based; serializes to core `size:` (line-level when the\n // whole line is styled, an inline [text]{ size: … } span otherwise).\n const changeFontSize = useCallback(\n (delta: number) => {\n const next = Math.min(96, Math.max(8, fontSize + delta));\n setFontSize(next);\n editor?.chain().focus().setFontSize(`${next}pt`).run();\n },\n [editor, fontSize],\n );\n\n // Paragraph spacing — writes core `leading:` / `space-before:` / `space-after:`\n // onto every block in the selection (multi-block selections supported).\n const setLeading = useCallback(\n (v: string | null) => {\n editor?.chain().focus().setBlockProp(\"leading\", v).run();\n closeAll();\n },\n [editor],\n );\n\n const toggleSpace = useCallback(\n (key: \"space-before\" | \"space-after\") => {\n if (!editor) return;\n const cur = getBlockProp(editor, key);\n editor\n .chain()\n .focus()\n .setBlockProp(key, cur ? null : SPACE_STEP)\n .run();\n closeAll();\n },\n [editor],\n );\n\n const customSpacing = useCallback(() => {\n if (!editor) return;\n const before = window.prompt(\n \"Space before block (e.g. 12px, 1em — empty for none):\",\n getBlockProp(editor, \"space-before\") || \"\",\n );\n if (before === null) return;\n const after = window.prompt(\n \"Space after block (e.g. 12px, 1em — empty for none):\",\n getBlockProp(editor, \"space-after\") || \"\",\n );\n if (after === null) return;\n editor\n .chain()\n .focus()\n .setBlockProp(\"space-before\", before.trim() || null)\n .setBlockProp(\"space-after\", after.trim() || null)\n .run();\n closeAll();\n }, [editor]);\n\n // Two-sided row — writes the core `end:` property (`text: … | end: …`):\n // content at the line start, value at the line end (flex split, RTL-native).\n const editSplitEnd = useCallback(() => {\n if (!editor) return;\n const cur = getBlockProp(editor, \"end\");\n const next = window.prompt(\n \"Line-end text (shown at the end of the line — empty to remove):\",\n cur || \"\",\n );\n if (next === null) return;\n editor\n .chain()\n .focus()\n .setBlockProp(\"end\", next.trim() || null)\n .run();\n }, [editor]);\n\n const insertSplitRow = useCallback(() => {\n if (!editor) return;\n editor\n .chain()\n .focus()\n .insertContent({\n type: \"paragraph\",\n attrs: { end: \"End text\" },\n content: [{ type: \"text\", text: \"Start text\" }],\n })\n .run();\n closeAll();\n }, [editor]);\n\n /* ── Export (WYSIWYG print path) ─────────────────────────── */\n const themes = useMemo(() => builtinThemes(), []);\n const printMode = inkSaver ? \"minimal-ink\" : \"normal\";\n const doExportPDF = useCallback(\n () => exportDocumentPDF(content, theme, printMode),\n [content, theme, printMode],\n );\n const doSave = useCallback(() => downloadItFile(content), [content]);\n\n if (!editor) return null;\n\n const currentLeading = getBlockProp(editor, \"leading\");\n const hasEnd = !!getBlockProp(editor, \"end\");\n\n return (\n <div className=\"docs-toolbar docs-ribbon\">\n {/* ── Edit ─────────────────────────────────────────── */}\n <Group label=\"Edit\">\n <Btn\n onClick={() => editor.chain().focus().undo().run()}\n disabled={locked || !editor.can().undo()}\n title=\"Undo (⌘Z)\"\n >\n <Undo2 size={16} />\n </Btn>\n <Btn\n onClick={() => editor.chain().focus().redo().run()}\n disabled={locked || !editor.can().redo()}\n title=\"Redo (⌘⇧Z)\"\n >\n <Redo2 size={16} />\n </Btn>\n </Group>\n\n <GroupSep />\n\n {/* ── File / Export ────────────────────────────────── */}\n <Group label=\"File\">\n <Btn onClick={doSave} title=\"Save / Download the .it file\">\n <Download size={16} />\n <span className=\"ribbon-btn-text\">Save</span>\n </Btn>\n <Btn onClick={doExportPDF} title=\"Export PDF (⌘P) — WYSIWYG\">\n <Printer size={16} />\n <span className=\"ribbon-btn-text\">PDF</span>\n </Btn>\n <Btn\n onClick={() => setInkSaver((v) => !v)}\n active={inkSaver}\n title=\"Minimal ink mode (plain callouts when printing)\"\n >\n <Droplets size={16} />\n </Btn>\n <select\n className=\"ribbon-theme-select\"\n value={theme}\n onChange={(e) => onThemeChange(e.target.value)}\n title=\"Document theme (used everywhere — canvas, print, export)\"\n >\n {themes.map((t) => (\n <option key={t} value={t}>\n {t.charAt(0).toUpperCase() + t.slice(1)}\n </option>\n ))}\n </select>\n </Group>\n\n <GroupSep />\n\n <div className={locked ? \"ribbon-locked\" : \"ribbon-editing\"}>\n {/* ── Style (paragraph type) ───────────────────────── */}\n <Group label=\"Style\">\n {/* Block style (Title / Section / …) */}\n <div className=\"docs-tb-dropdown\" ref={styleRef}>\n <button\n className=\"docs-tb-select docs-tb-paragraph-select\"\n onClick={() => {\n closeAll();\n setStyleOpen(!styleOpen);\n }}\n >\n <span className=\"docs-tb-select-label\">{getCurrentStyle()}</span>\n <ChevronDown size={14} />\n </button>\n {styleOpen && (\n <div className=\"docs-tb-dropdown-menu docs-style-menu\">\n {STYLE_OPTIONS.map((opt) => (\n <button\n key={opt.node}\n className={`docs-tb-dropdown-item${getCurrentStyle() === opt.label ? \" active\" : \"\"}`}\n onClick={() => setStyle(opt.node)}\n >\n <span\n className={`docs-style-preview docs-style-${opt.node}`}\n >\n {opt.label}\n </span>\n </button>\n ))}\n </div>\n )}\n </div>\n </Group>\n\n <GroupSep />\n\n {/* ── Font (family + size) ─────────────────────────── */}\n <Group label=\"Font\">\n {/* Font family */}\n <div className=\"docs-tb-dropdown\" ref={fontRef}>\n <button\n className=\"docs-tb-select docs-tb-font-select\"\n onClick={() => {\n closeAll();\n setFontOpen(!fontOpen);\n }}\n >\n <span className=\"docs-tb-select-label\">{getCurrentFont()}</span>\n <ChevronDown size={14} />\n </button>\n {fontOpen && (\n <div className=\"docs-tb-dropdown-menu docs-font-menu\">\n {FONT_FAMILIES.map((f) => (\n <button\n key={f.value || \"default\"}\n className={`docs-tb-dropdown-item${getCurrentFont() === f.label ? \" active\" : \"\"}`}\n style={{ fontFamily: f.value || \"inherit\" }}\n onClick={() => {\n if (f.value) {\n editor.chain().focus().setFontFamily(f.value).run();\n } else {\n editor.chain().focus().unsetFontFamily().run();\n }\n closeAll();\n }}\n >\n {f.label}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Font size → core `size:` */}\n <Btn onClick={() => changeFontSize(-1)} title=\"Decrease font size\">\n <Minus size={14} />\n </Btn>\n <span className=\"docs-tb-fontsize\">{fontSize}</span>\n <Btn onClick={() => changeFontSize(1)} title=\"Increase font size\">\n <Plus size={14} />\n </Btn>\n </Group>\n\n <GroupSep />\n\n {/* ── Text (B I U S + color) ───────────────────────── */}\n <Group label=\"Text\">\n <Btn\n onClick={() => editor.chain().focus().toggleBold().run()}\n active={editor.isActive(\"bold\")}\n title=\"Bold (⌘B)\"\n >\n <Bold size={16} />\n </Btn>\n <Btn\n onClick={() => editor.chain().focus().toggleItalic().run()}\n active={editor.isActive(\"italic\")}\n title=\"Italic (⌘I)\"\n >\n <Italic size={16} />\n </Btn>\n <Btn\n onClick={() => editor.chain().focus().toggleUnderline().run()}\n active={editor.isActive(\"underline\")}\n title=\"Underline (⌘U)\"\n >\n <Underline size={16} />\n </Btn>\n <Btn\n onClick={() => editor.chain().focus().toggleStrike().run()}\n active={editor.isActive(\"strike\")}\n title=\"Strikethrough (⌘⇧X)\"\n >\n <Strikethrough size={16} />\n </Btn>\n\n {/* Text Color */}\n <div\n className=\"docs-tb-dropdown docs-tb-color-dropdown\"\n ref={textColorRef}\n >\n <button\n className=\"docs-tb-btn docs-tb-color-btn\"\n onClick={() => {\n closeAll();\n setTextColorOpen(!textColorOpen);\n }}\n title=\"Text color\"\n >\n <Palette size={16} />\n <span\n className=\"docs-tb-color-indicator\"\n style={{\n background:\n editor.getAttributes(\"textStyle\")?.color || \"#000000\",\n }}\n />\n </button>\n {textColorOpen && (\n <div className=\"docs-tb-dropdown-menu docs-color-grid-menu\">\n <div className=\"docs-color-grid-label\">Text color</div>\n <div className=\"docs-color-grid\">\n {TEXT_COLORS.map((c) => (\n <button\n key={c}\n className=\"docs-color-swatch\"\n style={{ background: c }}\n title={c}\n onClick={() => {\n editor.chain().focus().setColor(c).run();\n closeAll();\n }}\n />\n ))}\n </div>\n <button\n className=\"docs-tb-dropdown-item\"\n onClick={() => {\n editor.chain().focus().unsetColor().run();\n closeAll();\n }}\n >\n <RemoveFormatting size={14} /> Reset\n </button>\n </div>\n )}\n </div>\n\n {/* Highlight Color */}\n <div\n className=\"docs-tb-dropdown docs-tb-color-dropdown\"\n ref={highlightColorRef}\n >\n <button\n className=\"docs-tb-btn docs-tb-color-btn\"\n onClick={() => {\n closeAll();\n setHighlightColorOpen(!highlightColorOpen);\n }}\n title=\"Highlight color\"\n >\n <Highlighter size={16} />\n <span\n className=\"docs-tb-color-indicator\"\n style={{\n background:\n editor.getAttributes(\"highlight\")?.color || \"transparent\",\n }}\n />\n </button>\n {highlightColorOpen && (\n <div className=\"docs-tb-dropdown-menu docs-color-grid-menu\">\n <div className=\"docs-color-grid-label\">Highlight color</div>\n <div className=\"docs-color-grid docs-highlight-grid\">\n {HIGHLIGHT_COLORS.map((c) => (\n <button\n key={c}\n className=\"docs-color-swatch\"\n style={{ background: c }}\n title={c}\n onClick={() => {\n if (c === \"#ffffff\") {\n editor.chain().focus().unsetHighlight().run();\n } else {\n editor\n .chain()\n .focus()\n .toggleHighlight({ color: c })\n .run();\n }\n closeAll();\n }}\n />\n ))}\n </div>\n </div>\n )}\n </div>\n\n <Btn\n onClick={() => editor.chain().focus().toggleCode().run()}\n active={editor.isActive(\"code\")}\n title=\"Inline code\"\n >\n <Code size={16} />\n </Btn>\n <Btn\n onClick={() =>\n editor.chain().focus().unsetAllMarks().clearNodes().run()\n }\n title=\"Clear formatting\"\n >\n <RemoveFormatting size={16} />\n </Btn>\n </Group>\n\n <GroupSep />\n\n {/* ── Paragraph (align / direction / spacing / lists) ─ */}\n <Group label=\"Paragraph\">\n {/* Alignment → core `align:` */}\n <Btn\n onClick={() => editor.chain().focus().setTextAlign(\"left\").run()}\n active={editor.isActive({ textAlign: \"left\" })}\n title=\"Align left\"\n >\n <AlignLeft size={16} />\n </Btn>\n <Btn\n onClick={() => editor.chain().focus().setTextAlign(\"center\").run()}\n active={editor.isActive({ textAlign: \"center\" })}\n title=\"Align center\"\n >\n <AlignCenter size={16} />\n </Btn>\n <Btn\n onClick={() => editor.chain().focus().setTextAlign(\"right\").run()}\n active={editor.isActive({ textAlign: \"right\" })}\n title=\"Align right\"\n >\n <AlignRight size={16} />\n </Btn>\n <Btn\n onClick={() =>\n editor.chain().focus().setTextAlign(\"justify\").run()\n }\n active={editor.isActive({ textAlign: \"justify\" })}\n title=\"Justify\"\n >\n <AlignJustify size={16} />\n </Btn>\n <Btn\n onClick={() => onToggleRtl?.()}\n active={isRtl}\n title={\n isRtl\n ? \"Switch to LTR (left-to-right)\"\n : \"Switch to RTL (right-to-left)\"\n }\n >\n <span\n style={{\n fontSize: 11,\n fontWeight: 700,\n letterSpacing: -0.5,\n lineHeight: 1,\n }}\n >\n {isRtl ? \"LTR\" : \"RTL\"}\n </span>\n </Btn>\n\n {/* Line & paragraph spacing → core `leading:` / `space-before:` / `space-after:` */}\n <div className=\"docs-tb-dropdown\" ref={spacingRef}>\n <button\n className={`docs-tb-btn${currentLeading ? \" active\" : \"\"}`}\n onClick={() => {\n closeAll();\n setSpacingOpen(!spacingOpen);\n }}\n title=\"Line & paragraph spacing\"\n >\n <Rows3 size={16} />\n <ChevronDown size={12} />\n </button>\n {spacingOpen && (\n <div className=\"docs-tb-dropdown-menu docs-spacing-menu\">\n <div className=\"docs-insert-category\">Line spacing</div>\n <button\n className={`docs-tb-dropdown-item${!currentLeading ? \" active\" : \"\"}`}\n onClick={() => setLeading(null)}\n >\n Default\n </button>\n {LINE_SPACINGS.map((v) => (\n <button\n key={v}\n className={`docs-tb-dropdown-item${currentLeading === v ? \" active\" : \"\"}`}\n onClick={() => setLeading(v)}\n >\n {v === \"1\" ? \"Single\" : v === \"2\" ? \"Double\" : v}\n </button>\n ))}\n <div className=\"docs-insert-divider\" />\n <div className=\"docs-insert-category\">Paragraph spacing</div>\n <button\n className=\"docs-tb-dropdown-item\"\n onClick={() => toggleSpace(\"space-before\")}\n >\n {getBlockProp(editor, \"space-before\")\n ? \"Remove space before block\"\n : \"Add space before block\"}\n </button>\n <button\n className=\"docs-tb-dropdown-item\"\n onClick={() => toggleSpace(\"space-after\")}\n >\n {getBlockProp(editor, \"space-after\")\n ? \"Remove space after block\"\n : \"Add space after block\"}\n </button>\n <button\n className=\"docs-tb-dropdown-item\"\n onClick={customSpacing}\n >\n Custom spacing…\n </button>\n </div>\n )}\n </div>\n\n <Btn\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n active={editor.isActive(\"bulletList\")}\n title=\"Bullet list\"\n >\n <List size={16} />\n </Btn>\n <Btn\n onClick={() => editor.chain().focus().toggleOrderedList().run()}\n active={editor.isActive(\"orderedList\")}\n title=\"Numbered list\"\n >\n <ListOrdered size={16} />\n </Btn>\n </Group>\n\n <GroupSep />\n\n {/* ── Insert ───────────────────────────────────────── */}\n <Group label=\"Insert\">\n <div className=\"docs-tb-dropdown\" ref={insertRef}>\n <button\n className=\"docs-tb-select docs-tb-insert-select\"\n onClick={() => {\n closeAll();\n setInsertOpen(!insertOpen);\n }}\n >\n <Plus size={15} />\n <span>Insert</span>\n <ChevronDown size={14} />\n </button>\n {insertOpen && (\n <div className=\"docs-tb-dropdown-menu docs-insert-menu\">\n <button\n className=\"docs-tb-dropdown-item docs-insert-item\"\n onClick={insertSplitRow}\n title=\"Two-sided row — content at the line start, value at the line end (text: … | end: …)\"\n >\n <span className=\"docs-insert-icon\">\n <AlignHorizontalSpaceBetween size={13} />\n </span>\n <span className=\"docs-insert-label\">two-sided row</span>\n <span className=\"docs-insert-kw\">end:</span>\n </button>\n <div className=\"docs-insert-divider\" />\n {insertGroups.map((group, gi) => (\n <div key={group.category}>\n {gi > 0 && <div className=\"docs-insert-divider\" />}\n <div className=\"docs-insert-category\">{group.category}</div>\n {group.items.map((opt) => (\n <button\n key={opt.keyword}\n className=\"docs-tb-dropdown-item docs-insert-item\"\n onClick={() => insertBlock(opt.keyword)}\n disabled={opt.isReadOnly}\n title={opt.description}\n >\n <span className=\"docs-insert-icon\">\n {CATEGORY_META[opt.category]?.icon || \"•\"}\n </span>\n <span className=\"docs-insert-label\">{opt.label}</span>\n <span className=\"docs-insert-kw\">\n {opt.isReadOnly ? \"locked\" : `.${opt.keyword}`}\n </span>\n </button>\n ))}\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Two-sided row → core `end:` */}\n <Btn\n onClick={editSplitEnd}\n active={hasEnd}\n title=\"Two-sided row — set the text shown at the END of this line (end: property)\"\n >\n <AlignHorizontalSpaceBetween size={16} />\n </Btn>\n </Group>\n </div>\n\n {/* ── Trust ────────────────────────────────────────── */}\n {trust && onChange ? (\n <>\n <GroupSep />\n <Group label=\"Trust\">\n <TrustControl\n content={content}\n onChange={onChange}\n trust={trust}\n intact={sealIntact}\n />\n </Group>\n </>\n ) : (\n onTrustAction && (\n <>\n <GroupSep />\n <Group label=\"Trust\">\n <Btn\n onClick={() => onTrustAction(\"seal\")}\n disabled={locked}\n title=\"Seal — freeze the document with a tamper-evident hash\"\n >\n <span className=\"ribbon-btn-text\">Seal</span>\n </Btn>\n <Btn onClick={() => onTrustAction(\"sign\")} title=\"Sign\">\n <span className=\"ribbon-btn-text\">Sign</span>\n </Btn>\n <Btn onClick={() => onTrustAction(\"verify\")} title=\"Verify\">\n <span className=\"ribbon-btn-text\">Verify</span>\n </Btn>\n </Group>\n </>\n )\n )}\n </div>\n );\n}\n","// Rulers — the Google-Docs strips above and to the left of the page.\n//\n// Horizontal ruler: shows the page width, ticks in the paper's natural unit\n// (A-series → cm, US sizes → in), and DRAGGABLE margin stops on the left and\n// right. Dragging a stop rewrites the document's `page:` margins (via\n// onMargins), so the shaded zones, the on-screen text column, and the printed\n// PDF all move together.\n//\n// Vertical ruler: the same idea down the left side — top & bottom margin stops.\n//\n// All px come from page-geometry.ts so the rulers are EXACTLY as long as the\n// page sheet and the stops sit exactly on the print margins. Both track zoom\n// and the canvas scroll so ticks stay glued to the sheet.\n\nimport { useEffect, useState, useMemo, useRef, useCallback } from \"react\";\nimport type { PageGeometry } from \"./page-geometry\";\n\ninterface RulerProps {\n geometry: PageGeometry;\n zoom: number;\n /** The scrollable canvas element — the ruler mirrors its scroll. */\n scrollEl: React.RefObject<HTMLDivElement | null>;\n /** Apply new margins (px) when a stop is dragged. Omit → read-only ruler. */\n onMargins?: (next: {\n top?: number;\n right?: number;\n bottom?: number;\n left?: number;\n }) => void;\n /** Disable dragging (e.g. sealed document). */\n locked?: boolean;\n}\n\ninterface Tick {\n x: number;\n kind: \"minor\" | \"major\";\n label?: string;\n}\n\n/** px per ruler unit at zoom 1 (96dpi: 1in = 96px, 1cm = 96/2.54 px). */\nconst UNIT_PX = { in: 96, cm: 96 / 2.54 } as const;\n/** Minor tick step in units (Docs: quarter-inch / half-centimetre). */\nconst MINOR_STEP = { in: 0.25, cm: 0.5 } as const;\n\nfunction buildTicks(length: number, unit: \"cm\" | \"in\"): Tick[] {\n const unitPx = UNIT_PX[unit];\n const step = MINOR_STEP[unit];\n const out: Tick[] = [];\n const units = length / unitPx;\n for (let u = 0; u <= units + 1e-6; u += step) {\n const isMajor = Math.abs(u - Math.round(u)) < 1e-6;\n out.push({\n x: u * unitPx,\n kind: isMajor ? \"major\" : \"minor\",\n label: isMajor && u > 0 ? String(Math.round(u)) : undefined,\n });\n }\n return out;\n}\n\n/* ── Horizontal ruler ──────────────────────────────────────────── */\n\nexport function DocsRuler({\n geometry,\n zoom,\n scrollEl,\n onMargins,\n locked = false,\n}: RulerProps) {\n const [scrollLeft, setScrollLeft] = useState(0);\n const [drag, setDrag] = useState<null | \"left\" | \"right\">(null);\n const trackRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const el = scrollEl.current;\n if (!el) return;\n const onScroll = () => setScrollLeft(el.scrollLeft);\n onScroll();\n el.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => el.removeEventListener(\"scroll\", onScroll);\n }, [scrollEl]);\n\n const ticks = useMemo(\n () => buildTicks(geometry.width, geometry.unit),\n [geometry.width, geometry.unit],\n );\n\n const onPointerDown = useCallback(\n (side: \"left\" | \"right\") => (e: React.PointerEvent) => {\n if (!onMargins || locked) return;\n e.preventDefault();\n setDrag(side);\n },\n [onMargins, locked],\n );\n\n useEffect(() => {\n if (!drag || !onMargins) return;\n const onMove = (e: PointerEvent) => {\n const track = trackRef.current;\n if (!track) return;\n const rect = track.getBoundingClientRect();\n const pageX = (e.clientX - rect.left) / zoom; // → page px\n if (drag === \"left\") {\n const left = Math.max(0, Math.min(pageX, geometry.width / 2));\n onMargins({ left });\n } else {\n const right = Math.max(0, Math.min(geometry.width - pageX, geometry.width / 2));\n onMargins({ right });\n }\n };\n const onUp = () => setDrag(null);\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n return () => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n };\n }, [drag, onMargins, zoom, geometry.width]);\n\n const w = geometry.width * zoom;\n const draggable = !!onMargins && !locked;\n\n return (\n <div className={`docs-ruler${draggable ? \" docs-ruler--draggable\" : \"\"}`}>\n <div\n ref={trackRef}\n className=\"docs-ruler-track\"\n style={{ width: w, transform: `translateX(${-scrollLeft}px)` }}\n >\n <div\n className=\"docs-ruler-margin\"\n style={{ left: 0, width: geometry.marginLeft * zoom }}\n />\n <div\n className=\"docs-ruler-margin\"\n style={{ right: 0, width: geometry.marginRight * zoom }}\n />\n {ticks.map((t, i) =>\n t.label ? (\n <span key={i} className=\"docs-ruler-num\" style={{ left: t.x * zoom }}>\n {t.label}\n </span>\n ) : (\n <span\n key={i}\n className={`docs-ruler-tick docs-ruler-tick--${t.kind}`}\n style={{ left: t.x * zoom }}\n />\n ),\n )}\n {draggable && (\n <>\n <span\n className={`docs-ruler-stop docs-ruler-stop--h${drag === \"left\" ? \" dragging\" : \"\"}`}\n style={{ left: geometry.marginLeft * zoom }}\n onPointerDown={onPointerDown(\"left\")}\n title=\"Drag to set the left margin\"\n />\n <span\n className={`docs-ruler-stop docs-ruler-stop--h${drag === \"right\" ? \" dragging\" : \"\"}`}\n style={{ left: (geometry.width - geometry.marginRight) * zoom }}\n onPointerDown={onPointerDown(\"right\")}\n title=\"Drag to set the right margin\"\n />\n </>\n )}\n </div>\n </div>\n );\n}\n\n/* ── Vertical ruler (left side) ────────────────────────────────── */\n\nexport function DocsVerticalRuler({\n geometry,\n zoom,\n scrollEl,\n onMargins,\n locked = false,\n /** Extra px between the top of the scroll area and the page sheet top. */\n topOffset = 0,\n}: RulerProps & { topOffset?: number }) {\n const [scrollTop, setScrollTop] = useState(0);\n const [drag, setDrag] = useState<null | \"top\" | \"bottom\">(null);\n const trackRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const el = scrollEl.current;\n if (!el) return;\n const onScroll = () => setScrollTop(el.scrollTop);\n onScroll();\n el.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => el.removeEventListener(\"scroll\", onScroll);\n }, [scrollEl]);\n\n // Auto-height pages (receipts) have no fixed sheet height → no vertical stops.\n const pageH = geometry.autoHeight ? geometry.width * 1.414 : geometry.height;\n const ticks = useMemo(\n () => buildTicks(pageH, geometry.unit),\n [pageH, geometry.unit],\n );\n\n const onPointerDown = useCallback(\n (side: \"top\" | \"bottom\") => (e: React.PointerEvent) => {\n if (!onMargins || locked || geometry.autoHeight) return;\n e.preventDefault();\n setDrag(side);\n },\n [onMargins, locked, geometry.autoHeight],\n );\n\n useEffect(() => {\n if (!drag || !onMargins) return;\n const onMove = (e: PointerEvent) => {\n const track = trackRef.current;\n if (!track) return;\n const rect = track.getBoundingClientRect();\n const pageY = (e.clientY - rect.left) / zoom;\n if (drag === \"top\") {\n const top = Math.max(0, Math.min(pageY, pageH / 2));\n onMargins({ top });\n } else {\n const bottom = Math.max(0, Math.min(pageH - pageY, pageH / 2));\n onMargins({ bottom });\n }\n };\n const onUp = () => setDrag(null);\n window.addEventListener(\"pointermove\", onMove);\n window.addEventListener(\"pointerup\", onUp);\n return () => {\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n };\n }, [drag, onMargins, zoom, pageH]);\n\n const h = pageH * zoom;\n const draggable = !!onMargins && !locked && !geometry.autoHeight;\n\n return (\n <div className=\"docs-ruler-v\">\n <div\n ref={trackRef}\n className=\"docs-ruler-v-track\"\n style={{ height: h, transform: `translateY(${topOffset - scrollTop}px)` }}\n >\n <div\n className=\"docs-ruler-margin docs-ruler-margin--v\"\n style={{ top: 0, height: geometry.marginTop * zoom }}\n />\n <div\n className=\"docs-ruler-margin docs-ruler-margin--v\"\n style={{ bottom: 0, height: geometry.marginBottom * zoom }}\n />\n {ticks.map((t, i) =>\n t.label ? (\n <span key={i} className=\"docs-ruler-num docs-ruler-num--v\" style={{ top: t.x * zoom }}>\n {t.label}\n </span>\n ) : (\n <span\n key={i}\n className={`docs-ruler-tick docs-ruler-tick--v docs-ruler-tick--${t.kind}`}\n style={{ top: t.x * zoom }}\n />\n ),\n )}\n {draggable && (\n <>\n <span\n className={`docs-ruler-stop docs-ruler-stop--v${drag === \"top\" ? \" dragging\" : \"\"}`}\n style={{ top: geometry.marginTop * zoom }}\n onPointerDown={onPointerDown(\"top\")}\n title=\"Drag to set the top margin\"\n />\n <span\n className={`docs-ruler-stop docs-ruler-stop--v${drag === \"bottom\" ? \" dragging\" : \"\"}`}\n style={{ top: (pageH - geometry.marginBottom) * zoom }}\n onPointerDown={onPointerDown(\"bottom\")}\n title=\"Drag to set the bottom margin\"\n />\n </>\n )}\n </div>\n </div>\n );\n}\n","// Document status chrome for the visual editor:\n//\n// - TrustBanner: a professional document-status bar derived from the trust\n// blocks (seal/sign/approve/freeze) — \"🔒 Sealed — signed by Ahmed (CEO) on\n// 2026-06-12 · hash verified ✓\" instead of raw chips. Sealed documents are\n// read-only (VisualEditor flips editable off); the banner says so.\n// - DocPropsBar: a tidy, collapsible header strip for document-level metadata\n// (meta: id/version/owner…, page:, font:, header:, footer:, watermark:),\n// which is otherwise invisible in the page.\n\nimport { useMemo, useState } from \"react\";\nimport { parseIntentText } from \"@dotit/core\";\nimport type { TrustState } from \"./trust-state\";\n\n/* ── Trust status banner ─────────────────────────────────────── */\n\ninterface TrustBannerProps {\n trust: TrustState;\n /** verifyDocument().intact — null when the document is not sealed. */\n intact: boolean | null;\n}\n\nfunction who(by: string, role?: string): string {\n return role ? `${by} (${role})` : by;\n}\n\nexport function TrustBanner({ trust, intact }: TrustBannerProps) {\n if (trust.isSealed) {\n const signer = trust.sealedBy || \"unknown\";\n const role = trust.signatures[trust.signatures.length - 1]?.role;\n return (\n <div className=\"docs-trust-banner docs-trust-banner--sealed\" role=\"status\">\n <span className=\"docs-trust-banner__icon\">🔒</span>\n <span className=\"docs-trust-banner__title\">Sealed</span>\n <span className=\"docs-trust-banner__text\">\n signed by {who(signer, role)}\n {trust.sealedAt ? ` on ${trust.sealedAt}` : \"\"} · read-only\n </span>\n {intact === true && (\n <span className=\"docs-trust-banner__verify docs-trust-banner__verify--ok\">\n hash verified ✓\n </span>\n )}\n {intact === false && (\n <span className=\"docs-trust-banner__verify docs-trust-banner__verify--bad\">\n ⚠ hash mismatch — content changed after sealing\n </span>\n )}\n </div>\n );\n }\n\n if (trust.signatures.length > 0) {\n return (\n <div className=\"docs-trust-banner docs-trust-banner--signed\" role=\"status\">\n <span className=\"docs-trust-banner__icon\">✍</span>\n <span className=\"docs-trust-banner__title\">Signed</span>\n <span className=\"docs-trust-banner__text\">\n by{\" \"}\n {trust.signatures\n .map((s) => `${who(s.by, s.role)}${s.at ? ` on ${s.at}` : \"\"}`)\n .join(\" · \")}\n </span>\n </div>\n );\n }\n\n if (trust.approvals.length > 0) {\n return (\n <div\n className=\"docs-trust-banner docs-trust-banner--approved\"\n role=\"status\"\n >\n <span className=\"docs-trust-banner__icon\">✓</span>\n <span className=\"docs-trust-banner__title\">Approved</span>\n <span className=\"docs-trust-banner__text\">\n by{\" \"}\n {trust.approvals\n .map((a) => `${who(a.by, a.role)}${a.at ? ` on ${a.at}` : \"\"}`)\n .join(\" · \")}\n </span>\n </div>\n );\n }\n\n return null;\n}\n\n/* ── Document properties strip ───────────────────────────────── */\n\ninterface DocProp {\n key: string;\n value: string;\n}\n\nfunction collectDocProps(source: string): DocProp[] {\n let doc;\n try {\n doc = parseIntentText(source);\n } catch {\n return [];\n }\n const props: DocProp[] = [];\n const push = (key: string, value: unknown) => {\n const v = value == null ? \"\" : String(value).trim();\n if (v) props.push({ key, value: v });\n };\n\n for (const block of doc.blocks) {\n switch (block.type) {\n case \"meta\":\n // meta: | id: INV-001 | version: 2 | owner: Ahmed | …\n for (const [k, v] of Object.entries(block.properties || {})) push(k, v);\n break;\n case \"track\":\n push(\"tracked\", block.properties?.id ?? block.content);\n break;\n case \"page\": {\n const orientation = block.properties?.orientation;\n push(\n \"page\",\n [block.content, orientation].filter(Boolean).join(\" · \"),\n );\n break;\n }\n case \"font\":\n push(\n \"font\",\n [\n block.content || block.properties?.family,\n block.properties?.size,\n ]\n .filter(Boolean)\n .join(\" · \"),\n );\n break;\n case \"header\":\n push(\"header\", block.content);\n break;\n case \"footer\":\n push(\"footer\", block.content);\n break;\n case \"watermark\":\n push(\"watermark\", block.content);\n break;\n }\n }\n return props;\n}\n\nexport function DocPropsBar({ source }: { source: string }) {\n const [open, setOpen] = useState(false);\n const props = useMemo(() => collectDocProps(source), [source]);\n\n if (props.length === 0) return null;\n\n // Collapsed: a one-line summary of the leading properties.\n const summary = props\n .slice(0, 4)\n .map((p) => `${p.key}: ${p.value}`)\n .join(\" · \");\n\n return (\n <div className={`docs-props-bar${open ? \" open\" : \"\"}`}>\n <button\n className=\"docs-props-toggle\"\n onClick={() => setOpen((o) => !o)}\n title={open ? \"Hide document properties\" : \"Show document properties\"}\n >\n <span className=\"docs-props-caret\">{open ? \"▾\" : \"▸\"}</span>\n Document properties\n {!open && <span className=\"docs-props-summary\">{summary}</span>}\n </button>\n {open && (\n <div className=\"docs-props-chips\">\n {props.map((p, i) => (\n <span className=\"docs-props-chip\" key={`${p.key}-${i}`}>\n <b>{p.key}</b> {p.value}\n </span>\n ))}\n </div>\n )}\n </div>\n );\n}\n","// Trust state extraction — reads the document's trust blocks (track/approve/\n// sign/freeze/amendment) into a structured lifecycle snapshot. Pure function\n// over the parsed document; the TrustBanner and the sealed read-only behavior\n// are driven from this.\n\nimport type { IntentDocument } from \"@dotit/core\";\n\nexport interface TrustState {\n lifecycle: \"draft\" | \"tracked\" | \"approved\" | \"signed\" | \"sealed\";\n isTracked: boolean;\n trackBlock: { id: string; by: string; at: string } | null;\n approvals: { by: string; role: string; at: string; note?: string }[];\n signatures: { by: string; role: string; at: string }[];\n isSealed: boolean;\n sealedBy: string | null;\n sealedAt: string | null;\n sealHash: string | null;\n amendments: {\n section: string;\n was: string;\n now: string;\n by: string;\n ref: string;\n at: string;\n }[];\n}\n\nfunction prop(\n block: { properties?: Record<string, string | number> } | null,\n key: string,\n fallback = \"\",\n): string {\n const v = block?.properties?.[key];\n return v != null ? String(v) : fallback;\n}\n\nexport function extractTrustState(doc: IntentDocument | null): TrustState {\n const base: TrustState = {\n lifecycle: \"draft\",\n isTracked: false,\n trackBlock: null,\n approvals: [],\n signatures: [],\n isSealed: false,\n sealedBy: null,\n sealedAt: null,\n sealHash: null,\n amendments: [],\n };\n\n if (!doc) return base;\n\n const blocks = doc.blocks;\n\n // Track\n const track = blocks.find((b) => b.type === \"track\");\n if (track) {\n base.isTracked = true;\n base.lifecycle = \"tracked\";\n base.trackBlock = {\n id: prop(track, \"id\", track.content ?? \"\"),\n by: prop(track, \"by\"),\n at: prop(track, \"at\"),\n };\n }\n\n // Approvals\n const approveBlocks = blocks.filter((b) => b.type === \"approve\");\n for (const a of approveBlocks) {\n base.approvals.push({\n by: prop(a, \"by\", a.content ?? \"\"),\n role: prop(a, \"role\"),\n at: prop(a, \"at\"),\n note: prop(a, \"note\") || undefined,\n });\n }\n if (base.approvals.length > 0) base.lifecycle = \"approved\";\n\n // Signatures\n const signBlocks = blocks.filter((b) => b.type === \"sign\");\n for (const s of signBlocks) {\n base.signatures.push({\n by: prop(s, \"by\", s.content ?? \"\"),\n role: prop(s, \"role\"),\n at: prop(s, \"at\"),\n });\n }\n if (base.signatures.length > 0) base.lifecycle = \"signed\";\n\n // Sealed\n const freeze = blocks.find((b) => b.type === \"freeze\");\n if (freeze) {\n base.isSealed = true;\n base.lifecycle = \"sealed\";\n // The sealer's identity lives on the sign: block added during sealing — the\n // freeze: block carries only at/hash/status. Fall back to any freeze content.\n const lastSig = base.signatures[base.signatures.length - 1];\n base.sealedBy = lastSig?.by || prop(freeze, \"by\", freeze.content ?? \"\");\n base.sealedAt = prop(freeze, \"at\") || lastSig?.at || \"\";\n base.sealHash = prop(freeze, \"hash\");\n }\n\n // Amendments\n const amendBlocks = blocks.filter((b) => b.type === \"amendment\");\n for (const am of amendBlocks) {\n base.amendments.push({\n section: prop(am, \"section\", am.content ?? \"\"),\n was: prop(am, \"was\"),\n now: prop(am, \"now\"),\n by: prop(am, \"by\"),\n ref: prop(am, \"ref\"),\n at: prop(am, \"at\"),\n });\n }\n\n return base;\n}\n","// Template placeholder highlighting for the visual editor.\n//\n// Decorates every `{{path.to.value}}` in text content as an inline chip, so\n// template authors SEE their variables at a glance. Pure view decoration —\n// the document text is untouched, so round-trip and merge are unaffected.\n\nimport { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport type { Node as PMNode } from \"@tiptap/pm/model\";\n\nconst key = new PluginKey(\"template-highlight\");\nconst VAR_RE = /\\{\\{[^}]+\\}\\}/g;\n\nfunction buildDecorations(doc: PMNode): DecorationSet {\n const decos: Decoration[] = [];\n doc.descendants((node, pos) => {\n if (!node.isText || !node.text) return;\n VAR_RE.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = VAR_RE.exec(node.text))) {\n decos.push(\n Decoration.inline(pos + m.index, pos + m.index + m[0].length, {\n class: \"it-doc-var\",\n }),\n );\n }\n });\n return DecorationSet.create(doc, decos);\n}\n\nexport const TemplateHighlight = Extension.create({\n name: \"templateHighlight\",\n\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key,\n state: {\n init: (_cfg, state) => buildDecorations(state.doc),\n apply: (tr, old) =>\n tr.docChanged ? buildDecorations(tr.doc) : old,\n },\n props: {\n decorations(state) {\n return key.getState(state);\n },\n },\n }),\n ];\n },\n});\n\n/**\n * Extract the template variables used in `.it` source — unique, in order of\n * first appearance. Runtime print tokens ({{page}}/{{pages}}) and system\n * variables are excluded; they resolve at print/merge time on their own.\n */\nexport function extractTemplateVariables(source: string): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n VAR_RE.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = VAR_RE.exec(source))) {\n const name = m[0].slice(2, -2).trim();\n if (/^(page|pages|date|time|year)$/i.test(name)) continue;\n if (!seen.has(name)) {\n seen.add(name);\n out.push(name);\n }\n }\n return out;\n}\n\n/**\n * Build a sample-data skeleton for a set of variable paths:\n * [\"customer.name\", \"items.0.qty\"] → { customer: { name: \"\" }, items: [{ qty: \"\" }] }\n */\nexport function buildSampleSkeleton(vars: string[]): Record<string, unknown> {\n const root: Record<string, unknown> = {};\n for (const path of vars) {\n const parts = path.split(\".\");\n let cur: Record<string, unknown> = root;\n for (let i = 0; i < parts.length; i++) {\n const p = parts[i];\n const last = i === parts.length - 1;\n // `each:` loop variables bind as item.* — represent as a one-element array\n // under a plural-ish key the author can rename.\n if (last) {\n if (!(p in cur)) cur[p] = \"\";\n } else {\n if (!(p in cur) || typeof cur[p] !== \"object\" || cur[p] === null)\n cur[p] = {};\n cur = cur[p] as Record<string, unknown>;\n }\n }\n }\n return root;\n}\n","// Home / End keymap — move the caret to the start / end of the visual line.\n//\n// ProseMirror has no built-in Home/End that respects soft-wrapped (visual)\n// lines, so the default keys did nothing useful here. We resolve the caret's\n// current client rect, then walk left/right to the document position whose rect\n// sits at the same vertical band but the far horizontal edge — i.e. the visual\n// line boundary. Works for both LTR and RTL because we test geometry, not\n// logical order: \"line start\" = leftmost in LTR, rightmost in RTL.\n\nimport { Extension } from \"@tiptap/core\";\nimport { TextSelection } from \"@tiptap/pm/state\";\nimport type { EditorView } from \"@tiptap/pm/view\";\n\n/** Find the doc position at the visual start/end of the line containing `from`. */\nfunction visualLineEdge(\n view: EditorView,\n from: number,\n edge: \"start\" | \"end\",\n): number | null {\n const coords = view.coordsAtPos(from);\n // A vertical band tolerance so we stay on the same wrapped line.\n const bandTop = coords.top + 1;\n const bandBottom = coords.bottom - 1;\n const dir = edge === \"start\" ? -1 : 1;\n\n let pos = from;\n let last = from;\n // Walk one character at a time while we remain on the same visual line.\n for (let i = 0; i < 100000; i++) {\n const next = pos + dir;\n if (next < 0 || next > view.state.doc.content.size) break;\n let c;\n try {\n c = view.coordsAtPos(next);\n } catch {\n break;\n }\n // Left the vertical band → we crossed into the previous/next visual line.\n if (c.bottom <= bandTop || c.top >= bandBottom) break;\n pos = next;\n last = next;\n }\n return last;\n}\n\nexport const LineKeymap = Extension.create({\n name: \"lineKeymap\",\n\n addKeyboardShortcuts() {\n const moveToEdge = (edge: \"start\" | \"end\", extend: boolean) => {\n const { view } = this.editor;\n const { state } = view;\n const { selection } = state;\n const head = selection.head;\n const target = visualLineEdge(view, head, edge);\n if (target == null || target === head) {\n // Fall back to textblock start/end so the key is never a no-op.\n return false;\n }\n const $target = state.doc.resolve(target);\n const anchor = extend ? selection.anchor : target;\n const tr = state.tr.setSelection(\n extend\n ? TextSelection.between(state.doc.resolve(anchor), $target)\n : TextSelection.near($target),\n );\n view.dispatch(tr.scrollIntoView());\n return true;\n };\n\n return {\n Home: () => moveToEdge(\"start\", false),\n End: () => moveToEdge(\"end\", false),\n \"Shift-Home\": () => moveToEdge(\"start\", true),\n \"Shift-End\": () => moveToEdge(\"end\", true),\n };\n },\n});\n","import {\n useRef,\n useEffect,\n useLayoutEffect,\n useCallback,\n useState,\n useMemo,\n} from \"react\";\nimport { useEditor, EditorContent } from \"@tiptap/react\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport Underline from \"@tiptap/extension-underline\";\nimport { TextStyle } from \"@tiptap/extension-text-style\";\nimport Color from \"@tiptap/extension-color\";\nimport Highlight from \"@tiptap/extension-highlight\";\nimport TextAlign from \"@tiptap/extension-text-align\";\nimport FontFamily from \"@tiptap/extension-font-family\";\nimport Subscript from \"@tiptap/extension-subscript\";\nimport Superscript from \"@tiptap/extension-superscript\";\nimport { FontSize } from \"./font-size\";\nimport { Pagination } from \"./pagination\";\nimport { sourceToDoc, docToSource, detectUnsupportedStyling } from \"./bridge\";\nimport {\n ITTitle,\n ITSummary,\n ITSection,\n ITSub,\n ITCallout,\n ITQuote,\n ITCode,\n ITDivider,\n ITTable,\n ITMeta,\n ITTrust,\n ITMetric,\n ITStyleRule,\n ITBreak,\n ITGenericBlock,\n ITComment,\n} from \"./extensions\";\nimport { ITParagraph, BlockProps } from \"./block-props\";\nimport { DocsToolbar } from \"./DocsToolbar\";\nimport { DocsRuler, DocsVerticalRuler } from \"./Ruler\";\nimport { TrustBanner, DocPropsBar } from \"./TrustBanner\";\nimport { extractTrustState } from \"./trust-state\";\nimport {\n getBuiltinTheme,\n generateThemeCSS,\n parseIntentText,\n documentStyleCSS,\n verifyDocument,\n upsertMetaProperty,\n} from \"@dotit/core\";\nimport {\n getPageGeometry,\n resolvePageTokens,\n setPageMargin,\n MM,\n type PageGeometry,\n} from \"./page-geometry\";\nimport { TemplateHighlight } from \"./template-highlight\";\nimport { LineKeymap } from \"./line-keymap\";\nimport { exportDocumentPDF } from \"./print\";\nimport type { TrustAction } from \"./types\";\n\n/** Grey gap between page cards on the canvas (px). */\nconst PAGE_GAP = 28;\n\n// Where each `style:` target lives in the EDITOR's markup (.it-doc-* classes).\n// documentStyleCSS() does the collection/sanitization — same engine as core's\n// print path — so a rule means exactly the same thing on canvas and on paper.\nconst EDITOR_STYLE_SELECTORS: Record<string, string[]> = {\n title: [\".it-doc-title\"],\n summary: [\".it-doc-summary\"],\n section: [\".it-doc-section\"],\n sub: [\".it-doc-sub\"],\n text: [\"p\"],\n quote: [\".it-doc-quote\"],\n callout: [\".it-doc-callout\"],\n info: [\".it-doc-callout\"],\n table: [\".it-doc-table th\", \".it-doc-table td\"],\n \"table-header\": [\".it-doc-table th\"],\n metric: [\".it-doc-metric\"],\n contact: ['.it-doc-generic[data-keyword=\"contact\"]'],\n divider: [\".it-doc-divider\"],\n};\n\ninterface Props {\n value: string;\n onChange: (source: string) => void;\n theme: string;\n onThemeChange: (theme: string) => void;\n /** Force read-only (sealed documents are read-only regardless). */\n readOnly?: boolean;\n /** Show the formatting ribbon. Default true. */\n showRibbon?: boolean;\n /** Show the trust status banner + document properties strip. Default true. */\n showTrustBanner?: boolean;\n /** Ribbon Trust group (Seal / Sign / Verify). Group is hidden when omitted. */\n onTrustAction?: (action: TrustAction) => void;\n}\n\nexport function VisualEditor({\n value,\n onChange,\n theme,\n onThemeChange,\n readOnly = false,\n showRibbon = true,\n showTrustBanner = true,\n onTrustAction,\n}: Props) {\n const lastSourceRef = useRef<string>(\"\");\n const isInternalUpdate = useRef(false);\n const isHydrating = useRef(true);\n // Styling that can't be saved to .it / won't print through core (regression guard).\n const [unsupported, setUnsupported] = useState<string[]>([]);\n // Live page geometry from the document's own page:/header:/footer: blocks —\n // the same numbers the print path uses (that's what makes the view WYSIWYG).\n const geometryRef = useRef<PageGeometry>(getPageGeometry(\"\"));\n const [pageCount, setPageCount] = useState(1);\n\n const editor = useEditor({\n extensions: [\n Pagination.configure({\n geometry: () => geometryRef.current,\n gap: PAGE_GAP,\n onPages: setPageCount,\n }),\n StarterKit.configure({\n heading: false,\n codeBlock: false,\n blockquote: false,\n horizontalRule: false,\n // Replaced by ITParagraph (core block props: end/leading/space-…).\n paragraph: false,\n }),\n ITParagraph,\n BlockProps,\n LineKeymap,\n Underline,\n TextStyle,\n Color,\n Highlight.configure({ multicolor: true }),\n TextAlign.configure({\n types: [\"paragraph\", \"itTitle\", \"itSummary\", \"itSection\", \"itSub\"],\n }),\n FontFamily,\n FontSize,\n Subscript,\n Superscript,\n ITTitle,\n ITSummary,\n ITSection,\n ITSub,\n ITCallout,\n ITQuote,\n ITCode,\n ITDivider,\n ITTable,\n ITMeta,\n ITTrust,\n ITMetric,\n ITStyleRule,\n ITBreak,\n ITGenericBlock,\n ITComment,\n TemplateHighlight,\n ],\n content: sourceToDoc(value),\n onUpdate: ({ editor: ed }) => {\n // Avoid rewriting source while editor is still hydrating initial content.\n if (isHydrating.current) return;\n const json = ed.getJSON();\n const source = docToSource(json);\n lastSourceRef.current = source;\n isInternalUpdate.current = true;\n // Fidelity guard: flag any styling that won't survive to .it / core print.\n setUnsupported(detectUnsupportedStyling(json));\n onChange(source);\n },\n editorProps: {\n attributes: {\n class: \"docs-page-content\",\n spellcheck: \"true\",\n },\n },\n });\n\n // Sync external source changes (e.g. from file open, source mode edits)\n useEffect(() => {\n // Mark hydration complete on next tick after mount content is applied.\n const t = window.setTimeout(() => {\n isHydrating.current = false;\n lastSourceRef.current = value;\n }, 0);\n return () => window.clearTimeout(t);\n }, []);\n\n useEffect(() => {\n if (!editor) return;\n if (isInternalUpdate.current) {\n isInternalUpdate.current = false;\n return;\n }\n if (value !== lastSourceRef.current) {\n const json = sourceToDoc(value);\n editor.commands.setContent(json);\n lastSourceRef.current = value;\n }\n }, [value, editor]);\n\n // Host \"insert text/variable\" → insert at the current caret. Dispatch a\n // window CustomEvent(\"it-insert-text\", { detail: \"{{customer.name}}\" }).\n useEffect(() => {\n if (!editor) return;\n const handler = (e: Event) => {\n const text = (e as CustomEvent<string>).detail;\n if (text) editor.chain().focus().insertContent(text).run();\n };\n window.addEventListener(\"it-insert-text\", handler);\n return () => window.removeEventListener(\"it-insert-text\", handler);\n }, [editor]);\n\n // Geometry derived from the document itself (page:/header:/footer: blocks).\n const geometry = useMemo(() => getPageGeometry(value), [value]);\n useEffect(() => {\n geometryRef.current = geometry;\n // Nudge the pagination plugin to re-layout with the new geometry.\n editor?.view.dispatch(editor.state.tr);\n }, [geometry, editor]);\n const pageRef = useRef<HTMLDivElement>(null);\n\n // Word count for the page indicator\n const getWordCount = useCallback(() => {\n if (!editor) return 0;\n return (\n editor.storage.characterCount?.words?.() ??\n editor.getText().split(/\\s+/).filter(Boolean).length\n );\n }, [editor]);\n\n // ── Theme CSS injection ──────────────────────────────────\n const themeCSS = useMemo(() => {\n if (!theme) return \"\";\n try {\n const t = getBuiltinTheme(theme);\n if (!t) return \"\";\n return generateThemeCSS(t).replace(/:root\\{/, \".docs-page{\");\n } catch {\n return \"\";\n }\n }, [theme]);\n\n const docLayoutMeta = useMemo(() => {\n try {\n const doc = parseIntentText(value);\n const header = doc.blocks.find((b) => b.type === \"header\")?.content || \"\";\n const footer = doc.blocks.find((b) => b.type === \"footer\")?.content || \"\";\n const metaBlock = doc.blocks.find((b) => b.type === \"meta\");\n const dir = String(metaBlock?.properties?.dir || \"ltr\").toLowerCase();\n return { header, footer, dir };\n } catch {\n return { header: \"\", footer: \"\", dir: \"ltr\" };\n }\n }, [value]);\n\n // ── Trust state: status banner + sealed read-only ─────────\n const trust = useMemo(() => {\n try {\n return extractTrustState(parseIntentText(value));\n } catch {\n return extractTrustState(null);\n }\n }, [value]);\n\n // Hash check for the banner (\"hash verified ✓\") — only when sealed.\n const sealIntact = useMemo<boolean | null>(() => {\n if (!trust.isSealed) return null;\n try {\n return verifyDocument(value).intact;\n } catch {\n return null;\n }\n }, [value, trust.isSealed]);\n\n // Sealed documents are read-only — the canvas refuses edits and the ribbon's\n // formatting groups are disabled (clear professional indication via banner).\n // Hosts can force the same with the readOnly prop.\n const locked = trust.isSealed || readOnly;\n useEffect(() => {\n if (!editor) return;\n if (editor.isEditable === !locked) return;\n editor.setEditable(!locked);\n }, [editor, locked]);\n\n // Native RTL: set `dir` directly on the ProseMirror editable element so the\n // caret jumps to the right edge and typing flows right-to-left (not just a\n // visual mirror). Reflows immediately when the meta dir toggles.\n useEffect(() => {\n if (!editor) return;\n const dom = editor.view.dom as HTMLElement;\n dom.setAttribute(\"dir\", docLayoutMeta.dir === \"rtl\" ? \"rtl\" : \"ltr\");\n }, [editor, docLayoutMeta.dir]);\n\n // Live document styles: apply the doc's `style:` rules to the canvas so the\n // author SEES the house styling while editing (and the WYSIWYG print export\n // inherits it automatically, since it copies the page's <style> elements).\n const docStyleRulesCSS = useMemo(() => {\n try {\n return documentStyleCSS(\n parseIntentText(value),\n EDITOR_STYLE_SELECTORS,\n \".docs-page .tiptap \",\n );\n } catch {\n return \"\";\n }\n }, [value]);\n useEffect(() => {\n let el = document.getElementById(\n \"it-doc-style-rules\",\n ) as HTMLStyleElement | null;\n if (!el) {\n el = document.createElement(\"style\");\n el.id = \"it-doc-style-rules\";\n document.head.appendChild(el);\n }\n el.textContent = docStyleRulesCSS;\n }, [docStyleRulesCSS]);\n\n // RTL toggle — idempotent via core's upsertMetaProperty (no more\n // `dir: rtl | dir: rtl` spam). Setting null removes the property cleanly.\n const toggleRtl = useCallback(() => {\n const isRtl = docLayoutMeta.dir === \"rtl\";\n onChange(upsertMetaProperty(value, \"dir\", isRtl ? null : \"rtl\"));\n }, [value, onChange, docLayoutMeta.dir]);\n\n // Ruler drag → update the page: block's margins. Writes mm (the .it canonical\n // unit) as a `page: … | margin: T R B L` shorthand so the change round-trips\n // and the print path reads identical margins.\n const setMargins = useCallback(\n (next: { top?: number; right?: number; bottom?: number; left?: number }) => {\n const g = geometryRef.current;\n const pxToMm = (px: number) => Math.max(0, Math.round((px / MM) * 10) / 10);\n const t = pxToMm(next.top ?? g.marginTop);\n const r = pxToMm(next.right ?? g.marginRight);\n const b = pxToMm(next.bottom ?? g.marginBottom);\n const l = pxToMm(next.left ?? g.marginLeft);\n const marginVal = `${t}mm ${r}mm ${b}mm ${l}mm`;\n onChange(setPageMargin(value, marginVal));\n },\n [value, onChange],\n );\n\n useEffect(() => {\n const id = \"it-editor-theme-css\";\n let el = document.getElementById(id) as HTMLStyleElement | null;\n if (!el) {\n el = document.createElement(\"style\");\n el.id = id;\n document.head.appendChild(el);\n }\n el.textContent = themeCSS;\n }, [themeCSS]);\n\n // ── Zoom ─────────────────────────────────────────────────\n const canvasRef = useRef<HTMLDivElement>(null);\n const [zoom, setZoom] = useState(1);\n const prevZoomRef = useRef(zoom);\n // Store focal point in content-space coordinates for zoom\n const focalRef = useRef<{ cx: number; cy: number } | null>(null);\n\n // Capture focal point at mouse position (for wheel zoom)\n const captureFocalAtMouse = useCallback(\n (e: { clientX: number; clientY: number }) => {\n const el = canvasRef.current;\n if (!el) return;\n const rect = el.getBoundingClientRect();\n // Mouse position in content-space (scroll + offset within viewport)\n focalRef.current = {\n cx: el.scrollLeft + (e.clientX - rect.left),\n cy: el.scrollTop + (e.clientY - rect.top),\n };\n },\n [],\n );\n\n // Capture focal point at viewport center (for keyboard zoom)\n const captureFocalAtCenter = useCallback(() => {\n const el = canvasRef.current;\n if (!el) return;\n focalRef.current = {\n cx: el.scrollLeft + el.clientWidth / 2,\n cy: el.scrollTop + el.clientHeight / 2,\n };\n }, []);\n\n // After DOM paints with new zoom, restore scroll so focal point is stable\n useLayoutEffect(() => {\n const el = canvasRef.current;\n const focal = focalRef.current;\n const prevZoom = prevZoomRef.current;\n if (!el || !focal || prevZoom === zoom) return;\n const ratio = zoom / prevZoom;\n // The focal point in old content-space maps to focal * ratio in new content-space\n const rect = el.getBoundingClientRect();\n // Where was the focal point relative to the viewport?\n const vpX = focal.cx - el.scrollLeft;\n const vpY = focal.cy - el.scrollTop;\n el.scrollLeft = focal.cx * ratio - vpX;\n el.scrollTop = focal.cy * ratio - vpY;\n focalRef.current = null;\n prevZoomRef.current = zoom;\n }, [zoom]);\n\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (!(e.metaKey || e.ctrlKey)) return;\n // Cmd/Ctrl+P → OUR WYSIWYG PDF export, not the raw browser print dialog.\n if (e.key === \"p\" || e.key === \"P\") {\n e.preventDefault();\n exportDocumentPDF(value, theme);\n return;\n }\n if (e.key === \"=\" || e.key === \"+\") {\n e.preventDefault();\n captureFocalAtCenter();\n setZoom((z) => Math.min(2, +(z + 0.1).toFixed(2)));\n } else if (e.key === \"-\") {\n e.preventDefault();\n captureFocalAtCenter();\n setZoom((z) => Math.max(0.25, +(z - 0.1).toFixed(2)));\n } else if (e.key === \"0\") {\n e.preventDefault();\n captureFocalAtCenter();\n setZoom(1);\n }\n };\n window.addEventListener(\"keydown\", handler);\n return () => window.removeEventListener(\"keydown\", handler);\n }, [captureFocalAtCenter, value, theme]);\n\n useEffect(() => {\n const el = canvasRef.current;\n if (!el) return;\n const handler = (e: WheelEvent) => {\n if (e.ctrlKey || e.metaKey) {\n e.preventDefault();\n const delta = e.deltaY > 0 ? -0.1 : 0.1;\n captureFocalAtMouse(e);\n setZoom((z) => Math.min(2, Math.max(0.25, +(z + delta).toFixed(2))));\n }\n };\n el.addEventListener(\"wheel\", handler, { passive: false });\n return () => el.removeEventListener(\"wheel\", handler);\n }, [captureFocalAtMouse]);\n\n return (\n <div className=\"docs-container\">\n {showRibbon && (\n <DocsToolbar\n editor={editor}\n isRtl={docLayoutMeta.dir === \"rtl\"}\n onToggleRtl={toggleRtl}\n content={value}\n onChange={onChange}\n theme={theme}\n onThemeChange={onThemeChange}\n onTrustAction={onTrustAction}\n trust={trust}\n sealIntact={sealIntact}\n locked={locked}\n />\n )}\n {showTrustBanner && <TrustBanner trust={trust} intact={sealIntact} />}\n {showTrustBanner && <DocPropsBar source={value} />}\n {unsupported.length > 0 && (\n <div className=\"docs-fidelity-warning\" role=\"status\">\n ⚠ Some formatting ({unsupported.join(\", \")}) can’t be saved to{\" \"}\n <code>.it</code> and won’t appear when printed through the template —\n remove it or use the toolbar’s color/size/style controls instead.\n </div>\n )}\n <DocsRuler\n geometry={geometry}\n zoom={zoom}\n scrollEl={canvasRef}\n onMargins={setMargins}\n locked={locked}\n />\n <div className=\"docs-canvas-row\">\n <DocsVerticalRuler\n geometry={geometry}\n zoom={zoom}\n scrollEl={canvasRef}\n onMargins={setMargins}\n locked={locked}\n />\n <div className=\"docs-canvas\" ref={canvasRef}>\n <div\n className=\"docs-page-scaler\"\n style={{ width: geometry.width * zoom }}\n >\n <div\n className=\"docs-page-flow\"\n dir={docLayoutMeta.dir}\n style={{\n transform: zoom !== 1 ? `scale(${zoom})` : undefined,\n transformOrigin: \"top left\",\n }}\n >\n {/* One continuous editable sheet, visually cut into Word-like pages.\n The static band below is page 1's top margin + header; the\n Pagination plugin closes every page with its footer band (incl.\n the last) and opens the next with its header band. */}\n <div\n className=\"docs-page docs-sheet\"\n ref={pageRef}\n style={\n {\n width: geometry.width,\n minHeight: geometry.autoHeight ? geometry.width : undefined,\n \"--page-mx-l\": `${geometry.marginLeft}px`,\n \"--page-mx-r\": `${geometry.marginRight}px`,\n } as React.CSSProperties\n }\n >\n <div\n className=\"docs-sheet-header\"\n data-it-spacer=\"\"\n style={{ height: geometry.autoHeight ? undefined : geometry.marginTop }}\n >\n <div className=\"docs-pb-header\">\n <span className=\"docs-pb-text\">\n {geometry.autoHeight\n ? \"\"\n : resolvePageTokens(geometry.header, 1, pageCount)}\n </span>\n </div>\n </div>\n <EditorContent editor={editor} />\n </div>\n </div>\n </div>\n <div className=\"docs-page-footer\">\n {pageCount} {pageCount === 1 ? \"page\" : \"pages\"} &middot;{\" \"}\n {getWordCount()} words\n {zoom !== 1 && (\n <span className=\"zoom-indicator\">\n {\" \"}\n &middot; {Math.round(zoom * 100)}%\n </span>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n}\n","// IntentTextEditor — the embeddable IntentText visual editor.\n//\n// A controlled React component over `.it` source text: the host owns the\n// document (value/onChange), the editor renders a Word-like WYSIWYG canvas\n// with the formatting ribbon and trust banner. Everything styled here maps to\n// core `.it` properties, so the printed PDF always matches the screen.\n\nimport { useCallback, useState } from \"react\";\nimport { VisualEditor } from \"./VisualEditor\";\nimport type { TrustAction } from \"./types\";\n\nexport interface IntentTextEditorProps {\n /** Current `.it` source text (controlled). */\n value: string;\n /** Called with the updated `.it` source on every edit. */\n onChange: (source: string) => void;\n /**\n * Document theme id (see builtinThemes()). When provided the theme is\n * controlled — pair it with onThemeChange so the ribbon's theme select\n * works. When omitted the editor manages it internally (default\n * \"corporate\").\n */\n theme?: string;\n /** Called when the user picks a theme in the ribbon. */\n onThemeChange?: (theme: string) => void;\n /** Force read-only. Sealed documents are read-only automatically. */\n readOnly?: boolean;\n /** Show the formatting ribbon. Default true. */\n showRibbon?: boolean;\n /** Show the trust status banner + document properties strip. Default true. */\n showTrustBanner?: boolean;\n /**\n * Handle the ribbon's Trust group (Seal / Sign / Verify). The editor only\n * reports the intent — wire it to your own dialogs/flows (e.g. core's\n * sealDocument / verifyDocument). The group is hidden when omitted.\n */\n onTrustAction?: (action: TrustAction) => void;\n}\n\nconst DEFAULT_THEME = \"corporate\";\n\nexport function IntentTextEditor({\n value,\n onChange,\n theme,\n onThemeChange,\n readOnly = false,\n showRibbon = true,\n showTrustBanner = true,\n onTrustAction,\n}: IntentTextEditorProps) {\n // Theme is controlled when the host passes `theme`; self-managed otherwise.\n const [internalTheme, setInternalTheme] = useState(theme ?? DEFAULT_THEME);\n const activeTheme = theme ?? internalTheme;\n const handleThemeChange = useCallback(\n (t: string) => {\n setInternalTheme(t);\n onThemeChange?.(t);\n },\n [onThemeChange],\n );\n\n return (\n <VisualEditor\n value={value}\n onChange={onChange}\n theme={activeTheme}\n onThemeChange={handleThemeChange}\n readOnly={readOnly}\n showRibbon={showRibbon}\n showTrustBanner={showTrustBanner}\n onTrustAction={onTrustAction}\n />\n );\n}\n"],"names":["FontSize","Extension","el","attributes","size","chain","MM","PAPER_MM","PAPER_UNIT","DEFAULT_MARGIN_MM","NARROW_MARGIN_MM","NARROW_WIDTH_MM","parseLength","v","m","parseMargins","raw","fallback","parts","p","getPageGeometry","source","marginRaw","header","footer","doc","parseIntentText","props","b","width","height","autoHeight","unit","named","w","h","defMargin","mt","mr","mb","ml","setPageMargin","marginValue","lines","pageIdx","l","line","insertAt","pageLine","resolvePageTokens","text","page","pages","paginationKey","PluginKey","bandHtml","kind","resolved","escapeHtml","s","Pagination","opts","Plugin","DecorationSet","tr","old","meta","state","view","raf","lastSig","makeBreak","g","restHeight","makeTail","recompute","dom","domTop","all","blocks","spacerAbove","c","r","breaks","pos","pageStart","lastBottom","i","nodeSize","lastRest","sig","decos","idx","Decoration","set","schedule","CALLOUT_TYPES","META_KEYWORDS","TRUST_KEYWORDS","HEADING_MAP","KEYWORD_ALIASES","MARK_STYLE_KEYS","parseProps","formatProps","exclude","entries","k","textToContent","result","part","inlineNodeMarks","node","marks","ts","MAPPABLE_INLINE","inlineToContent","inline","fallbackText","n","applyPropsAsMarks","content","properties","tsAttrs","family","bg","marksToProps","mark","runToInlineText","child","extractText","t","types","link","hl","hasColorFont","semanticCount","out","SUPPORTED_MARKS","detectUnsupportedStyling","found","walk","inlineToSource","children","align","mergeProps","existingRaw","markProps","existing","key","normalizeKeyword","keyword","lineKeyword","trimmedLine","parsedBlockKeyword","blockType","keywordsMatch","sourceKey","parsedKey","parseInlineProps","rest","seg","fallbackLineToBlock","type","listLineMatch","trimmed","bullet","ordered","makeListItem","sourceToDoc","block","blockToNode","blockIdx","li","mkw","pType","listStart","items","lj","rows","rawBlock","nextParsed","textContent","propsJson","textAlign","attrs","variant","propStr","docToSource","nodeToLines","item","mp","nodeToLine","merged","a","blockProps","by","byPart","kw","direct","property","css","TEXT_STYLES","CALLOUT_STYLES","CHIP_STYLES","KEYWORD_STYLES","computeKeywordStyles","rules","styles","rule","value","buildStyle","endAttrs","ITTitle","Node","HTMLAttributes","safeParse","mergeAttributes","ITSummary","ITSection","ITSub","ITCallout","icons","ITQuote","ITCode","ITDivider","ITMeta","parseRows","ITTable","head","body","tableCellAttrs","editor","getPos","table","thead","tbody","commit","next","json","makeCell","tag","cell","editable","e","render","grid","htr","row","updated","parseTrustLine","colon","segs","ITTrust","role","date","hash","who","what","name","valid","ITMetric","isTotal","valueIsVar","ITStyleRule","decl","ITBreak","ITGenericBlock","linkTarget","ITComment","val","PARA_ATTR","PROPS_JSON_SPACING","PROPS_JSON_END","safeParseProps","supportsKey","typeName","ITParagraph","Paragraph","BlockProps","dispatch","from","to","changed","getBlockProp","CATEGORY_META","printHtmlViaIframe","html","iframe","printed","doPrint","idoc","injectCss","MINIMAL_INK_CSS","cssContent","cssContentValue","buildWysiwygPrint","printMode","tiptap","clone","bodyHtml","sizeCss","marginCss","pageCss","overrides","download","data","filename","mime","blob","url","buildPrintHtml","theme","full","renderPrint","exportDocumentPDF","downloadItFile","id","title","exportDocumentHTML","builtinThemes","listBuiltinThemes","SIGNER_KEY","ROLE_KEY","TrustControl","onChange","trust","intact","open","setOpen","useState","signing","setSigning","signer","setSigner","setRole","busy","setBusy","rootRef","useRef","lastClickRef","debounced","useCallback","fn","now","useEffect","onDown","sealed","coreIsSealed","doSign","res","signDocument","doSeal","sealDocument","doUnseal","unsealDocument","verifyResult","setVerifyResult","doVerify","verifyDocument","faceIcon","jsx","PenTool","faceLabel","faceClass","FileLock2","ShieldCheck","jsxs","o","ChevronDown","Fragment","LockOpen","STYLE_OPTIONS","READ_ONLY_INSERT_KEYWORDS","HIDDEN_INSERT_KEYWORDS","CATEGORY_ORDER","FONT_FAMILIES","LINE_SPACINGS","SPACE_STEP","TEXT_COLORS","HIGHLIGHT_COLORS","Btn","onClick","active","disabled","Group","label","className","GroupSep","DocsToolbar","isRtl","onToggleRtl","onThemeChange","onTrustAction","sealIntact","locked","styleOpen","setStyleOpen","insertOpen","setInsertOpen","fontOpen","setFontOpen","textColorOpen","setTextColorOpen","highlightColorOpen","setHighlightColorOpen","spacingOpen","setSpacingOpen","inkSaver","setInkSaver","styleRef","insertRef","fontRef","textColorRef","highlightColorRef","spacingRef","handler","closeAll","getCurrentStyle","opt","getCurrentFont","match","f","fontSize","setFontSize","setSelTick","insertGroups","useMemo","grouped","entry","LANGUAGE_REGISTRY","category","list","updateFontSize","setStyle","nodeType","insertBlock","changeFontSize","delta","setLeading","toggleSpace","cur","customSpacing","before","after","editSplitEnd","insertSplitRow","themes","doExportPDF","doSave","currentLeading","hasEnd","Undo2","Redo2","Download","Printer","Droplets","Minus","Plus","Bold","Italic","Underline","Strikethrough","Palette","RemoveFormatting","Highlighter","Code","AlignLeft","AlignCenter","AlignRight","AlignJustify","Rows3","List","ListOrdered","AlignHorizontalSpaceBetween","group","gi","UNIT_PX","MINOR_STEP","buildTicks","length","unitPx","step","units","u","isMajor","DocsRuler","geometry","zoom","scrollEl","onMargins","scrollLeft","setScrollLeft","drag","setDrag","trackRef","onScroll","ticks","onPointerDown","side","onMove","track","rect","pageX","left","right","onUp","draggable","DocsVerticalRuler","topOffset","scrollTop","setScrollTop","pageH","pageY","top","bottom","TrustBanner","collectDocProps","push","orientation","DocPropsBar","summary","prop","extractTrustState","base","approveBlocks","signBlocks","freeze","amendBlocks","am","VAR_RE","buildDecorations","TemplateHighlight","_cfg","extractTemplateVariables","seen","buildSampleSkeleton","vars","root","path","visualLineEdge","edge","coords","bandTop","bandBottom","dir","last","LineKeymap","moveToEdge","extend","selection","target","$target","anchor","TextSelection","PAGE_GAP","EDITOR_STYLE_SELECTORS","VisualEditor","readOnly","showRibbon","showTrustBanner","lastSourceRef","isInternalUpdate","isHydrating","unsupported","setUnsupported","geometryRef","pageCount","setPageCount","useEditor","StarterKit","TextStyle","Color","Highlight","TextAlign","FontFamily","Subscript","Superscript","ed","pageRef","getWordCount","themeCSS","getBuiltinTheme","generateThemeCSS","docLayoutMeta","metaBlock","docStyleRulesCSS","documentStyleCSS","toggleRtl","upsertMetaProperty","setMargins","pxToMm","px","marginVal","canvasRef","setZoom","prevZoomRef","focalRef","captureFocalAtMouse","captureFocalAtCenter","useLayoutEffect","focal","prevZoom","ratio","vpX","vpY","z","EditorContent","DEFAULT_THEME","IntentTextEditor","internalTheme","setInternalTheme","activeTheme","handleThemeChange"],"mappings":"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"}