@pixerate/editor 0.14.1 → 0.14.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -0
- package/dist/index.cjs +111 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +111 -3
- package/dist/index.js.map +1 -1
- package/dist/serializers/index.cjs +111 -3
- package/dist/serializers/index.cjs.map +1 -1
- package/dist/serializers/index.d.cts +8 -0
- package/dist/serializers/index.d.ts +8 -0
- package/dist/serializers/index.js +111 -3
- package/dist/serializers/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/grammar/tokens.ts","../src/grammar/tokenizer.ts","../src/grammar/resolver.ts","../src/grammar/sourcemap.ts","../src/extensions/gradient-text.ts","../src/extensions/slash-commands.ts","../src/extensions/template-suggestions.ts","../src/extensions/loading-node.ts","../src/extensions/SmilieReplacer.ts","../src/extensions/ColorHighlighter.ts","../src/extensions/FontSize.ts","../src/extensions/rich-text-preset.ts","../src/extensions/mention.ts","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/tiptap/tight-lists.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/util/markdown.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/serialize/state.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/marks/html.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/util/dom.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/html.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/blockquote.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/bullet-list.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/code-block.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/hard-break.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/heading.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/horizontal-rule.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/image.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/list-item.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/ordered-list.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/paragraph.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/util/prosemirror.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/table.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/task-item.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/task-list.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/text.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/marks/bold.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/marks/code.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/marks/italic.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/marks/link.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/marks/strike.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/index.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/util/extensions.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/serialize/MarkdownSerializer.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/parse/MarkdownParser.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/tiptap/clipboard.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/Markdown.js","../src/extensions/markdown.ts","../src/extensions/image.ts","../src/serializers/mentions.ts","../src/serializers/plain-text.ts","../src/serializers/markdown.ts","../src/controller.ts","../src/spreadsheet/formula/lexer.ts","../src/spreadsheet/formula/parser.ts","../src/spreadsheet/formula/evaluator.ts","../src/spreadsheet/formula/dependency-graph.ts","../src/spreadsheet/datasource/index.ts","../src/spreadsheet/controller.ts","../src/dirty.ts","../src/history/HistoryManager.ts","../src/canvas/layout.ts","../src/canvas/clock.ts","../src/canvas/trajectory.ts","../src/canvas/displacement.ts","../src/canvas/clipboard.ts","../src/canvas/view.ts","../src/canvas/streaming.ts","../src/agent/planner.ts","../src/agent/tools.ts","../src/image-editor/filters.ts","../src/image-editor/renderer.ts","../src/image-editor/controller.ts","../src/image-editor/geometry.ts"],"sourcesContent":["/**\n * Canonical regex patterns for prompt editing tokens.\n */\nexport const TEMPLATE_REGEX = /{{\\s*([^}]+?)\\s*}}/g;\nexport const VARIABLE_REGEX = /(?<!\\{)\\{([^{}]+)\\}(?!\\})/g;\nexport const INSTRUCTION_REGEX = /__(.+?)__/g;\n\n// Backward-compatible camelCase aliases\nexport const templateRegex = TEMPLATE_REGEX;\nexport const variableRegex = VARIABLE_REGEX;\nexport const instructionRegex = INSTRUCTION_REGEX;\n\nexport type TokenType = \"template\" | \"variable\" | \"instruction\" | \"text\";\n\nexport interface Token {\n type: TokenType;\n raw: string;\n value: string;\n start: number;\n end: number;\n}\n\nexport interface TemplateVersion {\n id: string;\n version: string | number;\n body: string;\n createdAt?: any;\n [key: string]: any;\n}\n\nexport interface Template {\n id?: string;\n name: string;\n body?: string;\n latestVersion?: string | number;\n versions?: TemplateVersion[];\n color?: string;\n [key: string]: any;\n}\n\nexport interface ColorGradient {\n from: string;\n to: string;\n}\n","import {\n TEMPLATE_REGEX,\n VARIABLE_REGEX,\n INSTRUCTION_REGEX,\n Token,\n} from \"./tokens\";\n\ninterface RawMatch {\n type: \"template\" | \"variable\" | \"instruction\";\n raw: string;\n value: string;\n start: number;\n end: number;\n}\n\n/**\n * Parses any prompt string into an array of typed tokens in linear order.\n * Plain text between tokens is preserved as `{ type: 'text' }`.\n */\nexport function tokenizePrompt(text: string): Token[] {\n if (!text) {\n return [];\n }\n\n const rawMatches: RawMatch[] = [];\n\n // Match {{template}}\n const tmplRegex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = tmplRegex.exec(text)) !== null) {\n rawMatches.push({\n type: \"template\",\n raw: match[0],\n value: match[1].trim(),\n start: match.index,\n end: match.index + match[0].length,\n });\n }\n\n // Match {variable}\n const varRegex = new RegExp(VARIABLE_REGEX.source, VARIABLE_REGEX.flags);\n while ((match = varRegex.exec(text)) !== null) {\n // Avoid double matching if overlapping with template\n const start = match.index;\n const end = start + match[0].length;\n const overlaps = rawMatches.some(\n (m) => !(end <= m.start || start >= m.end),\n );\n if (!overlaps) {\n rawMatches.push({\n type: \"variable\",\n raw: match[0],\n value: match[1].trim(),\n start,\n end,\n });\n }\n }\n\n // Match __instruction__\n const instRegex = new RegExp(\n INSTRUCTION_REGEX.source,\n INSTRUCTION_REGEX.flags,\n );\n while ((match = instRegex.exec(text)) !== null) {\n const start = match.index;\n const end = start + match[0].length;\n const overlaps = rawMatches.some(\n (m) => !(end <= m.start || start >= m.end),\n );\n if (!overlaps) {\n rawMatches.push({\n type: \"instruction\",\n raw: match[0],\n value: match[1].trim(),\n start,\n end,\n });\n }\n }\n\n // Sort matches by start index\n rawMatches.sort((a, b) => a.start - b.start);\n\n const tokens: Token[] = [];\n let currentIdx = 0;\n\n for (const m of rawMatches) {\n if (m.start > currentIdx) {\n const textChunk = text.slice(currentIdx, m.start);\n tokens.push({\n type: \"text\",\n raw: textChunk,\n value: textChunk,\n start: currentIdx,\n end: m.start,\n });\n }\n tokens.push({\n type: m.type,\n raw: m.raw,\n value: m.value,\n start: m.start,\n end: m.end,\n });\n currentIdx = m.end;\n }\n\n if (currentIdx < text.length) {\n const textChunk = text.slice(currentIdx);\n tokens.push({\n type: \"text\",\n raw: textChunk,\n value: textChunk,\n start: currentIdx,\n end: text.length,\n });\n }\n\n return tokens;\n}\n","import {\n TEMPLATE_REGEX,\n VARIABLE_REGEX,\n INSTRUCTION_REGEX,\n Template,\n TemplateVersion,\n} from \"./tokens\";\n\n/**\n * Finds the latest version of a template based on `latestVersion` or last version entry.\n */\nexport function getLatestVersion(\n template: Template,\n): TemplateVersion | undefined {\n if (!template.versions || template.versions.length === 0) {\n if (template.body !== undefined) {\n return {\n id: template.id || \"default\",\n version: \"1.0\",\n body: template.body,\n };\n }\n return undefined;\n }\n if (template.latestVersion) {\n const found = template.versions.find(\n (v) => v.version === template.latestVersion,\n );\n if (found) return found;\n }\n return template.versions[template.versions.length - 1];\n}\n\nexport interface ResolveTemplatesOptions {\n bindings?: Record<string, string>;\n maxDepth?: number;\n}\n\n/** Marker substituted for a template tag that would recurse into itself. */\nexport const TEMPLATE_LOOP_ERROR = \"[Template loop detected]\";\n/** Marker substituted for a template tag nested deeper than `maxDepth`. */\nexport const TEMPLATE_DEPTH_ERROR = \"[Template max depth exceeded]\";\n\n/**\n * Returns the body a template tag resolves to, honoring version bindings.\n */\nexport function getTemplateBody(\n template: Template,\n bindings?: Record<string, string>,\n): string | undefined {\n const boundVersionId = bindings?.[template.name];\n if (boundVersionId && template.versions) {\n const boundVersion = template.versions.find(\n (v) => v.id === boundVersionId || v.version === boundVersionId,\n );\n return boundVersion?.body;\n }\n return getLatestVersion(template)?.body ?? template.body;\n}\n\n/**\n * Recursively resolves template tags `{{template_name}}` in a given text.\n * A tag that would recurse into itself is replaced with `TEMPLATE_LOOP_ERROR`,\n * and a tag nested deeper than `maxDepth` with `TEMPLATE_DEPTH_ERROR`; the rest\n * of the text still resolves normally.\n */\nexport function resolveTemplates(\n text: string,\n templates: Template[] = [],\n options?: ResolveTemplatesOptions,\n): string {\n const templateMap = new Map<string, Template>();\n for (const t of templates) {\n templateMap.set(t.name, t);\n }\n\n const maxDepth = options?.maxDepth ?? 10;\n\n function resolveRecursive(\n currentText: string,\n visited: Set<string>,\n depth: number,\n ): string {\n const regex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n\n // A function replacer keeps `$&`, `$'` etc. in template bodies literal.\n return currentText.replace(regex, (fullMatch, rawTemplateName: string) => {\n const templateName = rawTemplateName.trim();\n\n if (visited.has(templateName)) {\n return TEMPLATE_LOOP_ERROR;\n }\n\n const template = templateMap.get(templateName);\n if (!template) {\n return fullMatch;\n }\n\n const versionBody = getTemplateBody(template, options?.bindings);\n if (versionBody === undefined) {\n return fullMatch;\n }\n\n if (depth + 1 > maxDepth) {\n return TEMPLATE_DEPTH_ERROR;\n }\n\n const nextVisited = new Set(visited);\n nextVisited.add(templateName);\n\n return resolveRecursive(versionBody, nextVisited, depth + 1);\n });\n }\n\n return resolveRecursive(text, new Set(), 0);\n}\n\n/**\n * Replaces `{variableName}` with values from a dictionary.\n */\nexport function resolveVariables(\n text: string,\n values: Record<string, string | number>,\n): string {\n if (!text) return \"\";\n return text.replace(\n new RegExp(VARIABLE_REGEX.source, VARIABLE_REGEX.flags),\n (fullMatch, varName) => {\n const key = varName.trim();\n if (Object.prototype.hasOwnProperty.call(values, key)) {\n return String(values[key]);\n }\n return fullMatch;\n },\n );\n}\n\n/**\n * Extracts unique template names referenced in text.\n */\nexport function extractTemplateNames(text: string): string[] {\n if (!text) return [];\n const set = new Set<string>();\n const regex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n set.add(match[1].trim());\n }\n return Array.from(set);\n}\n\n/**\n * Extracts unique variable names referenced in text.\n */\nexport function extractVariableNames(text: string): string[] {\n if (!text) return [];\n const set = new Set<string>();\n const regex = new RegExp(VARIABLE_REGEX.source, VARIABLE_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n set.add(match[1].trim());\n }\n return Array.from(set);\n}\n\n/**\n * Extracts unique instruction names referenced in text.\n */\nexport function extractInstructionNames(text: string): string[] {\n if (!text) return [];\n const set = new Set<string>();\n const regex = new RegExp(INSTRUCTION_REGEX.source, INSTRUCTION_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n set.add(match[1].trim());\n }\n return Array.from(set);\n}\n","import { TEMPLATE_REGEX, Template } from \"./tokens\";\nimport {\n getTemplateBody,\n resolveTemplates,\n type ResolveTemplatesOptions,\n} from \"./resolver\";\n\nexport interface SourceMapSegment {\n resolvedStart: number;\n resolvedEnd: number;\n source: \"raw\" | \"template\";\n rawStart: number;\n rawEnd: number;\n templateName?: string;\n}\n\n/**\n * Resolves templates in text while tracking character offset mapping\n * between the raw input and the fully resolved output.\n */\nexport function resolveTemplatesWithMapping(\n text: string,\n templates: Template[] = [],\n templateBindings?: Record<string, string>,\n options?: Pick<ResolveTemplatesOptions, \"maxDepth\">,\n): { text: string; map: SourceMapSegment[] } {\n if (!templates || templates.length === 0 || !text.includes(\"{{\")) {\n return {\n text,\n map: [\n {\n resolvedStart: 0,\n resolvedEnd: text.length,\n source: \"raw\",\n rawStart: 0,\n rawEnd: text.length,\n },\n ],\n };\n }\n\n const templateMap = new Map(templates.map((t) => [t.name, t]));\n const regex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n let match: RegExpExecArray | null;\n let lastIndex = 0;\n let resolvedText = \"\";\n const map: SourceMapSegment[] = [];\n\n while ((match = regex.exec(text)) !== null) {\n const [fullMatch, rawTemplateName] = match;\n const templateName = rawTemplateName.trim();\n const matchIndex = match.index;\n\n // Add raw text preceding this template match\n if (matchIndex > lastIndex) {\n const rawSegment = text.substring(lastIndex, matchIndex);\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + rawSegment.length,\n source: \"raw\",\n rawStart: lastIndex,\n rawEnd: matchIndex,\n });\n resolvedText += rawSegment;\n }\n\n let resolvedBody = fullMatch;\n let isTemplate = false;\n\n const template = templateMap.get(templateName);\n if (template && getTemplateBody(template, templateBindings) !== undefined) {\n // Resolve the tag itself so loop and depth handling match resolveTemplates.\n resolvedBody = resolveTemplates(fullMatch, templates, {\n bindings: templateBindings,\n maxDepth: options?.maxDepth,\n });\n isTemplate = true;\n }\n\n if (isTemplate) {\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + resolvedBody.length,\n source: \"template\",\n rawStart: matchIndex,\n rawEnd: matchIndex + fullMatch.length,\n templateName,\n });\n resolvedText += resolvedBody;\n } else {\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + fullMatch.length,\n source: \"raw\",\n rawStart: matchIndex,\n rawEnd: matchIndex + fullMatch.length,\n });\n resolvedText += fullMatch;\n }\n\n lastIndex = matchIndex + fullMatch.length;\n }\n\n // Add any remaining raw text after the final match\n if (lastIndex < text.length) {\n const rawSegment = text.substring(lastIndex);\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + rawSegment.length,\n source: \"raw\",\n rawStart: lastIndex,\n rawEnd: text.length,\n });\n resolvedText += rawSegment;\n }\n\n return { text: resolvedText, map };\n}\n\n/**\n * Maps an offset in resolved text back to the corresponding offset in raw text.\n */\nexport function mapResolvedOffsetToRaw(\n resolvedOffset: number,\n map: SourceMapSegment[],\n): number {\n for (let i = 0; i < map.length; i++) {\n const seg = map[i];\n const isLast = i === map.length - 1;\n const inRange = isLast\n ? resolvedOffset >= seg.resolvedStart && resolvedOffset <= seg.resolvedEnd\n : resolvedOffset >= seg.resolvedStart && resolvedOffset < seg.resolvedEnd;\n\n if (inRange) {\n if (seg.source === \"raw\") {\n return seg.rawStart + (resolvedOffset - seg.resolvedStart);\n }\n // The end of the text maps to the end of the tag; anywhere inside a\n // resolved template maps to the start of its tag.\n if (resolvedOffset === seg.resolvedEnd) {\n return seg.rawEnd;\n }\n return seg.rawStart;\n }\n }\n return resolvedOffset;\n}\n\n/**\n * Maps an offset in raw text to the corresponding offset in resolved text.\n */\nexport function mapRawOffsetToResolved(\n rawOffset: number,\n map: SourceMapSegment[],\n): number {\n for (let i = 0; i < map.length; i++) {\n const seg = map[i];\n const isLast = i === map.length - 1;\n const inRange = isLast\n ? rawOffset >= seg.rawStart && rawOffset <= seg.rawEnd\n : rawOffset >= seg.rawStart && rawOffset < seg.rawEnd;\n\n if (inRange) {\n if (seg.source === \"raw\") {\n return seg.resolvedStart + (rawOffset - seg.rawStart);\n }\n if (rawOffset === seg.rawEnd) {\n return seg.resolvedEnd;\n }\n return seg.resolvedStart;\n }\n }\n return rawOffset;\n}\n","import { Mark } from \"@tiptap/core\";\nimport { Plugin } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport type { Node as ProsemirrorNode } from \"@tiptap/pm/model\";\nimport type { EditorState } from \"@tiptap/pm/state\";\nimport { TEMPLATE_REGEX, VARIABLE_REGEX, INSTRUCTION_REGEX, ColorGradient } from \"../grammar/tokens\";\n\nexport interface GradientTextOptions {\n templateColorMap: Map<string, ColorGradient>;\n speed?: number;\n jsonVariables?: string[] | Set<string>;\n onTemplateClick?: (templateName: string, event: MouseEvent) => void;\n}\n\nconst createGradientDecorations = (\n doc: ProsemirrorNode,\n options: GradientTextOptions,\n): Decoration[] => {\n const decorations: Decoration[] = [];\n const speed = options.speed ?? 1;\n const jsonVarSet = options.jsonVariables\n ? options.jsonVariables instanceof Set\n ? options.jsonVariables\n : new Set(options.jsonVariables)\n : null;\n\n doc.descendants((node, pos) => {\n if (node.isText) {\n const text = node.text || \"\";\n let match: RegExpExecArray | null;\n\n // 1. Template: {{templateName}}\n const tmplRegex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n while ((match = tmplRegex.exec(text)) !== null) {\n const templateName = match[1].trim();\n const colors = options.templateColorMap?.get(templateName);\n\n if (colors) {\n const start = pos + match.index;\n const end = start + match[0].length;\n const { from: colorFrom, to: colorTo } = colors;\n\n const style = `--bg-size: ${\n speed * 300\n }%; --color-from: ${colorFrom}; --color-to: ${colorTo}; caret-color: #111 !important; background-image: linear-gradient(to right, ${colorFrom}, ${colorTo}, ${colorFrom}); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent;`;\n\n decorations.push(\n Decoration.inline(start, end, {\n class:\n \"inline animate-gradient bg-gradient-to-r from-[var(--color-from)] via-[var(--color-to)] to-[var(--color-from)] bg-[length:var(--bg-size)_100%] bg-clip-text text-transparent border border-(--color-to)/20 px-1 py-0.5 rounded-sm cursor-pointer\",\n style,\n \"data-template\": templateName,\n }),\n );\n }\n }\n\n // 2. Instruction: __text__\n const instRegex = new RegExp(\n INSTRUCTION_REGEX.source,\n INSTRUCTION_REGEX.flags,\n );\n while ((match = instRegex.exec(text)) !== null) {\n const content = match[1].trim();\n const colors = options.templateColorMap?.get(content) || {\n from: \"#ffaa40\",\n to: \"#9c40ff\",\n };\n\n const start = pos + match.index;\n const end = start + match[0].length;\n const { from: colorFrom, to: colorTo } = colors;\n\n const style = `--bg-size: ${\n speed * 300\n }%; --color-from: ${colorFrom}; --color-to: ${colorTo}; caret-color: #111 !important; background-image: linear-gradient(to right, #fb7185, #8b5cf6, #fb7185); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent;`;\n\n decorations.push(\n Decoration.inline(start, end, {\n class:\n \"italic animate-gradient bg-gradient-to-r from-rose-400 from-50% to-violet-500 to-50% bg-size-[200%_100%] bg-clip-text text-transparent inline-flex items-baseline gap-0.5\",\n style,\n }),\n );\n }\n\n // 3. Variable: {variableName}\n const varRegex = new RegExp(\n VARIABLE_REGEX.source,\n VARIABLE_REGEX.flags,\n );\n while ((match = varRegex.exec(text)) !== null) {\n const variableName = match[1].trim();\n const start = pos + match.index;\n const end = start + match[0].length;\n const isJsonVar = jsonVarSet?.has(variableName);\n\n decorations.push(\n Decoration.inline(start, end, {\n class: isJsonVar\n ? \"bg-violet-400/40 border-b-4 border-rose-300 dark:border-rose-800 inline-flex items-baseline px-1 py-0 text-foreground/80 gap-0.5 rounded-xs\"\n : \"bg-rose-400/40 border-b-4 border-violet-300 dark:border-violet-800 inline-flex items-baseline px-1 py-0 text-foreground/80 gap-0.5 rounded-xs\",\n \"data-variable\": variableName,\n }),\n );\n }\n }\n });\n\n return decorations;\n};\n\nexport const GradientText = Mark.create<GradientTextOptions>({\n name: \"gradientText\",\n\n addOptions() {\n return {\n templateColorMap: new Map(),\n speed: 1,\n jsonVariables: undefined,\n onTemplateClick: undefined,\n };\n },\n\n renderHTML({ HTMLAttributes }) {\n const defaultColors = {\n from: \"#ffaa40\",\n to: \"#9c40ff\",\n };\n const speed = this.options.speed ?? 1;\n const style = `--bg-size: ${speed * 300}%; --color-from: ${\n defaultColors.from\n }; --color-to: ${defaultColors.to}; caret-color: #111 !important;`;\n\n return [\n \"span\",\n {\n class:\n \"inline animate-gradient bg-gradient-to-r from-[var(--color-from)] via-[var(--color-to)] to-[var(--color-from)] bg-[length:var(--bg-size)_100%] bg-clip-text text-transparent\",\n style,\n ...HTMLAttributes,\n },\n 0,\n ];\n },\n\n parseHTML() {\n return [\n {\n tag: \"span\",\n getAttrs: (node) =>\n (node as HTMLElement).classList.contains(\"animate-gradient\") &&\n (node as HTMLElement).classList.contains(\"bg-clip-text\") &&\n null,\n },\n ];\n },\n\n addProseMirrorPlugins() {\n const markOptions = this.options;\n\n return [\n new Plugin({\n state: {\n init(_, { doc }) {\n return DecorationSet.create(\n doc,\n createGradientDecorations(doc, markOptions),\n );\n },\n apply(tr, value: DecorationSet) {\n const newDoc = tr.doc;\n if (tr.docChanged) {\n return DecorationSet.create(\n newDoc,\n createGradientDecorations(newDoc, markOptions),\n );\n }\n return value.map(tr.mapping, newDoc);\n },\n },\n props: {\n decorations(state: EditorState) {\n return (this as any).getState(state) as DecorationSet;\n },\n handleClickOn(view, pos, _node, _nodePos, event) {\n const decorationSet = (this as any).getState(\n view.state,\n ) as DecorationSet;\n const decorations = decorationSet.find(pos, pos + 1);\n\n for (const decoration of decorations) {\n const decorationWithAttrs = decoration as any;\n const templateName =\n decorationWithAttrs.type?.attrs?.[\"data-template\"];\n if (templateName) {\n if (markOptions.onTemplateClick) {\n markOptions.onTemplateClick(templateName, event as MouseEvent);\n }\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(\n new CustomEvent(\"show-gradient-popover\", {\n detail: {\n templateName,\n target: event.target,\n },\n }),\n );\n }\n return true;\n }\n }\n return false;\n },\n },\n }),\n ];\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport { Plugin } from \"@tiptap/pm/state\";\n\nexport interface SlashCommandMatchData {\n match: RegExpMatchArray;\n query: string;\n from: number;\n to: number;\n coords: { top: number; left: number; bottom: number; right: number };\n}\n\nexport interface SlashCommandsOptions {\n trigger?: string;\n onMatch?: (data: SlashCommandMatchData) => void;\n onClear?: () => void;\n containerId?: string;\n}\n\nexport const SlashCommands = Extension.create<SlashCommandsOptions>({\n name: \"slashCommands\",\n\n addOptions() {\n return {\n trigger: \"/\",\n onMatch: undefined,\n onClear: undefined,\n containerId: undefined,\n };\n },\n\n addProseMirrorPlugins() {\n const opts = this.options;\n\n return [\n new Plugin({\n view() {\n return {\n update(view) {\n const { state } = view;\n const { selection } = state;\n const { $from } = selection;\n\n if (!$from.parent.isTextblock) {\n opts.onClear?.();\n return;\n }\n\n const textBeforeCursor = $from.parent.textBetween(\n 0,\n $from.parentOffset,\n );\n\n const slashMatch = textBeforeCursor.match(\n /(?:^|\\s)\\/([a-zA-Z0-9_-]*)$/,\n );\n\n if (slashMatch) {\n const matchIndex = slashMatch.index ?? 0;\n const offsetInParent =\n matchIndex + (slashMatch[0].startsWith(\" \") ? 1 : 0);\n const matchFrom = $from.start() + offsetInParent;\n const matchTo = $from.pos;\n const coords = view.coordsAtPos($from.pos);\n\n let relativeCoords = {\n top: coords.top,\n left: coords.left,\n bottom: coords.bottom,\n right: coords.right,\n };\n\n if (opts.containerId && typeof document !== \"undefined\") {\n const container = document.getElementById(opts.containerId);\n if (container) {\n const rect = container.getBoundingClientRect();\n relativeCoords = {\n top: coords.bottom - rect.top + 5,\n left: coords.left - rect.left,\n bottom: coords.bottom - rect.top,\n right: coords.right - rect.left,\n };\n }\n }\n\n opts.onMatch?.({\n match: slashMatch,\n query: slashMatch[1] || \"\",\n from: matchFrom,\n to: matchTo,\n coords: relativeCoords,\n });\n } else {\n opts.onClear?.();\n }\n },\n };\n },\n }),\n ];\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport Suggestion, { SuggestionOptions } from \"@tiptap/suggestion\";\nimport { Template } from \"../grammar/tokens\";\n\nexport interface TemplateSuggestionsOptions {\n templates: Template[];\n char?: string;\n onSuggestion?: (props: {\n query: string;\n range: { from: number; to: number };\n clientRect?: (() => DOMRect | null) | null;\n items: Template[];\n command: (props: { name: string }) => void;\n }) => void;\n}\n\nexport const TemplateSuggestions = Extension.create<TemplateSuggestionsOptions>({\n name: \"templateSuggestions\",\n\n addOptions() {\n return {\n templates: [],\n char: \"{{\",\n onSuggestion: undefined,\n };\n },\n\n addProseMirrorPlugins() {\n const opts = this.options;\n\n const suggestionConfig: Omit<SuggestionOptions<Template>, \"editor\"> = {\n char: opts.char || \"{{\",\n items: ({ query }) => {\n const lower = query.toLowerCase();\n return (opts.templates || []).filter((t) =>\n t.name.toLowerCase().includes(lower),\n );\n },\n command: ({ editor, range, props }) => {\n editor\n .chain()\n .focus()\n .deleteRange(range)\n .insertContent(`{{${props.name}}}`)\n .run();\n },\n render: () => {\n return {\n onStart: (props) => {\n opts.onSuggestion?.(props as any);\n },\n onUpdate: (props) => {\n opts.onSuggestion?.(props as any);\n },\n onExit: () => {\n opts.onSuggestion?.({\n query: \"\",\n range: { from: 0, to: 0 },\n items: [],\n command: () => {},\n });\n },\n };\n },\n };\n\n const SuggestionFn =\n typeof Suggestion === \"function\"\n ? Suggestion\n : (Suggestion as any)?.default || (Suggestion as any)?.Suggestion;\n\n return [\n SuggestionFn({\n editor: this.editor,\n ...suggestionConfig,\n }),\n ];\n },\n});\n","import { Node, mergeAttributes } from \"@tiptap/core\";\n\nexport const LoadingNode = Node.create({\n name: \"loadingNode\",\n group: \"inline\",\n inline: true,\n selectable: true,\n atom: true,\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-id\"),\n renderHTML: (attributes) => {\n if (!attributes.id) return {};\n return { \"data-id\": attributes.id };\n },\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'span[data-type=\"loading\"]',\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-type\": \"loading\",\n class: \"inline-flex items-center px-1.5 py-0.5 text-xs text-muted-foreground animate-pulse\",\n }),\n \"⏳\",\n ];\n },\n});\n","import { Extension, textInputRule } from \"@tiptap/core\";\n\nexport const SmilieReplacer = Extension.create({\n name: \"smilieReplacer\",\n\n addInputRules() {\n return [\n textInputRule({ find: /-___- $/, replace: \"😑 \" }),\n textInputRule({ find: /:'-\\) $/, replace: \"😂 \" }),\n textInputRule({ find: /':-\\) $/, replace: \"😅 \" }),\n textInputRule({ find: /':-D $/, replace: \"😅 \" }),\n textInputRule({ find: />:-\\) $/, replace: \"😆 \" }),\n textInputRule({ find: /-__- $/, replace: \"😑 \" }),\n textInputRule({ find: /':-\\( $/, replace: \"😓 \" }),\n textInputRule({ find: /:'-\\( $/, replace: \"😢 \" }),\n textInputRule({ find: />:-\\( $/, replace: \"😠 \" }),\n textInputRule({ find: /O:-\\) $/, replace: \"😇 \" }),\n textInputRule({ find: /:'\\) $/, replace: \"😂 \" }),\n textInputRule({ find: /:-D $/, replace: \"😃 \" }),\n textInputRule({ find: /':\\) $/, replace: \"😅 \" }),\n textInputRule({ find: /;-\\) $/, replace: \"😉 \" }),\n textInputRule({ find: /B-\\) $/, replace: \"😎 \" }),\n textInputRule({ find: /:-\\* $/, replace: \"😘 \" }),\n textInputRule({ find: /:-\\) $/, replace: \"🙂 \" }),\n textInputRule({ find: /-_- $/, replace: \"😑 \" }),\n textInputRule({ find: /:-O $/, replace: \"😮 \" }),\n textInputRule({ find: /:-P $/, replace: \"😛 \" }),\n textInputRule({ find: /:-p $/, replace: \"😛 \" }),\n textInputRule({ find: /:-\\/ $/, replace: \"😕 \" }),\n textInputRule({ find: /:-\\( $/, replace: \"😞 \" }),\n textInputRule({ find: /:'\\( $/, replace: \"😢 \" }),\n textInputRule({ find: /:D $/, replace: \"😃 \" }),\n textInputRule({ find: /=D $/, replace: \"😃 \" }),\n textInputRule({ find: /;\\) $/, replace: \"😉 \" }),\n textInputRule({ find: /B\\) $/, replace: \"😎 \" }),\n textInputRule({ find: /:\\) $/, replace: \"🙂 \" }),\n textInputRule({ find: /=\\) $/, replace: \"🙂 \" }),\n textInputRule({ find: /:O $/, replace: \"😮 \" }),\n textInputRule({ find: /:P $/, replace: \"😛 \" }),\n textInputRule({ find: /:p $/, replace: \"😛 \" }),\n textInputRule({ find: /:\\/ $/, replace: \"😕 \" }),\n textInputRule({ find: /:\\( $/, replace: \"😞 \" }),\n textInputRule({ find: /<3 $/, replace: \"❤️ \" }),\n textInputRule({ find: /<\\/3 $/, replace: \"💔 \" }),\n textInputRule({ find: /\\/shrug $/, replace: \"¯\\\\_(ツ)_/¯ \" }),\n ];\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport { Plugin } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport type { Node as ProsemirrorNode } from \"@tiptap/pm/model\";\n\nexport function findHexColors(doc: ProsemirrorNode): DecorationSet {\n const hexColorRegex = /(#[0-9a-fA-F]{3,8})\\b/g;\n const decorations: Decoration[] = [];\n\n doc.descendants((node, position) => {\n if (!node.text) return;\n\n let match: RegExpExecArray | null;\n while ((match = hexColorRegex.exec(node.text)) !== null) {\n const color = match[0];\n const from = position + match.index;\n const to = from + color.length;\n\n decorations.push(\n Decoration.inline(from, to, {\n class: \"color-highlight px-1 py-0.5 rounded text-xs font-mono border\",\n style: `--color: ${color}; background-color: ${color}20; border-color: ${color}; color: ${color};`,\n }),\n );\n }\n });\n\n return DecorationSet.create(doc, decorations);\n}\n\nexport const ColorHighlighter = Extension.create({\n name: \"colorHighlighter\",\n\n addProseMirrorPlugins() {\n return [\n new Plugin({\n state: {\n init(_, { doc }) {\n return findHexColors(doc);\n },\n apply(transaction, oldState) {\n return transaction.docChanged ? findHexColors(transaction.doc) : oldState;\n },\n },\n props: {\n decorations(state) {\n return (this as any).getState(state);\n },\n },\n }),\n ];\n },\n});\n","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 {\n types: [\"textStyle\"],\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n fontSize: {\n default: null,\n parseHTML: (element) =>\n element.style.fontSize.replace(/['\"]+/g, \"\"),\n renderHTML: (attributes) => {\n if (!attributes.fontSize) {\n return {};\n }\n return {\n style: `font-size: ${attributes.fontSize}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setFontSize:\n (fontSize: string) =>\n ({ chain }) =>\n chain().setMark(\"textStyle\", { fontSize }).run(),\n unsetFontSize:\n () =>\n ({ chain }) =>\n chain()\n .setMark(\"textStyle\", { fontSize: null })\n .removeEmptyTextStyle()\n .run(),\n };\n },\n});\n\nexport default FontSize;\n","import {\n wrappingInputRule,\n markInputRule,\n type Extensions,\n} from \"@tiptap/core\";\nimport * as _StarterKit from \"@tiptap/starter-kit\";\nimport * as _Color from \"@tiptap/extension-color\";\nimport * as _Highlight from \"@tiptap/extension-highlight\";\nimport * as _Link from \"@tiptap/extension-link\";\nimport * as _TaskList from \"@tiptap/extension-task-list\";\nimport * as _TaskItem from \"@tiptap/extension-task-item\";\nimport * as _TextAlign from \"@tiptap/extension-text-align\";\nimport * as _TextStyle from \"@tiptap/extension-text-style\";\nimport * as _Typography from \"@tiptap/extension-typography\";\nimport * as _Underline from \"@tiptap/extension-underline\";\nimport * as _Placeholder from \"@tiptap/extension-placeholder\";\nimport * as _CharacterCount from \"@tiptap/extension-character-count\";\n\nconst resolveExt = (mod: any, name: string) =>\n mod?.[name] ||\n mod?.default?.[name] ||\n mod?.default?.default ||\n mod?.default ||\n mod;\n\nconst StarterKit = resolveExt(_StarterKit, \"StarterKit\");\nconst Color = resolveExt(_Color, \"Color\");\nconst Highlight = resolveExt(_Highlight, \"Highlight\");\nconst Link = resolveExt(_Link, \"Link\");\nconst TaskList = resolveExt(_TaskList, \"TaskList\");\nconst TaskItem = resolveExt(_TaskItem, \"TaskItem\");\nconst TextAlign = resolveExt(_TextAlign, \"TextAlign\");\nconst TextStyle = resolveExt(_TextStyle, \"TextStyle\");\nconst Typography = resolveExt(_Typography, \"Typography\");\nconst Underline = resolveExt(_Underline, \"Underline\");\nconst Placeholder = resolveExt(_Placeholder, \"Placeholder\");\nconst CharacterCount = resolveExt(_CharacterCount, \"CharacterCount\");\n\nimport { SmilieReplacer } from \"./SmilieReplacer\";\nimport { ColorHighlighter } from \"./ColorHighlighter\";\nimport { FontSize } from \"./FontSize\";\nimport { Mention, type MentionOptions } from \"./mention\";\nimport { Markdown, type MarkdownOptions } from \"./markdown\";\nimport { Image, type ImageOptions } from \"./image\";\n\nexport interface RichTextPresetOptions {\n placeholder?: string | ((props: { node: any }) => string);\n characterLimit?: number;\n openLinksOnClick?: boolean;\n enableSmilies?: boolean;\n enableColorHighlighter?: boolean;\n headingLevels?: (1 | 2 | 3 | 4 | 5 | 6)[];\n mention?: MentionOptions | boolean;\n markdown?: MarkdownOptions | boolean;\n image?: ImageOptions | boolean;\n}\n\n/**\n * Creates a standard rich-text extensions bundle with full formatting support.\n */\nexport function createRichTextPreset(\n options: RichTextPresetOptions = {},\n): Extensions {\n const {\n placeholder = \"Start typing...\",\n characterLimit,\n openLinksOnClick = false,\n enableSmilies = true,\n enableColorHighlighter = true,\n headingLevels = [1, 2, 3, 4],\n } = options;\n\n const extensions: Extensions = [\n StarterKit.configure({\n orderedList: {\n HTMLAttributes: {\n class: \"list-decimal pl-4\",\n },\n },\n bulletList: {\n HTMLAttributes: {\n class: \"list-disc pl-4\",\n },\n },\n heading: {\n levels: headingLevels,\n HTMLAttributes: {\n class: \"font-bold tracking-tight\",\n },\n },\n }),\n TextStyle,\n Color,\n Highlight.configure({ multicolor: true }),\n Underline,\n Typography,\n TextAlign.configure({\n types: [\"heading\", \"paragraph\"],\n }),\n Link.extend({\n addInputRules() {\n return [\n markInputRule({\n find: /(?:^|\\s)\\[([^\\]]+)\\]\\(([^)]+)\\)$/,\n type: this.type,\n getAttributes: (match) => ({\n href: match[2],\n }),\n }),\n ];\n },\n }).configure({\n openOnClick: openLinksOnClick,\n autolink: true,\n defaultProtocol: \"https\",\n protocols: [\"file\", \"vscode\", \"cursor\"],\n HTMLAttributes: {\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n class: \"text-blue-500 underline underline-offset-2\",\n },\n }),\n TaskList,\n TaskItem.extend({\n addInputRules() {\n return [\n wrappingInputRule({\n find: /^\\s*(\\[([ |x])?\\])\\s$/i,\n type: this.type,\n getAttributes: (match) => ({\n checked: match[2]?.toLowerCase() === \"x\",\n }),\n }),\n ];\n },\n }).configure({\n nested: true,\n }),\n FontSize,\n Placeholder.configure({\n emptyEditorClass: \"is-empty\",\n placeholder:\n typeof placeholder === \"function\" ? placeholder : () => placeholder,\n }),\n ];\n\n if (characterLimit) {\n extensions.push(\n CharacterCount.configure({\n limit: characterLimit,\n }),\n );\n }\n\n if (enableSmilies) {\n extensions.push(SmilieReplacer);\n }\n\n if (enableColorHighlighter) {\n extensions.push(ColorHighlighter);\n }\n\n if (options.mention) {\n const mentionConfig =\n typeof options.mention === \"object\" ? options.mention : {};\n extensions.push(\n Mention.configure({\n HTMLAttributes: {\n class: \"pixerate-mention-node\",\n ...(mentionConfig.HTMLAttributes || {}),\n },\n ...mentionConfig,\n }),\n );\n }\n\n if (options.markdown) {\n const markdownConfig =\n typeof options.markdown === \"object\" ? options.markdown : {};\n extensions.push(\n Markdown.configure({\n html: true,\n tightLists: true,\n tightListClass: \"tight\",\n bulletListMarker: \"-\",\n linkify: true,\n breaks: true,\n transformPastedText: true,\n transformCopiedText: true,\n ...markdownConfig,\n }),\n );\n }\n\n if (options.image !== false) {\n const imageConfig =\n typeof options.image === \"object\" ? options.image : {};\n extensions.push(\n Image.configure({\n HTMLAttributes: {\n class: \"rounded-md max-w-full h-auto my-2\",\n ...(imageConfig.HTMLAttributes || {}),\n },\n ...imageConfig,\n }),\n );\n }\n\n return extensions;\n}\n","import {\n Mention as TipTapMention,\n type MentionOptions as TipTapMentionOptions,\n} from \"@tiptap/extension-mention\";\nimport type { SuggestionOptions } from \"@tiptap/suggestion\";\n\nexport interface MentionEntity {\n id: string;\n label: string;\n type?: string;\n avatarUrl?: string;\n color?: string;\n handle?: string;\n name?: string;\n hexColor?: string;\n aliases?: string[];\n [key: string]: any;\n}\n\nexport interface MentionOptions extends Partial<TipTapMentionOptions> {\n HTMLAttributes?: Record<string, any>;\n suggestion?: Partial<SuggestionOptions<MentionEntity>>;\n}\n\nconst BaseMention =\n TipTapMention ||\n (TipTapMention as any)?.default?.default ||\n (TipTapMention as any)?.default ||\n (TipTapMention as any);\n\n/**\n * First-class native Mention extension for @pixerate/editor.\n * Creates atomic inline <span data-type=\"mention\"> nodes with full suggestion support.\n */\nexport const Mention = BaseMention.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n type: {\n default: null,\n parseHTML: (element: HTMLElement) =>\n element.getAttribute(\"data-type-name\") ||\n element.getAttribute(\"data-entity-type\"),\n renderHTML: (attributes: Record<string, any>) => {\n if (!attributes.type) return {};\n return { \"data-type-name\": attributes.type };\n },\n },\n avatarUrl: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute(\"data-avatar-url\"),\n renderHTML: (attributes: Record<string, any>) => {\n if (!attributes.avatarUrl) return {};\n return { \"data-avatar-url\": attributes.avatarUrl };\n },\n },\n color: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute(\"data-color\"),\n renderHTML: (attributes: Record<string, any>) => {\n if (!attributes.color) return {};\n return { \"data-color\": attributes.color };\n },\n },\n };\n },\n});\n\n/**\n * Helper to configure the Mention extension with preset defaults.\n */\nexport function createMentionExtension(options: Partial<MentionOptions> = {}) {\n const { HTMLAttributes = {}, ...rest } = options;\n return Mention.configure({\n HTMLAttributes: {\n class: \"pixerate-mention-node\",\n ...HTMLAttributes,\n },\n ...rest,\n });\n}\n","import { Extension } from \"@tiptap/core\";\n\nexport const MarkdownTightLists = Extension.create({\n name: 'markdownTightLists',\n addOptions: () => ({\n tight: true,\n tightClass: 'tight',\n listTypes: [\n 'bulletList',\n 'orderedList',\n ],\n }),\n addGlobalAttributes() {\n return [\n {\n types: this.options.listTypes,\n attributes: {\n tight: {\n default: this.options.tight,\n parseHTML: element =>\n element.getAttribute('data-tight') === 'true' || !element.querySelector('p'),\n renderHTML: attributes => ({\n class: attributes.tight ? this.options.tightClass : null,\n 'data-tight': attributes.tight ? 'true' : null,\n }),\n },\n },\n },\n ]\n },\n addCommands() {\n return {\n toggleTight: (tight = null) => ({ editor, commands }) => {\n function toggleTight(name) {\n if(!editor.isActive(name)) {\n return false;\n }\n const attrs = editor.getAttributes(name);\n return commands.updateAttributes(name, {\n tight: tight ?? !attrs?.tight,\n });\n }\n return this.options.listTypes\n .some(name => toggleTight(name));\n }\n }\n },\n});\n","import markdownit from 'markdown-it';\n\nconst md = markdownit();\n\nfunction scanDelims(text, pos) {\n md.inline.State.prototype.scanDelims.call({ src: text, posMax: text.length })\n const state = new (md.inline.State)(text, null, null, []);\n return state.scanDelims(pos, true);\n}\n\nexport function shiftDelim(text, delim, start, offset) {\n let res = text.substring(0, start) + text.substring(start + delim.length);\n res = res.substring(0, start + offset) + delim + res.substring(start + offset);\n return res;\n}\n\nfunction trimStart(text, delim, from, to) {\n let pos = from, res = text;\n while(pos < to) {\n if(scanDelims(res, pos).can_open) {\n break;\n }\n res = shiftDelim(res, delim, pos, 1);\n pos++;\n }\n return { text: res, from: pos, to }\n}\n\nfunction trimEnd(text, delim, from, to) {\n let pos = to, res = text;\n while(pos > from) {\n if(scanDelims(res, pos).can_close) {\n break;\n }\n res = shiftDelim(res, delim, pos, -1);\n pos--;\n }\n return { text: res, from, to: pos }\n}\n\nexport function trimInline(text, delim, from, to) {\n let state = {\n text,\n from,\n to,\n }\n\n state = trimStart(state.text, delim, state.from, state.to);\n state = trimEnd(state.text, delim, state.from, state.to);\n\n if(state.to - state.from < delim.length + 1) {\n state.text = state.text.substring(0, state.from) + state.text.substring(state.to + delim.length);\n }\n\n return state.text;\n}\n","import { MarkdownSerializerState as BaseMarkdownSerializerState } from \"prosemirror-markdown\";\nimport { trimInline } from \"../util/markdown\";\n\n\n/**\n * Override default MarkdownSerializerState to:\n * - handle commonmark delimiters (https://spec.commonmark.org/0.29/#left-flanking-delimiter-run)\n */\nexport class MarkdownSerializerState extends BaseMarkdownSerializerState {\n\n inTable = false;\n\n constructor(nodes, marks, options) {\n super(nodes, marks, options ?? {});\n this.inlines = [];\n }\n\n render(node, parent, index) {\n super.render(node, parent, index);\n const top = this.inlines[this.inlines.length - 1];\n if(top?.start && top?.end) {\n const { delimiter, start, end } = this.normalizeInline(top);\n this.out = trimInline(this.out, delimiter, start, end);\n this.inlines.pop();\n }\n }\n\n markString(mark, open, parent, index) {\n const info = this.marks[mark.type.name]\n if(info.expelEnclosingWhitespace) {\n if(open) {\n this.inlines.push({\n start: this.out.length,\n delimiter: info.open,\n });\n } else {\n const top = this.inlines.pop();\n this.inlines.push({\n ...top,\n end: this.out.length,\n });\n }\n }\n return super.markString(mark, open, parent, index);\n }\n\n normalizeInline(inline) {\n let { start, end } = inline;\n while(this.out.charAt(start).match(/\\s/)) {\n start++;\n }\n return {\n ...inline,\n start,\n }\n }\n}\n","import { Fragment } from \"@tiptap/pm/model\";\nimport { getHTMLFromFragment, Mark } from \"@tiptap/core\";\n\n\nexport default Mark.create({\n name: 'markdownHTMLMark',\n /**\n * @return {{markdown: MarkdownMarkSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: {\n open(state, mark) {\n if(!this.editor.storage.markdown.options.html) {\n console.warn(`Tiptap Markdown: \"${mark.type.name}\" mark is only available in html mode`);\n return '';\n }\n return getMarkTags(mark)?.[0] ?? '';\n },\n close(state, mark) {\n if(!this.editor.storage.markdown.options.html) {\n return '';\n }\n return getMarkTags(mark)?.[1] ?? '';\n },\n },\n parse: {\n // handled by markdown-it\n }\n }\n }\n }\n});\n\nfunction getMarkTags(mark) {\n const schema = mark.type.schema;\n const node = schema.text(' ', [mark]);\n const html = getHTMLFromFragment(Fragment.from(node), schema);\n const match = html.match(/^(<.*?>) (<\\/.*?>)$/);\n return match ? [match[1], match[2]] : null;\n}\n","\n\nexport function elementFromString(value) {\n // add a wrapper to preserve leading and trailing whitespace\n const wrappedValue = `<body>${value}</body>`\n\n return new window.DOMParser().parseFromString(wrappedValue, 'text/html').body\n}\n\nexport function escapeHTML(value) {\n return value\n ?.replace(/</g, '<')\n .replace(/>/g, '>');\n}\n\nexport function extractElement(node) {\n const parent = node.parentElement;\n const prepend = parent.cloneNode();\n\n while(parent.firstChild && parent.firstChild !== node) {\n prepend.appendChild(parent.firstChild);\n }\n\n if(prepend.childNodes.length > 0) {\n parent.parentElement.insertBefore(prepend, parent);\n }\n parent.parentElement.insertBefore(node, parent);\n if(parent.childNodes.length === 0) {\n parent.remove();\n }\n}\n\nexport function unwrapElement(node) {\n const parent = node.parentNode;\n\n while (node.firstChild) parent.insertBefore(node.firstChild, node);\n\n parent.removeChild(node);\n}\n","import { Fragment } from \"@tiptap/pm/model\";\nimport { getHTMLFromFragment, Node } from \"@tiptap/core\";\nimport { elementFromString } from \"../../util/dom\";\n\n\nexport default Node.create({\n name: 'markdownHTMLNode',\n addStorage() {\n return {\n markdown: {\n serialize(state, node, parent) {\n if(this.editor.storage.markdown.options.html) {\n state.write(serializeHTML(node, parent));\n } else {\n console.warn(`Tiptap Markdown: \"${node.type.name}\" node is only available in html mode`);\n state.write(`[${node.type.name}]`);\n }\n if(node.isBlock) {\n state.closeBlock(node);\n }\n },\n parse: {\n // handled by markdown-it\n },\n },\n }\n }\n});\n\nfunction serializeHTML(node, parent) {\n const schema = node.type.schema;\n const html = getHTMLFromFragment(Fragment.from(node), schema);\n\n if(node.isBlock && (parent instanceof Fragment || parent.type.name === schema.topNodeType.name)) {\n return formatBlock(html);\n }\n\n return html;\n}\n\n/**\n * format html block as per the commonmark spec\n */\nfunction formatBlock(html) {\n const dom = elementFromString(html);\n const element = dom.firstElementChild;\n\n element.innerHTML = element.innerHTML.trim()\n ? `\\n${element.innerHTML}\\n`\n : `\\n`;\n\n return element.outerHTML;\n}\n","import { Node } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Blockquote = Node.create({\n name: 'blockquote',\n});\n\nexport default Blockquote.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.nodes.blockquote,\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\n\n\nconst BulletList = Node.create({\n name: 'bulletList',\n});\n\nexport default BulletList.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize(state, node) {\n return state.renderList(node, \" \", () => (this.editor.storage.markdown.options.bulletListMarker || \"-\") + \" \");\n },\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\n\n\nconst CodeBlock = Node.create({\n name: 'codeBlock',\n});\n\nexport default CodeBlock.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize(state, node) {\n state.write(\"```\" + (node.attrs.language || \"\") + \"\\n\");\n state.text(node.textContent, false);\n state.ensureNewLine();\n state.write(\"```\");\n state.closeBlock(node);\n },\n parse: {\n setup(markdownit) {\n markdownit.set({\n langPrefix: this.options.languageClassPrefix ?? 'language-',\n });\n },\n updateDOM(element) {\n element.innerHTML = element.innerHTML.replace(/\\n<\\/code><\\/pre>/g, '</code></pre>')\n },\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\nimport HTMLNode from './html';\n\nconst HardBreak = Node.create({\n name: 'hardBreak',\n});\n\nexport default HardBreak.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize(state, node, parent, index) {\n for (let i = index + 1; i < parent.childCount; i++)\n if (parent.child(i).type != node.type) {\n state.write(\n state.inTable\n ? HTMLNode.storage.markdown.serialize.call(this, state, node, parent)\n : \"\\\\\\n\"\n );\n return;\n }\n },\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Heading = Node.create({\n name: 'heading',\n});\n\nexport default Heading.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.nodes.heading,\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst HorizontalRule = Node.create({\n name: 'horizontalRule',\n});\n\nexport default HorizontalRule.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.nodes.horizontal_rule,\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Image = Node.create({\n name: 'image',\n});\n\nexport default Image.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.nodes.image,\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst ListItem = Node.create({\n name: 'listItem',\n});\n\nexport default ListItem.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.nodes.list_item,\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\n\n\nconst OrderedList = Node.create({\n name: 'orderedList',\n});\n\nfunction findIndexOfAdjacentNode(node, parent, index) {\n let i = 0;\n for (; index - i > 0; i++) {\n if (parent.child(index - i - 1).type.name !== node.type.name) {\n break;\n }\n }\n return i;\n}\n\nexport default OrderedList.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize(state, node, parent, index) {\n const start = node.attrs.start || 1\n const maxW = String(start + node.childCount - 1).length\n const space = state.repeat(\" \", maxW + 2)\n const adjacentIndex = findIndexOfAdjacentNode(node, parent, index);\n const separator = adjacentIndex % 2 ? ') ' : '. ';\n state.renderList(node, space, i => {\n const nStr = String(start + i)\n return state.repeat(\" \", maxW - nStr.length) + nStr + separator;\n })\n },\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Paragraph = Node.create({\n name: 'paragraph',\n});\n\nexport default Paragraph.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.nodes.paragraph,\n parse: {\n // handled by markdown-it\n },\n },\n }\n }\n});\n","\n\nexport function childNodes(node) {\n return node?.content?.content ?? [];\n}\n","import { Node } from \"@tiptap/core\";\nimport { childNodes } from \"../../util/prosemirror\";\nimport HTMLNode from './html';\n\nconst Table = Node.create({\n name: 'table',\n});\n\nexport default Table.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize(state, node, parent) {\n if(!isMarkdownSerializable(node)) {\n HTMLNode.storage.markdown.serialize.call(this, state, node, parent);\n return;\n }\n state.inTable = true;\n node.forEach((row, p, i) => {\n state.write('| ');\n row.forEach((col, p, j) => {\n if(j) {\n state.write(' | ');\n }\n const cellContent = col.firstChild;\n if(cellContent.textContent.trim()) {\n state.renderInline(cellContent);\n }\n });\n state.write(' |')\n state.ensureNewLine();\n if(!i) {\n const delimiterRow = Array.from({length: row.childCount}).map(() => '---').join(' | ');\n state.write(`| ${delimiterRow} |`);\n state.ensureNewLine();\n }\n });\n state.closeBlock(node);\n state.inTable = false;\n },\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n})\n\n\nfunction hasSpan(node) {\n return node.attrs.colspan > 1 || node.attrs.rowspan > 1;\n}\n\nfunction isMarkdownSerializable(node) {\n const rows = childNodes(node);\n const firstRow = rows[0];\n const bodyRows = rows.slice(1);\n\n if(childNodes(firstRow).some(cell => cell.type.name !== 'tableHeader' || hasSpan(cell) || cell.childCount > 1)) {\n return false;\n }\n\n if(bodyRows.some(row =>\n childNodes(row).some(cell => cell.type.name === 'tableHeader' || hasSpan(cell) || cell.childCount > 1)\n )) {\n return false;\n }\n\n return true;\n}\n","import { Node } from \"@tiptap/core\";\n\n\nconst TaskItem = Node.create({\n name: 'taskItem',\n});\n\nexport default TaskItem.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize(state, node) {\n const check = node.attrs.checked ? '[x]' : '[ ]';\n state.write(`${check} `);\n state.renderContent(node);\n },\n parse: {\n updateDOM(element) {\n [...element.querySelectorAll('.task-list-item')]\n .forEach(item => {\n const input = item.querySelector('input');\n item.setAttribute('data-type', 'taskItem');\n if(input) {\n item.setAttribute('data-checked', input.checked);\n input.remove();\n }\n });\n },\n }\n }\n }\n }\n});\n","import taskListPlugin from \"markdown-it-task-lists\";\nimport { Node } from \"@tiptap/core\";\nimport BulletList from \"./bullet-list\";\n\n\nconst TaskList = Node.create({\n name: 'taskList',\n});\n\nexport default TaskList.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: BulletList.storage.markdown.serialize,\n parse: {\n setup(markdownit) {\n markdownit.use(taskListPlugin);\n },\n updateDOM(element) {\n [...element.querySelectorAll('.contains-task-list')]\n .forEach(list => {\n list.setAttribute('data-type', 'taskList');\n });\n },\n }\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\nimport { escapeHTML } from \"../../util/dom\";\n\n\nconst Text = Node.create({\n name: 'text',\n});\n\nexport default Text.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize(state, node) {\n state.text(escapeHTML(node.text));\n },\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Mark } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Bold = Mark.create({\n name: 'bold',\n});\n\nexport default Bold.extend({\n /**\n * @return {{markdown: MarkdownMarkSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.marks.strong,\n parse: {\n // handled by markdown-it\n }\n },\n }\n }\n});\n","import { Mark } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Code = Mark.create({\n name: 'code',\n});\n\nexport default Code.extend({\n /**\n * @return {{markdown: MarkdownMarkSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.marks.code,\n parse: {\n // handled by markdown-it\n }\n }\n }\n }\n})\n","import { Mark } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Italic = Mark.create({\n name: 'italic',\n});\n\nexport default Italic.extend({\n /**\n * @return {{markdown: MarkdownMarkSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.marks.em,\n parse: {\n // handled by markdown-it\n }\n }\n }\n }\n})\n","import { Mark } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Link = Mark.create({\n name: 'link',\n});\n\nexport default Link.extend({\n /**\n * @return {{markdown: MarkdownMarkSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.marks.link,\n parse: {\n // handled by markdown-it\n }\n }\n }\n }\n})\n","import { Mark } from \"@tiptap/core\";\n\n\nconst Strike = Mark.create({\n name: 'strike',\n});\n\nexport default Strike.extend({\n /**\n * @return {{markdown: MarkdownMarkSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: {open: '~~', close: '~~', expelEnclosingWhitespace: true},\n parse: {\n // handled by markdown-it\n },\n },\n }\n }\n});\n","import Blockquote from \"./nodes/blockquote\";\nimport BulletList from \"./nodes/bullet-list\";\nimport CodeBlock from \"./nodes/code-block\";\nimport HardBreak from \"./nodes/hard-break\";\nimport Heading from \"./nodes/heading\";\nimport HorizontalRule from \"./nodes/horizontal-rule\";\nimport HTMLNode from \"./nodes/html\";\nimport Image from \"./nodes/image\";\nimport ListItem from \"./nodes/list-item\";\nimport OrderedList from \"./nodes/ordered-list\";\nimport Paragraph from \"./nodes/paragraph\";\nimport Table from \"./nodes/table\";\nimport TaskItem from \"./nodes/task-item\";\nimport TaskList from \"./nodes/task-list\";\nimport Text from \"./nodes/text\";\n\nimport Bold from \"./marks/bold\";\nimport Code from \"./marks/code\";\nimport HTMLMark from \"./marks/html\";\nimport Italic from \"./marks/italic\";\nimport Link from \"./marks/link\";\nimport Strike from \"./marks/strike\";\n\n\nexport default [\n Blockquote,\n BulletList,\n CodeBlock,\n HardBreak,\n Heading,\n HorizontalRule,\n HTMLNode,\n Image,\n ListItem,\n OrderedList,\n Paragraph,\n Table,\n TaskItem,\n TaskList,\n Text,\n\n Bold,\n Code,\n HTMLMark,\n Italic,\n Link,\n Strike,\n]\n","import markdownExtensions from \"../extensions\";\n\n\nexport function getMarkdownSpec(extension) {\n const markdownSpec = extension.storage?.markdown;\n const defaultMarkdownSpec = markdownExtensions.find(e => e.name === extension.name)?.storage.markdown;\n\n if(markdownSpec || defaultMarkdownSpec) {\n return {\n ...defaultMarkdownSpec,\n ...markdownSpec,\n };\n }\n\n return null;\n}\n","import { MarkdownSerializerState } from './state';\nimport HTMLMark from \"../extensions/marks/html\";\nimport HTMLNode from \"../extensions/nodes/html\";\nimport { getMarkdownSpec } from \"../util/extensions\";\nimport HardBreak from \"../extensions/nodes/hard-break\";\n\n\nexport class MarkdownSerializer {\n /**\n * @type {import('@tiptap/core').Editor}\n */\n editor = null;\n\n constructor(editor) {\n this.editor = editor;\n }\n\n serialize(content) {\n const state = new MarkdownSerializerState(this.nodes, this.marks, {\n hardBreakNodeName: HardBreak.name,\n });\n\n state.renderContent(content);\n\n return state.out;\n }\n\n get nodes() {\n return {\n ...Object.fromEntries(\n Object.keys(this.editor.schema.nodes)\n .map(name => [name, this.serializeNode(HTMLNode)])\n ),\n ...Object.fromEntries(\n this.editor.extensionManager.extensions\n .filter(extension => extension.type === 'node' && this.serializeNode(extension))\n .map(extension => [extension.name, this.serializeNode(extension)])\n ?? []\n ),\n };\n }\n\n get marks() {\n return {\n ...Object.fromEntries(\n Object.keys(this.editor.schema.marks)\n .map(name => [name, this.serializeMark(HTMLMark)])\n ),\n ...Object.fromEntries(\n this.editor.extensionManager.extensions\n .filter(extension => extension.type === 'mark' && this.serializeMark(extension))\n .map(extension => [extension.name, this.serializeMark(extension)])\n ?? []\n ),\n };\n }\n\n serializeNode(node) {\n return getMarkdownSpec(node)?.serialize?.bind({ editor: this.editor, options: node.options });\n }\n\n serializeMark(mark) {\n const serialize = getMarkdownSpec(mark)?.serialize;\n return serialize\n ? {\n ...serialize,\n open: typeof serialize.open === 'function' ? serialize.open.bind({ editor: this.editor, options: mark.options }) : serialize.open,\n close: typeof serialize.close === 'function' ? serialize.close.bind({ editor: this.editor, options: mark.options }) : serialize.close,\n }\n : null\n }\n}\n\n","import markdownit from \"markdown-it\";\nimport { elementFromString, extractElement, unwrapElement } from \"../util/dom\";\nimport { getMarkdownSpec } from \"../util/extensions\";\n\nexport class MarkdownParser {\n /**\n * @type {import('@tiptap/core').Editor}\n */\n editor = null;\n /**\n * @type {markdownit}\n */\n md = null;\n\n constructor(editor, { html, linkify, breaks }) {\n this.editor = editor;\n this.md = this.withPatchedRenderer(markdownit({\n html,\n linkify,\n breaks,\n }));\n }\n\n parse(content, { inline } = {}) {\n if(typeof content === 'string') {\n this.editor.extensionManager.extensions.forEach(extension =>\n getMarkdownSpec(extension)?.parse?.setup?.call({ editor:this.editor, options:extension.options }, this.md)\n );\n\n const renderedHTML = this.md.render(content);\n const element = elementFromString(renderedHTML);\n\n this.editor.extensionManager.extensions.forEach(extension =>\n getMarkdownSpec(extension)?.parse?.updateDOM?.call({ editor:this.editor, options:extension.options }, element)\n );\n\n this.normalizeDOM(element, { inline, content });\n\n return element.innerHTML;\n }\n\n return content;\n }\n\n normalizeDOM(node, { inline, content }) {\n this.normalizeBlocks(node);\n\n // remove all \\n appended by markdown-it\n node.querySelectorAll('*').forEach(el => {\n if(el.nextSibling?.nodeType === Node.TEXT_NODE && !el.closest('pre')) {\n el.nextSibling.textContent = el.nextSibling.textContent.replace(/^\\n/, '');\n }\n });\n\n if(inline) {\n this.normalizeInline(node, content);\n }\n\n return node;\n }\n\n normalizeBlocks(node) {\n const blocks = Object.values(this.editor.schema.nodes)\n .filter(node => node.isBlock);\n\n const selector = blocks\n .map(block => block.spec.parseDOM?.map(spec => spec.tag))\n .flat()\n .filter(Boolean)\n .join(',');\n\n if(!selector) {\n return;\n }\n\n [...node.querySelectorAll(selector)].forEach(el => {\n if(el.parentElement.matches('p')) {\n extractElement(el);\n }\n });\n }\n\n normalizeInline(node, content) {\n if(node.firstElementChild?.matches('p')) {\n const firstParagraph = node.firstElementChild;\n const { nextElementSibling } = firstParagraph;\n const startSpaces = content.match(/^\\s+/)?.[0] ?? '';\n const endSpaces = !nextElementSibling\n ? content.match(/\\s+$/)?.[0] ?? ''\n : '';\n\n if(content.match(/^\\n\\n/)) {\n firstParagraph.innerHTML = `${firstParagraph.innerHTML}${endSpaces}`;\n return;\n }\n\n unwrapElement(firstParagraph);\n\n node.innerHTML = `${startSpaces}${node.innerHTML}${endSpaces}`;\n }\n }\n\n /**\n * @param {markdownit} md\n */\n withPatchedRenderer(md) {\n const withoutNewLine = (renderer) => (...args) => {\n const rendered = renderer(...args);\n if(rendered === '\\n') {\n return rendered; // keep soft breaks\n }\n if(rendered[rendered.length - 1] === '\\n') {\n return rendered.slice(0, -1);\n }\n return rendered;\n }\n\n md.renderer.rules.hardbreak = withoutNewLine(md.renderer.rules.hardbreak);\n md.renderer.rules.softbreak = withoutNewLine(md.renderer.rules.softbreak);\n md.renderer.rules.fence = withoutNewLine(md.renderer.rules.fence);\n md.renderer.rules.code_block = withoutNewLine(md.renderer.rules.code_block);\n md.renderer.renderToken = withoutNewLine(md.renderer.renderToken.bind(md.renderer));\n\n return md;\n }\n}\n\n","import { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\nimport { DOMParser } from '@tiptap/pm/model';\nimport { elementFromString } from \"../../util/dom\";\n\nexport const MarkdownClipboard = Extension.create({\n name: 'markdownClipboard',\n addOptions() {\n return {\n transformPastedText: false,\n transformCopiedText: false,\n }\n },\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: new PluginKey('markdownClipboard'),\n props: {\n clipboardTextParser: (text, context, plainText) => {\n if(plainText || !this.options.transformPastedText) {\n return null; // pasting with shift key prevents formatting\n }\n const parsed = this.editor.storage.markdown.parser.parse(text, { inline: true });\n return DOMParser.fromSchema(this.editor.schema)\n .parseSlice(elementFromString(parsed), {\n preserveWhitespace: true,\n context,\n });\n },\n /**\n * @param {import('prosemirror-model').Slice} slice\n */\n clipboardTextSerializer: (slice) => {\n if(!this.options.transformCopiedText) {\n return null;\n }\n return this.editor.storage.markdown.serializer.serialize(slice.content);\n },\n },\n })\n ]\n }\n})\n","import { Extension, extensions } from '@tiptap/core';\nimport { MarkdownTightLists } from \"./extensions/tiptap/tight-lists\";\nimport { MarkdownSerializer } from \"./serialize/MarkdownSerializer\";\nimport { MarkdownParser } from \"./parse/MarkdownParser\";\nimport { MarkdownClipboard } from \"./extensions/tiptap/clipboard\";\n\nexport const Markdown = Extension.create({\n name: 'markdown',\n priority: 50,\n addOptions() {\n return {\n html: true,\n tightLists: true,\n tightListClass: 'tight',\n bulletListMarker: '-',\n linkify: false,\n breaks: false,\n transformPastedText: false,\n transformCopiedText: false,\n }\n },\n addCommands() {\n const commands = extensions.Commands.config.addCommands();\n return {\n setContent: (content, emitUpdate, parseOptions) => (props) => {\n return commands.setContent(\n props.editor.storage.markdown.parser.parse(content),\n emitUpdate,\n parseOptions\n )(props);\n },\n insertContentAt: (range, content, options) => (props) => {\n return commands.insertContentAt(\n range,\n props.editor.storage.markdown.parser.parse(content, { inline: true }),\n options\n )(props);\n },\n }\n },\n onBeforeCreate() {\n this.editor.storage.markdown = {\n options: { ...this.options },\n parser: new MarkdownParser(this.editor, this.options),\n serializer: new MarkdownSerializer(this.editor),\n getMarkdown: () => {\n return this.editor.storage.markdown.serializer.serialize(this.editor.state.doc);\n },\n }\n this.editor.options.initialContent = this.editor.options.content;\n this.editor.options.content = this.editor.storage.markdown.parser.parse(this.editor.options.content);\n },\n onCreate() {\n this.editor.options.content = this.editor.options.initialContent;\n delete this.editor.options.initialContent;\n },\n addStorage() {\n return {\n /// storage will be defined in onBeforeCreate() to prevent initial object overriding\n }\n },\n addExtensions() {\n return [\n MarkdownTightLists.configure({\n tight: this.options.tightLists,\n tightClass: this.options.tightListClass,\n }),\n MarkdownClipboard.configure({\n transformPastedText: this.options.transformPastedText,\n transformCopiedText: this.options.transformCopiedText,\n }),\n ]\n },\n});\n","import {\n Markdown as TipTapMarkdown,\n type MarkdownOptions as TipTapMarkdownOptions,\n} from \"tiptap-markdown\";\n\nconst resolveExt = (mod: any, name: string) =>\n mod?.[name] ||\n mod?.default?.[name] ||\n mod?.default?.default ||\n mod?.default ||\n mod;\n\n/**\n * Built-in native Markdown extension for @pixerate/editor based on tiptap-markdown.\n * Enables automatic markdown parsing, serialization, and clipboard handling.\n */\nexport const Markdown = resolveExt(TipTapMarkdown, \"Markdown\");\n\nexport type { TipTapMarkdownOptions as MarkdownOptions };\n","import * as _Image from \"@tiptap/extension-image\";\nimport type { ImageOptions as TipTapImageOptions } from \"@tiptap/extension-image\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\n\nconst resolveExt = (mod: any, name: string) =>\n mod?.[name] ||\n mod?.default?.[name] ||\n mod?.default?.default ||\n mod?.default ||\n mod;\n\nconst BaseImage = resolveExt(_Image, \"Image\");\n\nexport interface ImageOptions extends Partial<TipTapImageOptions> {\n /**\n * Custom upload handler called when an image is pasted or dropped.\n * Resolves to the uploaded image URL string.\n */\n upload?: (file: File) => Promise<string> | string;\n\n /**\n * Callback invoked if the upload handler throws or rejects, or if an image\n * exceeds maxBase64Size when no upload handler is configured.\n */\n onUploadError?: (error: Error, file: File) => void;\n\n /**\n * Maximum allowed file size (in bytes) when embedding images as base64 data URLs\n * without an upload handler. Defaults to 65536 (64 KB).\n * Files larger than this will be rejected to avoid memory bloat and prompt/stream saturation.\n */\n maxBase64Size?: number;\n\n /**\n * Whether to enable automatic image pasting from clipboard. Defaults to true.\n */\n enablePaste?: boolean;\n\n /**\n * Whether to enable automatic image drop. Defaults to true.\n */\n enableDrop?: boolean;\n}\n\nexport const imagePastePluginKey = new PluginKey(\"imagePasteHandler\");\n\n/**\n * Inserts an image node into the editor view at the current selection.\n */\nexport function insertImageNode(view: any, src: string, alt?: string) {\n const { schema } = view.state;\n const imageType = schema.nodes.image;\n if (!imageType) return;\n const node = imageType.create({ src, alt: alt || \"\" });\n const tr = view.state.tr.replaceSelectionWith(node);\n view.dispatch(tr);\n}\n\n/**\n * Updates an existing image node's src attribute across document positions.\n */\nexport function updateImageSrc(view: any, oldSrc: string, newSrc: string) {\n const { doc } = view.state;\n let foundPos: number | null = null;\n let foundAttrs: any = null;\n\n doc.descendants((node: any, pos: number) => {\n if (node.type.name === \"image\" && node.attrs.src === oldSrc) {\n foundPos = pos;\n foundAttrs = node.attrs;\n return false;\n }\n });\n\n if (foundPos !== null && foundAttrs) {\n const tr = view.state.tr.setNodeMarkup(foundPos, undefined, {\n ...foundAttrs,\n src: newSrc,\n });\n view.dispatch(tr);\n }\n}\n\n/**\n * Removes an existing image node matching src attribute across document positions.\n */\nexport function removeImageNode(view: any, src: string) {\n const { doc } = view.state;\n let foundPos: number | null = null;\n let nodeSize = 0;\n\n doc.descendants((node: any, pos: number) => {\n if (node.type.name === \"image\" && node.attrs.src === src) {\n foundPos = pos;\n nodeSize = node.nodeSize;\n return false;\n }\n });\n\n if (foundPos !== null) {\n const tr = view.state.tr.delete(foundPos, foundPos + nodeSize);\n view.dispatch(tr);\n }\n}\n\n/**\n * Handles inserting a pasted or dropped image file, supporting both async upload\n * handlers and direct base64/object-URL fallbacks.\n */\nexport function handleImageInsertion(\n view: any,\n file: File,\n options: ImageOptions,\n) {\n if (typeof options.upload === \"function\") {\n // Generate temporary preview URL if browser supports object URLs\n const hasObjectUrl =\n typeof URL !== \"undefined\" && typeof URL.createObjectURL === \"function\";\n const tempUrl = hasObjectUrl ? URL.createObjectURL(file) : null;\n\n if (tempUrl) {\n insertImageNode(view, tempUrl, file.name);\n }\n\n Promise.resolve(options.upload(file))\n .then((uploadedUrl) => {\n if (!uploadedUrl) {\n throw new Error(\"Upload handler returned empty URL\");\n }\n if (tempUrl) {\n updateImageSrc(view, tempUrl, uploadedUrl);\n if (typeof URL.revokeObjectURL === \"function\") {\n URL.revokeObjectURL(tempUrl);\n }\n } else {\n insertImageNode(view, uploadedUrl, file.name);\n }\n })\n .catch((err) => {\n const error = err instanceof Error ? err : new Error(String(err));\n console.error(\"Failed to upload pasted image:\", error);\n if (tempUrl) {\n removeImageNode(view, tempUrl);\n if (typeof URL.revokeObjectURL === \"function\") {\n URL.revokeObjectURL(tempUrl);\n }\n }\n if (typeof options.onUploadError === \"function\") {\n options.onUploadError(error, file);\n }\n });\n } else if (options.allowBase64 !== false) {\n const maxBase64Size = options.maxBase64Size ?? 65536; // 64KB default\n if (file.size > maxBase64Size) {\n const err = new Error(\n `Image size (${Math.round(file.size / 1024)}KB) exceeds maxBase64Size (${Math.round(\n maxBase64Size / 1024,\n )}KB). Provide an upload handler to support large images.`,\n );\n console.warn(`[Editor] ${err.message}`);\n if (typeof options.onUploadError === \"function\") {\n options.onUploadError(err, file);\n }\n return;\n }\n\n if (typeof FileReader !== \"undefined\") {\n const reader = new FileReader();\n reader.onload = () => {\n const src = reader.result as string;\n if (src) {\n insertImageNode(view, src, file.name);\n }\n };\n reader.readAsDataURL(file);\n }\n }\n}\n\nexport const Image = BaseImage.extend({\n addOptions() {\n return {\n ...this.parent?.(),\n allowBase64: true,\n maxBase64Size: 65536,\n enablePaste: true,\n enableDrop: true,\n upload: undefined,\n onUploadError: undefined,\n HTMLAttributes: {\n class: \"rounded-md max-w-full h-auto my-2\",\n },\n };\n },\n\n addProseMirrorPlugins() {\n const parentPlugins = this.parent?.() || [];\n const options = this.options as ImageOptions;\n\n if (!options.enablePaste && !options.enableDrop) {\n return parentPlugins;\n }\n\n const pastePlugin = new Plugin({\n key: imagePastePluginKey,\n props: {\n handlePaste(view, event) {\n if (!options.enablePaste) return false;\n const items = Array.from(event.clipboardData?.items || []);\n const imageItems = items.filter(\n (item) => item.kind === \"file\" && item.type.startsWith(\"image/\"),\n );\n if (imageItems.length === 0) return false;\n\n event.preventDefault();\n\n for (const item of imageItems) {\n const file = item.getAsFile();\n if (!file) continue;\n handleImageInsertion(view, file, options);\n }\n return true;\n },\n handleDrop(view, event) {\n if (!options.enableDrop) return false;\n const files = Array.from(event.dataTransfer?.files || []);\n const imageFiles = files.filter((f) => f.type.startsWith(\"image/\"));\n if (imageFiles.length === 0) return false;\n\n event.preventDefault();\n\n for (const file of imageFiles) {\n handleImageInsertion(view, file, options);\n }\n return true;\n },\n },\n });\n\n return [...parentPlugins, pastePlugin];\n },\n});\n","import { escapeHtml } from \"./plain-text\";\nimport type { MentionEntity } from \"../extensions/mention\";\n\n/**\n * Canonical regex pattern for matching @mentions in plain text or markdown.\n * Supports:\n * - Standard unquoted handles: @username, @user.name, @team_alpha, @sa-1\n * - Quoted handles: @\"John Doe\", "Jane Doe"\n * Unquoted handles exclude trailing punctuation (e.g. @violet. matches \"violet\" without the dot).\n */\nexport const MENTION_REGEX =\n /(?:^|[\\s>(*_\"';\\\\/[\\]{}~`:]|"|>|<|&)@(?:\"([^\"]+)\"|"([^&]+)"|([a-zA-Z0-9_-]+(?:\\.[a-zA-Z0-9_-]+)*))/g;\n\n/**\n * Split regex identifying markdown code blocks, inline code, URLs, and existing HTML tags.\n * Used by preprocessMarkdownMentions to ensure non-mention regions remain completely untouched.\n */\nexport const MARKDOWN_MENTION_SPLIT_REGEX =\n /(```[\\s\\S]*?```|~~~[\\s\\S]*?~~~|<pre[\\s\\S]*?<\\/pre>|<code[\\s\\S]*?<\\/code>|`[^`\\n]+`|<span\\b[^>]*\\b(?:data-type=[\"']mention[\"']|class=[\"'][^\"']*pixerate-mention-node[^\"']*[\"']|data-mention=[\"'][^\"']*[\"'])[^>]*>[\\s\\S]*?<\\/span>|<[^>]+>|\\]\\([^)]+\\)|(?:https?|file|vscode|cursor|mailto):\\/\\/[^\\s<)]+)/gi;\n\nexport interface MentionSegment {\n type: \"text\" | \"mention\";\n value: string;\n handle?: string;\n}\n\nexport interface PreprocessMarkdownMentionsOptions {\n /**\n * Known pool of mentionable entities (users, agents, teams, etc.).\n */\n mentionables?: MentionEntity[];\n /**\n * Default entity type assigned when a handle does not match any entry in mentionables.\n * Defaults to 'user'.\n */\n defaultType?: string;\n /**\n * Custom resolver callback to derive entity metadata for unmatched handles.\n */\n resolveMention?: (handle: string) => Partial<MentionEntity> | null | undefined;\n}\n\n/**\n * Strips code blocks and inline code from markdown or HTML content:\n * - Fenced code blocks: ```...``` and ~~~...~~~\n * - Inline backtick code: `...`\n * - HTML code/pre tags: <pre>...</pre>, <code>...</code>\n * Used to avoid false-positive mention parsing and keyword analysis within code snippets, terminal logs, or stack traces.\n */\nexport function stripMarkdownCode(content: string): string {\n if (!content || typeof content !== \"string\") return \"\";\n return content\n .replace(/```[\\s\\S]*?```/g, \"\")\n .replace(/~~~[\\s\\S]*?~~~/g, \"\")\n .replace(/<pre[\\s\\S]*?<\\/pre>/gi, \"\")\n .replace(/<code[\\s\\S]*?<\\/code>/gi, \"\")\n .replace(/`[^`\\n]*`/g, \"\");\n}\n\n/**\n * Extracts unique mention handles from a text, markdown, or HTML string,\n * ignoring trailing punctuation, code blocks, URLs, and pre-existing HTML mention attributes.\n */\nexport function extractMentions(content: string): string[] {\n if (!content || typeof content !== \"string\") return [];\n\n // Normalize existing HTML mention nodes (e.g. from TipTap or rich text serializers)\n // so data-mention-suggestion-char=\"@\" does not trigger spurious quoted matches against attributes,\n // and ensure the actual mentioned label or ID is preserved cleanly.\n const normalizedMentionNodes = content.replace(\n /<span\\b[^>]*\\b(?:data-type=[\"']mention[\"']|class=[\"'][^\"']*pixerate-mention-node[^\"']*[\"'])[^>]*>([\\s\\S]*?)<\\/span>/gi,\n (match, inner) => {\n const labelMatch = match.match(/\\bdata-label=[\"']([^\"']+)[\"']/i);\n if (labelMatch) return ` @${labelMatch[1]} `;\n const idMatch = match.match(/\\bdata-id=[\"']([^\"']+)[\"']/i);\n if (idMatch) return ` @${idMatch[1]} `;\n return ` ${inner} `;\n }\n );\n\n const cleanContent = stripMarkdownCode(normalizedMentionNodes);\n // Strip URLs and markdown link destinations so @package or @handles in URLs are not extracted as mentions\n const withoutUrls = cleanContent\n .replace(/(?:https?|ftp|file|vscode|cursor|mailto):\\/\\/[^\\s<>()]+/gi, \"\")\n .replace(/\\]\\([^)]*\\)/g, \"]\");\n // Strip remaining HTML tags so attributes containing '@' or '>' aren't treated as mention triggers\n const textOnly = withoutUrls.replace(/<[^>]+>/g, \" \");\n\n const mentions: string[] = [];\n const seen = new Set<string>();\n\n const regex = new RegExp(MENTION_REGEX.source, \"g\");\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(textOnly)) !== null) {\n const handle = (match[1] ?? match[2] ?? match[3] ?? \"\").trim();\n if (handle && !seen.has(handle)) {\n seen.add(handle);\n mentions.push(handle);\n }\n }\n\n return mentions;\n}\n\n/**\n * Segments a text string into plain text parts and mention tokens.\n * Correctly leaves trailing punctuation (like \".\") as part of the following text segment.\n */\nexport function parseMentionSegments(content: string): MentionSegment[] {\n if (!content) return [];\n\n const segments: MentionSegment[] = [];\n const regex = new RegExp(MENTION_REGEX.source, \"g\");\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n const fullMatch = match[0];\n const atIndex = fullMatch.indexOf(\"@\");\n const prefix = atIndex > 0 ? fullMatch.slice(0, atIndex) : \"\";\n const mentionToken = fullMatch.slice(atIndex);\n const handle = match[1] ?? match[2] ?? match[3];\n const matchStart = match.index + prefix.length;\n\n if (matchStart > lastIndex) {\n segments.push({\n type: \"text\",\n value: content.slice(lastIndex, matchStart),\n });\n }\n\n segments.push({\n type: \"mention\",\n value: mentionToken,\n handle,\n });\n\n lastIndex = matchStart + mentionToken.length;\n }\n\n if (lastIndex < content.length) {\n segments.push({\n type: \"text\",\n value: content.slice(lastIndex),\n });\n }\n\n return segments;\n}\n\n/**\n * Preprocesses markdown text by turning raw @mention handles into TipTap-compatible\n * mention HTML spans (<span class=\"pixerate-mention-node\" data-type=\"mention\" ...>),\n * ensuring code blocks, inline code, existing mention nodes, and URLs remain immune.\n */\nexport function preprocessMarkdownMentions(\n content: string,\n optionsOrMentionables: MentionEntity[] | PreprocessMarkdownMentionsOptions = []\n): string {\n if (!content || typeof content !== \"string\") return \"\";\n\n const options: PreprocessMarkdownMentionsOptions = Array.isArray(optionsOrMentionables)\n ? { mentionables: optionsOrMentionables }\n : optionsOrMentionables;\n\n const allMentionables = options.mentionables || [];\n const defaultType = options.defaultType || \"user\";\n const resolveMention = options.resolveMention;\n\n const parts = content.split(MARKDOWN_MENTION_SPLIT_REGEX);\n\n return parts\n .map((part) => {\n if (!part) return \"\";\n\n // Preserve code fences, code tags, inline backticks, existing mention spans,\n // HTML tags, markdown link targets, and raw URLs untouched.\n if (\n part.startsWith(\"```\") ||\n part.startsWith(\"~~~\") ||\n part.startsWith(\"`\") ||\n part.startsWith(\"](\") ||\n /^(?:https?|file|vscode|cursor|mailto):\\/\\//i.test(part) ||\n /^<pre[\\s>]/i.test(part) ||\n /^<code[\\s>]/i.test(part) ||\n /^<[^>]+>$/i.test(part) ||\n /^<span\\b[^>]*\\b(?:data-type=[\"']mention[\"']|class=[\"'][^\"']*pixerate-mention-node[^\"']*[\"']|data-mention=[\"'][^\"']*[\"'])/i.test(\n part\n )\n ) {\n return part;\n }\n\n const regex = new RegExp(MENTION_REGEX.source, \"g\");\n return part.replace(regex, (match, quotedHandle, escapedQuotedHandle, standardHandle) => {\n const atIndex = match.indexOf(\"@\");\n const prefix = atIndex > 0 ? match.slice(0, atIndex) : \"\";\n const rawHandle = (quotedHandle || escapedQuotedHandle || standardHandle || \"\").trim();\n if (!rawHandle) return match;\n\n const lowerHandle = rawHandle.toLowerCase();\n const entity = allMentionables.find((e) => {\n if (e.label?.toLowerCase() === lowerHandle) return true;\n if (e.handle?.toLowerCase() === lowerHandle) return true;\n if (e.name?.toLowerCase() === lowerHandle) return true;\n if (e.id?.toLowerCase() === lowerHandle) return true;\n if (e.type === \"agent\" && `agent${(e.handle || e.label || \"\").toLowerCase()}` === lowerHandle) return true;\n if (\n e.aliases?.some(\n (a: string) =>\n a.toLowerCase() === lowerHandle ||\n (e.type === \"agent\" && `agent${a.toLowerCase()}` === lowerHandle)\n )\n ) {\n return true;\n }\n return false;\n });\n\n let id = entity?.id;\n let label = entity?.label || entity?.handle || rawHandle;\n let type = entity?.type;\n let avatarUrl = entity?.avatarUrl;\n let color = entity?.color || entity?.hexColor;\n\n if (!entity) {\n const customResolved = resolveMention?.(rawHandle);\n if (customResolved) {\n id = customResolved.id ?? id;\n label = customResolved.label ?? customResolved.handle ?? label;\n type = customResolved.type ?? type;\n avatarUrl = customResolved.avatarUrl ?? avatarUrl;\n color = customResolved.color ?? customResolved.hexColor ?? color;\n } else {\n const stripped = lowerHandle.replace(/^agent[\\s\\-_]*/i, \"\");\n if (\n [\"supervisor\", \"coordinator\", \"planner\", \"validator\", \"executor\"].includes(stripped)\n ) {\n type = \"agent\";\n id = stripped;\n label = stripped;\n } else if (lowerHandle === \"agents\") {\n type = \"team\";\n id = \"agents\";\n label = \"agents\";\n } else {\n type = defaultType;\n id = rawHandle;\n label = rawHandle;\n }\n }\n }\n\n const avatarAttr = avatarUrl ? ` data-avatar-url=\"${escapeHtml(avatarUrl)}\"` : \"\";\n const colorAttr = color ? ` data-color=\"${escapeHtml(color)}\"` : \"\";\n\n return `${prefix}<span class=\"pixerate-mention-node\" data-type=\"mention\" data-id=\"${escapeHtml(\n id || label\n )}\" data-label=\"${escapeHtml(label)}\" data-mention-suggestion-char=\"@\" data-type-name=\"${escapeHtml(\n type || defaultType\n )}\"${avatarAttr}${colorAttr}>@${escapeHtml(label)}</span>`;\n });\n })\n .join(\"\");\n}\n","/**\n * Escapes characters that have syntactic meaning in HTML text.\n */\nexport function escapeHtml(text: string): string {\n if (!text) return \"\";\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\n/**\n * Matches strings that are already TipTap paragraph HTML (start with `<p>` and\n * end with `</p>`), as opposed to plain text that merely mentions a `<p>` tag.\n */\nconst PARAGRAPH_HTML_REGEX = /^\\s*<p[\\s>][\\s\\S]*<\\/p>\\s*$/i;\n\n/**\n * Converts a plain-text string with newlines into HTML paragraphs suitable\n * for TipTap initial content or setContent, preserving line breaks.\n * Input that is already paragraph HTML (`<p>…</p>`) is passed through as-is.\n */\nexport function plainTextToTipTapHtml(text: string): string {\n if (!text) return \"<p></p>\";\n if (PARAGRAPH_HTML_REGEX.test(text)) {\n return text;\n }\n return text\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\r/g, \"\\n\")\n .split(\"\\n\")\n .map((line) => `<p>${escapeHtml(line)}</p>`)\n .join(\"\");\n}\n\n/**\n * Block-level elements that start a new line in plain-text output.\n */\nconst BLOCK_TAGS = new Set([\n \"P\", \"DIV\", \"LI\", \"UL\", \"OL\", \"PRE\", \"BLOCKQUOTE\", \"TABLE\", \"TR\",\n \"H1\", \"H2\", \"H3\", \"H4\", \"H5\", \"H6\", \"HR\",\n]);\n\n/**\n * Matches a TipTap mention span (including its content). The lookahead keeps\n * a single `[^>]*` scan per tag, avoiding catastrophic backtracking on\n * malformed input.\n */\nconst MENTION_SPAN_REGEX =\n /<span\\b(?=[^>]*\\bdata-type=[\"']mention[\"'])([^>]*)>[\\s\\S]*?<\\/span>/gi;\n\nfunction getHtmlAttribute(attrs: string, name: string): string | undefined {\n const match = new RegExp(`\\\\b${name}=(?:\"([^\"]*)\"|'([^']*)')`, \"i\").exec(\n attrs,\n );\n return match ? (match[1] ?? match[2]) : undefined;\n}\n\n/**\n * Parses HTML into an inert fragment. Content of a `<template>` element is not\n * rendered, so `<img onerror>` and similar handlers never run.\n */\nfunction parseHtmlFragment(html: string): DocumentFragment {\n const template = document.createElement(\"template\");\n template.innerHTML = html;\n return template.content;\n}\n\nfunction decodeHtmlEntities(text: string): string {\n return text\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/�*39;/g, \"'\")\n .replace(/ /g, \"\\u00a0\")\n .replace(/&/g, \"&\");\n}\n\n/**\n * Extracts plain text from an HTML string or TipTap HTML, preserving newlines between block tags.\n */\nexport function htmlToPlainText(html: string): string {\n if (!html) return \"\";\n\n // Normalize mentions so data-label is preserved as @label even if textContent is empty\n const mentionNormalized = html.replace(MENTION_SPAN_REGEX, (match, attrs) => {\n const label =\n getHtmlAttribute(attrs, \"data-label\") || getHtmlAttribute(attrs, \"data-id\");\n return label ? `@${label}` : match;\n });\n\n if (typeof document !== \"undefined\") {\n const fragment = parseHtmlFragment(mentionNormalized);\n fragment\n .querySelectorAll(\"br.ProseMirror-trailingBreak\")\n .forEach((br) => br.remove());\n\n // Walk the tree, emitting one line per innermost block so nested blocks\n // (e.g. TipTap's <li><p>…</p></li>) are not repeated.\n const lines: string[] = [];\n let current: string | null = null;\n const flush = () => {\n if (current !== null) {\n lines.push(current);\n current = null;\n }\n };\n const visit = (node: Node) => {\n if (node.nodeType === 3) {\n const value = node.nodeValue ?? \"\";\n // Skip formatting whitespace between blocks.\n if (current === null && value.trim() === \"\") return;\n current = (current ?? \"\") + value;\n return;\n }\n if (node.nodeType !== 1) return;\n const tag = (node as Element).tagName.toUpperCase();\n if (tag === \"BR\") {\n current = (current ?? \"\") + \"\\n\";\n return;\n }\n if (!BLOCK_TAGS.has(tag)) {\n node.childNodes.forEach(visit);\n return;\n }\n flush();\n const linesBefore = lines.length;\n node.childNodes.forEach(visit);\n flush();\n // An empty block (e.g. <p></p>) is an empty line.\n if (lines.length === linesBefore && tag !== \"HR\") {\n lines.push(\"\");\n }\n };\n fragment.childNodes.forEach(visit);\n flush();\n return lines.join(\"\\n\");\n }\n\n // Node.js fallback regex\n const text = mentionNormalized\n .replace(/<br\\s*\\/?>/gi, \"\\n\")\n // A closing block, plus any closing wrappers right after it, ends one line.\n .replace(\n /<\\/(?:p|div|li|pre|blockquote|h[1-6])>(?:\\s*<\\/(?:li|ul|ol|blockquote|div)>)*/gi,\n \"\\n\",\n )\n .replace(/<[^>]+>/g, \"\");\n return decodeHtmlEntities(text).replace(/\\n$/, \"\");\n}\n\n/**\n * Extracts plain text from a TipTap editor instance, preserving newline separators\n * between block nodes and converting mention nodes to @label.\n */\nexport function getEditorText(editor: any): string {\n if (!editor) return \"\";\n const html = typeof editor.getHTML === \"function\" ? editor.getHTML() : \"\";\n if (html) {\n return htmlToPlainText(html);\n }\n if (typeof editor.getText === \"function\") {\n try {\n return editor.getText({ blockSeparator: \"\\n\" });\n } catch {\n return editor.getText();\n }\n }\n return \"\";\n}\n\nexport interface ExtractedMention {\n id: string;\n label: string;\n type?: string;\n avatarUrl?: string;\n color?: string;\n [key: string]: any;\n}\n\nimport { extractMentions } from \"./mentions\";\n\n/**\n * Traverses an editor instance, ProseMirror document, JSONContent, or HTML string\n * and extracts all mention attributes without needing regex.\n */\nexport function extractMentionsFromDoc(docOrEditor: any): ExtractedMention[] {\n if (!docOrEditor) return [];\n const mentions: ExtractedMention[] = [];\n\n // TipTap editor or ProseMirror Node with .descendants()\n const doc =\n docOrEditor?.state?.doc ||\n (typeof docOrEditor?.descendants === \"function\" ? docOrEditor : null);\n\n if (doc && typeof doc.descendants === \"function\") {\n doc.descendants((node: any) => {\n if (node.type?.name === \"mention\" && node.attrs) {\n mentions.push({\n id: node.attrs.id || \"\",\n label: node.attrs.label || \"\",\n type: node.attrs.type,\n avatarUrl: node.attrs.avatarUrl,\n color: node.attrs.color,\n ...node.attrs,\n });\n }\n });\n return mentions;\n }\n\n // JSONContent tree\n if (typeof docOrEditor === \"object\" && docOrEditor.content) {\n const walk = (nodes: any[]) => {\n for (const node of nodes) {\n if (node.type === \"mention\" && node.attrs) {\n mentions.push({\n id: node.attrs.id || \"\",\n label: node.attrs.label || \"\",\n type: node.attrs.type,\n avatarUrl: node.attrs.avatarUrl,\n color: node.attrs.color,\n ...node.attrs,\n });\n }\n if (Array.isArray(node.content)) {\n walk(node.content);\n }\n }\n };\n walk(docOrEditor.content);\n return mentions;\n }\n\n // HTML String\n if (typeof docOrEditor === \"string\") {\n if (typeof document !== \"undefined\") {\n parseHtmlFragment(docOrEditor).querySelectorAll('span[data-type=\"mention\"]').forEach((el) => {\n mentions.push({\n id: el.getAttribute(\"data-id\") || \"\",\n label: el.getAttribute(\"data-label\") || \"\",\n type: el.getAttribute(\"data-type-name\") || undefined,\n avatarUrl: el.getAttribute(\"data-avatar-url\") || undefined,\n color: el.getAttribute(\"data-color\") || undefined,\n });\n });\n } else {\n const spanRegex = /<span([^>]*data-type=[\"']mention[\"'][^>]*)>/gi;\n let match;\n while ((match = spanRegex.exec(docOrEditor)) !== null) {\n const attrStr = match[1];\n const getAttr = (name: string) => {\n const m = new RegExp(`${name}=[\"']([^\"']*)[\"']`, \"i\").exec(attrStr);\n return m ? m[1] : undefined;\n };\n mentions.push({\n id: getAttr(\"data-id\") || \"\",\n label: getAttr(\"data-label\") || \"\",\n type: getAttr(\"data-type-name\") || getAttr(\"data-entity-type\"),\n avatarUrl: getAttr(\"data-avatar-url\"),\n color: getAttr(\"data-color\"),\n });\n }\n }\n\n // Fallback: If no HTML mention tags were found, extract raw @mentions from text or markdown\n if (mentions.length === 0) {\n const rawHandles = extractMentions(docOrEditor);\n for (const handle of rawHandles) {\n mentions.push({\n id: handle,\n label: handle,\n type: \"user\",\n });\n }\n }\n }\n\n return mentions;\n}\n","import MarkdownIt from \"markdown-it\";\nimport taskLists from \"markdown-it-task-lists\";\nimport { getEditorText } from \"./plain-text\";\n\nconst md = new MarkdownIt({\n html: true,\n linkify: true,\n breaks: true,\n}).use(taskLists);\n\nconst defaultValidateLink = md.validateLink;\nmd.validateLink = (url: string) => {\n if (\n url.startsWith(\"file://\") ||\n url.startsWith(\"vscode://\") ||\n url.startsWith(\"cursor://\")\n ) {\n return true;\n }\n return defaultValidateLink.call(md, url);\n};\n\nimport {\n preprocessMarkdownMentions,\n type PreprocessMarkdownMentionsOptions,\n} from \"./mentions\";\nimport type { MentionEntity } from \"../extensions/mention\";\n\n/**\n * Preprocesses file-protocol and editor-protocol links in markdown content:\n * converts [label](file://...), vscode://, and cursor:// links into anchor tags\n * annotated with data-file-link=\"true\", preserving code backticks in labels.\n */\nexport function preprocessMarkdownFileLinks(content: string): string {\n if (!content) return \"\";\n return content.replace(\n /\\[([^\\]]+)\\]\\(((?:file|vscode|cursor):\\/\\/[^)]+)\\)/g,\n (_match, rawLabel, href) => {\n const trimmed = rawLabel.trim();\n const codeMatch = trimmed.match(/^`([^`]+)`$/);\n const labelContent = codeMatch ? `<code>${codeMatch[1]}</code>` : trimmed;\n return `<a href=\"${href}\" data-file-link=\"true\" title=\"Click to copy file path\">${labelContent}</a>`;\n }\n );\n}\n\nexport interface MarkdownToHtmlOptions {\n /**\n * Preprocess file, vscode, and cursor links into clickable data-file-link tags.\n */\n preprocessFileLinks?: boolean;\n /**\n * Whether to preprocess @mentions into TipTap mention node HTML spans.\n */\n preprocessMentions?: boolean;\n /**\n * Pool of mentionables to pass to preprocessMarkdownMentions.\n */\n mentionables?: MentionEntity[];\n /**\n * Full options for preprocessMarkdownMentions.\n */\n preprocessOptions?: PreprocessMarkdownMentionsOptions;\n}\n\n/**\n * Converts a markdown string into HTML suitable for TipTap initial content or setContent.\n */\nexport function markdownToTipTapHtml(\n markdown: string,\n options?: MarkdownToHtmlOptions\n): string {\n if (!markdown) return \"<p></p>\";\n let content = markdown;\n if (options?.preprocessFileLinks) {\n content = preprocessMarkdownFileLinks(content);\n }\n if (\n options?.preprocessMentions ||\n options?.mentionables ||\n options?.preprocessOptions\n ) {\n const mentionOpts = options.preprocessOptions || {\n mentionables: options.mentionables,\n };\n content = preprocessMarkdownMentions(content, mentionOpts);\n }\n return md.render(content);\n}\n\n/**\n * Extracts clean markdown from a TipTap editor instance.\n * If the editor has the Markdown extension configured, it uses editor.storage.markdown.getMarkdown().\n * Otherwise, it falls back to getEditorText(editor).\n */\nexport function getEditorMarkdown(editor: any): string {\n if (!editor) return \"\";\n if (typeof editor.storage?.markdown?.getMarkdown === \"function\") {\n return editor.storage.markdown.getMarkdown();\n }\n return getEditorText(editor);\n}\n","import { Editor, EditorOptions, Content, Extensions } from \"@tiptap/core\";\nimport {\n Slice,\n Fragment,\n Node as ProsemirrorNode,\n type Schema,\n} from \"@tiptap/pm/model\";\nimport { Token, tokenizePrompt } from \"./grammar\";\nimport {\n plainTextToTipTapHtml,\n getEditorText,\n markdownToTipTapHtml,\n getEditorMarkdown,\n} from \"./serializers\";\n\nexport interface EditorControllerOptions extends Partial<\n Omit<EditorOptions, \"element\" | \"content\">\n> {\n element?: Element | HTMLElement | null;\n content?: string | Content;\n plainTextMode?: boolean;\n markdownMode?: boolean;\n extensions?: Extensions;\n onPlainTextChange?: (text: string) => void;\n onMarkdownChange?: (markdown: string) => void;\n onTokensChange?: (tokens: Token[]) => void;\n onSelectionChange?: (range: { from: number; to: number } | null) => void;\n}\n\n/**\n * Builds an open slice with one paragraph per line, so inserting it splits the\n * surrounding paragraph like typing Enter would.\n */\nfunction plainTextToSlice(text: string, schema: Schema): Slice {\n const nodes: ProsemirrorNode[] = [];\n text\n .replace(/\\r\\n?/g, \"\\n\")\n .split(\"\\n\")\n .forEach((line) => {\n const nodeJson: any = { type: \"paragraph\" };\n if (line.length > 0) {\n nodeJson.content = [{ type: \"text\", text: line }];\n }\n try {\n nodes.push(ProsemirrorNode.fromJSON(schema, nodeJson));\n } catch {\n // Ignore invalid node\n }\n });\n return Slice.maxOpen(Fragment.fromArray(nodes));\n}\n\n/**\n * UI-agnostic controller managing the lifecycle, commands, and plain-text/token\n * synchronization of a rich text or prompt editor.\n */\nexport class EditorController {\n public readonly editor: Editor;\n private readonly plainTextMode: boolean;\n private readonly markdownMode: boolean;\n private readonly onPlainTextChange?: (text: string) => void;\n private readonly onMarkdownChange?: (markdown: string) => void;\n private readonly onTokensChange?: (tokens: Token[]) => void;\n private readonly onSelectionChange?: (\n range: { from: number; to: number } | null,\n ) => void;\n private baselineContent: string;\n\n constructor(options: EditorControllerOptions = {}) {\n const {\n element,\n content,\n plainTextMode = false,\n markdownMode = false,\n extensions = [],\n onPlainTextChange,\n onMarkdownChange,\n onTokensChange,\n onSelectionChange,\n ...editorOptions\n } = options;\n\n this.plainTextMode = plainTextMode;\n this.markdownMode = markdownMode;\n this.onPlainTextChange = onPlainTextChange;\n this.onMarkdownChange = onMarkdownChange;\n this.onTokensChange = onTokensChange;\n this.onSelectionChange = onSelectionChange;\n\n const initialContent =\n plainTextMode && typeof content === \"string\"\n ? plainTextToTipTapHtml(content)\n : markdownMode && typeof content === \"string\"\n ? markdownToTipTapHtml(content)\n : content;\n\n this.editor = new Editor({\n element: element || undefined,\n content: initialContent,\n extensions,\n ...editorOptions,\n onUpdate: (props) => {\n editorOptions.onUpdate?.(props);\n this.handleUpdate();\n },\n onSelectionUpdate: (props) => {\n editorOptions.onSelectionUpdate?.(props);\n this.handleSelectionUpdate();\n },\n });\n\n if (plainTextMode) {\n this.enforcePlainTextClipboard();\n }\n\n this.baselineContent = this.getCurrentContentString();\n }\n\n private enforcePlainTextClipboard() {\n this.editor.setOptions({\n editorProps: {\n ...this.editor.options.editorProps,\n clipboardTextParser: (\n text: string,\n context: any,\n _plain: boolean,\n view?: any,\n ) => {\n const schema =\n context?.doc?.type?.schema ||\n context?.schema ||\n view?.state?.schema ||\n this.editor.schema;\n\n if (!schema) return Slice.empty;\n\n return plainTextToSlice(text, schema);\n },\n },\n });\n }\n\n private handleUpdate() {\n if (this.plainTextMode || this.onPlainTextChange || this.onTokensChange) {\n const text = this.getPlainText();\n this.onPlainTextChange?.(text);\n\n if (this.onTokensChange) {\n const tokens = tokenizePrompt(text);\n this.onTokensChange(tokens);\n }\n }\n\n if (this.markdownMode || this.onMarkdownChange) {\n const markdown = this.getMarkdown();\n this.onMarkdownChange?.(markdown);\n }\n }\n\n private handleSelectionUpdate() {\n if (this.onSelectionChange) {\n const { from, to } = this.editor.state.selection;\n this.onSelectionChange({ from, to });\n }\n }\n\n public getPlainText(): string {\n return getEditorText(this.editor);\n }\n\n public setPlainText(text: string, emitUpdate = true) {\n const html = plainTextToTipTapHtml(text);\n this.editor.commands.setContent(html, emitUpdate);\n }\n\n public getMarkdown(): string {\n return getEditorMarkdown(this.editor);\n }\n\n public setMarkdown(markdown: string, emitUpdate = true) {\n if (this.editor.storage?.markdown?.parser) {\n this.editor.commands.setContent(markdown, emitUpdate);\n } else {\n const html = markdownToTipTapHtml(markdown);\n this.editor.commands.setContent(html, emitUpdate);\n }\n }\n\n /**\n * Replaces `from`..`to` with literal text: HTML in `text` is not parsed, and\n * newlines split paragraphs.\n */\n private insertPlainText(from: number, to: number, text: string) {\n const { state, view } = this.editor;\n const tr = text.includes(\"\\n\") || text.includes(\"\\r\")\n ? state.tr.replace(from, to, plainTextToSlice(text, state.schema))\n : text\n ? state.tr.insertText(text, from, to)\n : state.tr.delete(from, to);\n view.dispatch(tr.scrollIntoView());\n }\n\n /** Inserts text literally at the selection; HTML in `text` is not parsed. */\n public insertText(text: string) {\n const { from, to } = this.editor.state.selection;\n this.insertPlainText(from, to, text);\n }\n\n /** Inserts text literally at `pos`; HTML in `text` is not parsed. */\n public insertTextAt(pos: number, text: string) {\n this.insertPlainText(pos, pos, text);\n this.editor.commands.focus();\n }\n\n /** Replaces a range with literal text; HTML in `text` is not parsed. */\n public replaceRange(from: number, to: number, text: string) {\n this.insertPlainText(from, to, text);\n this.editor.commands.focus();\n }\n\n public getCurrentContentString(): string {\n if (this.plainTextMode) return this.getPlainText();\n if (this.markdownMode) return this.getMarkdown();\n return this.editor.getHTML();\n }\n\n public isDirty(): boolean {\n return this.getCurrentContentString() !== this.baselineContent;\n }\n\n public setCheckpoint(content?: string): void {\n this.baselineContent =\n content !== undefined ? content : this.getCurrentContentString();\n }\n\n public resetDirty(): void {\n this.setCheckpoint();\n }\n\n public getBaselineContent(): string {\n return this.baselineContent;\n }\n\n public destroy() {\n this.editor.destroy();\n }\n}\n\n/**\n * Creates and initializes an EditorController instance.\n */\nexport function createEditor(\n options: EditorControllerOptions = {},\n): EditorController {\n return new EditorController(options);\n}\n","export type FormulaTokenType =\n | 'NUMBER'\n | 'STRING'\n | 'BOOLEAN'\n | 'CELL_REF'\n | 'RANGE'\n | 'PROPERTY_REF'\n | 'IDENTIFIER'\n | 'OPERATOR'\n | 'LPAREN'\n | 'RPAREN'\n | 'COMMA'\n | 'EOF';\n\nexport interface FormulaToken {\n type: FormulaTokenType;\n value: string;\n position: number;\n}\n\nexport function tokenizeFormula(formula: string): FormulaToken[] {\n const tokens: FormulaToken[] = [];\n // Strip leading '=' if present\n let input = formula.trim();\n let offset = 0;\n if (input.startsWith('=')) {\n input = input.slice(1);\n offset = 1;\n }\n\n let i = 0;\n while (i < input.length) {\n const char = input[i];\n\n // Skip whitespace\n if (/\\s/.test(char)) {\n i++;\n continue;\n }\n\n // Number literal (int or float)\n if (/\\d/.test(char) || (char === '.' && i + 1 < input.length && /\\d/.test(input[i + 1]))) {\n const start = i;\n let hasDot = char === '.';\n i++;\n while (i < input.length && (/\\d/.test(input[i]) || (input[i] === '.' && !hasDot))) {\n if (input[i] === '.') hasDot = true;\n i++;\n }\n tokens.push({\n type: 'NUMBER',\n value: input.slice(start, i),\n position: start + offset\n });\n continue;\n }\n\n // String literal (\"...\" or '...')\n if (char === '\"' || char === \"'\") {\n const quote = char;\n const start = i;\n i++;\n let str = '';\n while (i < input.length && input[i] !== quote) {\n if (input[i] === '\\\\' && i + 1 < input.length) {\n i++;\n }\n str += input[i];\n i++;\n }\n if (i < input.length && input[i] === quote) {\n i++; // skip closing quote\n }\n tokens.push({\n type: 'STRING',\n value: str,\n position: start + offset\n });\n continue;\n }\n\n // Property reference: [property_name] e.g. [status], [title], [effortHours]\n if (char === '[') {\n const start = i;\n i++;\n let prop = '';\n while (i < input.length && input[i] !== ']') {\n prop += input[i];\n i++;\n }\n if (i < input.length && input[i] === ']') {\n i++;\n }\n tokens.push({\n type: 'PROPERTY_REF',\n value: prop.trim(),\n position: start + offset\n });\n continue;\n }\n\n // Single character delimiters\n if (char === '(') {\n tokens.push({ type: 'LPAREN', value: '(', position: i + offset });\n i++;\n continue;\n }\n if (char === ')') {\n tokens.push({ type: 'RPAREN', value: ')', position: i + offset });\n i++;\n continue;\n }\n if (char === ',') {\n tokens.push({ type: 'COMMA', value: ',', position: i + offset });\n i++;\n continue;\n }\n\n // Multi-character comparison operators: <=, >=, <>, !=\n const twoChars = input.slice(i, i + 2);\n if (['<=', '>=', '<>', '!='].includes(twoChars)) {\n tokens.push({\n type: 'OPERATOR',\n value: twoChars === '!=' ? '<>' : twoChars,\n position: i + offset\n });\n i += 2;\n continue;\n }\n\n // Single character operators: +, -, *, /, ^, &, =, <, >\n if (['+', '-', '*', '/', '^', '&', '=', '<', '>'].includes(char)) {\n tokens.push({ type: 'OPERATOR', value: char, position: i + offset });\n i++;\n continue;\n }\n\n // Identifiers, Cell references, and Ranges (e.g. SUM, A1, B2:B10, A:A)\n if (/[a-zA-Z_$]/.test(char)) {\n const start = i;\n while (i < input.length && /[a-zA-Z0-9_$.]/.test(input[i])) {\n i++;\n }\n const rawWord = input.slice(start, i);\n\n // Check if followed by colon indicating a range e.g. A1:B10 or A:A\n if (i < input.length && input[i] === ':') {\n const colonPos = i;\n i++; // skip colon\n const secondStart = i;\n while (i < input.length && /[a-zA-Z0-9_$.]/.test(input[i])) {\n i++;\n }\n const secondWord = input.slice(secondStart, i);\n if (secondWord.length > 0) {\n tokens.push({\n type: 'RANGE',\n value: `${rawWord}:${secondWord}`.toUpperCase(),\n position: start + offset\n });\n continue;\n } else {\n // Revert back\n i = colonPos;\n }\n }\n\n // Check for boolean literal\n const upper = rawWord.toUpperCase();\n if (upper === 'TRUE' || upper === 'FALSE') {\n tokens.push({\n type: 'BOOLEAN',\n value: upper,\n position: start + offset\n });\n continue;\n }\n\n // Check for Cell Reference (e.g. A1, $B$12, AA100)\n if (/^\\$?[A-Za-z]+\\$?[0-9]+$/.test(rawWord)) {\n tokens.push({\n type: 'CELL_REF',\n value: upper.replace(/\\$/g, ''),\n position: start + offset\n });\n continue;\n }\n\n // Function or generic identifier\n tokens.push({\n type: 'IDENTIFIER',\n value: upper,\n position: start + offset\n });\n continue;\n }\n\n // Skip unknown character\n i++;\n }\n\n tokens.push({ type: 'EOF', value: '', position: input.length + offset });\n return tokens;\n}\n","import { FormulaToken, tokenizeFormula, FormulaTokenType } from './lexer';\n\nexport type ASTNode =\n | LiteralNode\n | CellRefNode\n | RangeNode\n | PropertyRefNode\n | BinaryOpNode\n | UnaryOpNode\n | FunctionCallNode;\n\nexport interface LiteralNode {\n type: 'Literal';\n value: number | string | boolean;\n}\n\nexport interface CellRefNode {\n type: 'CellRef';\n ref: string;\n col: string;\n row: number;\n}\n\nexport interface RangeNode {\n type: 'Range';\n raw: string;\n startCol: string;\n startRow: number;\n endCol: string;\n endRow: number;\n}\n\nexport interface PropertyRefNode {\n type: 'PropertyRef';\n property: string;\n}\n\nexport interface BinaryOpNode {\n type: 'BinaryOp';\n op: string;\n left: ASTNode;\n right: ASTNode;\n}\n\nexport interface UnaryOpNode {\n type: 'UnaryOp';\n op: string;\n argument: ASTNode;\n}\n\nexport interface FunctionCallNode {\n type: 'FunctionCall';\n name: string;\n args: ASTNode[];\n}\n\nexport function parseCellReference(ref: string): { col: string; row: number } {\n const match = ref.match(/^([A-Za-z]+)(\\d+)$/);\n if (!match) {\n throw new Error(`Invalid cell reference: ${ref}`);\n }\n return {\n col: match[1].toUpperCase(),\n row: parseInt(match[2], 10)\n };\n}\n\nexport function parseRange(rangeStr: string): RangeNode {\n const [start, end] = rangeStr.split(':');\n const startRef = parseCellReference(start);\n const endRef = parseCellReference(end);\n return {\n type: 'Range',\n raw: rangeStr.toUpperCase(),\n startCol: startRef.col,\n startRow: startRef.row,\n endCol: endRef.col,\n endRow: endRef.row\n };\n}\n\nexport class FormulaParser {\n private tokens: FormulaToken[] = [];\n private current = 0;\n\n constructor(tokens: FormulaToken[]) {\n this.tokens = tokens;\n }\n\n public parse(): ASTNode {\n if (this.peek().type === 'EOF') {\n return { type: 'Literal', value: '' };\n }\n const expr = this.expression();\n if (this.peek().type !== 'EOF') {\n throw new Error(`Unexpected token at position ${this.peek().position}: ${this.peek().value}`);\n }\n return expr;\n }\n\n private expression(): ASTNode {\n return this.comparison();\n }\n\n private comparison(): ASTNode {\n let expr = this.concatenation();\n\n while (\n this.matchOperator('=', '<>', '<', '>', '<=', '>=')\n ) {\n const op = this.previous().value;\n const right = this.concatenation();\n expr = { type: 'BinaryOp', op, left: expr, right };\n }\n\n return expr;\n }\n\n private concatenation(): ASTNode {\n let expr = this.addition();\n\n while (this.matchOperator('&')) {\n const op = this.previous().value;\n const right = this.addition();\n expr = { type: 'BinaryOp', op, left: expr, right };\n }\n\n return expr;\n }\n\n private addition(): ASTNode {\n let expr = this.multiplication();\n\n while (this.matchOperator('+', '-')) {\n const op = this.previous().value;\n const right = this.multiplication();\n expr = { type: 'BinaryOp', op, left: expr, right };\n }\n\n return expr;\n }\n\n private multiplication(): ASTNode {\n let expr = this.exponentiation();\n\n while (this.matchOperator('*', '/')) {\n const op = this.previous().value;\n const right = this.exponentiation();\n expr = { type: 'BinaryOp', op, left: expr, right };\n }\n\n return expr;\n }\n\n private exponentiation(): ASTNode {\n let expr = this.unary();\n\n while (this.matchOperator('^')) {\n const op = this.previous().value;\n const right = this.unary();\n expr = { type: 'BinaryOp', op, left: expr, right };\n }\n\n return expr;\n }\n\n private unary(): ASTNode {\n if (this.matchOperator('-', '+')) {\n const op = this.previous().value;\n const argument = this.unary();\n return { type: 'UnaryOp', op, argument };\n }\n return this.primary();\n }\n\n private primary(): ASTNode {\n const token = this.peek();\n\n if (token.type === 'NUMBER') {\n this.advance();\n return { type: 'Literal', value: parseFloat(token.value) };\n }\n\n if (token.type === 'STRING') {\n this.advance();\n return { type: 'Literal', value: token.value };\n }\n\n if (token.type === 'BOOLEAN') {\n this.advance();\n return { type: 'Literal', value: token.value === 'TRUE' };\n }\n\n if (token.type === 'CELL_REF') {\n this.advance();\n const parsed = parseCellReference(token.value);\n return {\n type: 'CellRef',\n ref: token.value,\n col: parsed.col,\n row: parsed.row\n };\n }\n\n if (token.type === 'RANGE') {\n this.advance();\n return parseRange(token.value);\n }\n\n if (token.type === 'PROPERTY_REF') {\n this.advance();\n return {\n type: 'PropertyRef',\n property: token.value\n };\n }\n\n // Function call e.g. SUM(...)\n if (token.type === 'IDENTIFIER') {\n const name = token.value;\n this.advance();\n\n if (this.check('LPAREN')) {\n this.consume('LPAREN', `Expected '(' after function ${name}`);\n const args: ASTNode[] = [];\n if (!this.check('RPAREN')) {\n do {\n args.push(this.expression());\n } while (this.match('COMMA'));\n }\n this.consume('RPAREN', `Expected ')' after function arguments`);\n return {\n type: 'FunctionCall',\n name,\n args\n };\n }\n\n // Standalone identifier treated as string literal or reference\n return { type: 'Literal', value: name };\n }\n\n if (this.match('LPAREN')) {\n const expr = this.expression();\n this.consume('RPAREN', `Expected ')' after expression`);\n return expr;\n }\n\n throw new Error(`Unexpected token at position ${token.position}: ${token.value || token.type}`);\n }\n\n private match(...types: string[]): boolean {\n for (const type of types) {\n if (this.check(type)) {\n this.advance();\n return true;\n }\n }\n return false;\n }\n\n private matchOperator(...ops: string[]): boolean {\n if (this.check('OPERATOR') && ops.includes(this.peek().value)) {\n this.advance();\n return true;\n }\n return false;\n }\n\n private check(type: string): boolean {\n if (this.isAtEnd()) return false;\n return this.peek().type === type;\n }\n\n private advance(): FormulaToken {\n if (!this.isAtEnd()) this.current++;\n return this.previous();\n }\n\n private isAtEnd(): boolean {\n return this.peek().type === 'EOF';\n }\n\n private peek(): FormulaToken {\n return this.tokens[this.current];\n }\n\n private previous(): FormulaToken {\n return this.tokens[this.current - 1];\n }\n\n private consume(type: string, message: string): FormulaToken {\n if (this.check(type)) return this.advance();\n throw new Error(message);\n }\n}\n\nexport function parseFormula(formula: string): ASTNode {\n const tokens = tokenizeFormula(formula);\n const parser = new FormulaParser(tokens);\n return parser.parse();\n}\n","import { ASTNode, parseFormula } from './parser';\n\nexport interface EvaluationContext {\n resolveCell?: (col: string, row: number) => any;\n resolveRange?: (startCol: string, startRow: number, endCol: string, endRow: number) => any[];\n resolveProperty?: (property: string) => any;\n}\n\nexport function colNameToIndex(col: string): number {\n let index = 0;\n const upper = col.toUpperCase();\n for (let i = 0; i < upper.length; i++) {\n index = index * 26 + (upper.charCodeAt(i) - 65 + 1);\n }\n return index - 1;\n}\n\nexport function indexToColName(index: number): string {\n let num = index + 1;\n let name = '';\n while (num > 0) {\n const mod = (num - 1) % 26;\n name = String.fromCharCode(65 + mod) + name;\n num = Math.floor((num - mod) / 26);\n }\n return name;\n}\n\nexport class FormulaEvaluator {\n private context: EvaluationContext;\n\n constructor(context: EvaluationContext = {}) {\n this.context = context;\n }\n\n public evaluate(astOrFormula: ASTNode | string): any {\n const ast = typeof astOrFormula === 'string' ? parseFormula(astOrFormula) : astOrFormula;\n return this.evaluateNode(ast);\n }\n\n private evaluateNode(node: ASTNode): any {\n switch (node.type) {\n case 'Literal':\n return node.value;\n\n case 'CellRef': {\n if (!this.context.resolveCell) {\n throw new Error(`Cannot resolve cell reference ${node.ref}: no cell resolver provided`);\n }\n return this.context.resolveCell(node.col, node.row);\n }\n\n case 'Range': {\n if (!this.context.resolveRange) {\n throw new Error(`Cannot resolve range ${node.raw}: no range resolver provided`);\n }\n return this.context.resolveRange(node.startCol, node.startRow, node.endCol, node.endRow);\n }\n\n case 'PropertyRef': {\n if (!this.context.resolveProperty) {\n throw new Error(`Cannot resolve property [${node.property}]: no property resolver provided`);\n }\n return this.context.resolveProperty(node.property);\n }\n\n case 'UnaryOp': {\n const val = this.evaluateNode(node.argument);\n if (node.op === '-') return -Number(val);\n if (node.op === '+') return +Number(val);\n throw new Error(`Unsupported unary operator: ${node.op}`);\n }\n\n case 'BinaryOp': {\n const left = this.evaluateNode(node.left);\n const right = this.evaluateNode(node.right);\n\n switch (node.op) {\n case '+':\n return Number(left) + Number(right);\n case '-':\n return Number(left) - Number(right);\n case '*':\n return Number(left) * Number(right);\n case '/': {\n const denom = Number(right);\n if (denom === 0) return '#DIV/0!';\n return Number(left) / denom;\n }\n case '^':\n return Math.pow(Number(left), Number(right));\n case '&':\n return `${left ?? ''}${right ?? ''}`;\n case '=':\n // Relaxed equality\n return String(left).toLowerCase() === String(right).toLowerCase();\n case '<>':\n return String(left).toLowerCase() !== String(right).toLowerCase();\n case '<':\n return Number(left) < Number(right);\n case '<=':\n return Number(left) <= Number(right);\n case '>':\n return Number(left) > Number(right);\n case '>=':\n return Number(left) >= Number(right);\n default:\n throw new Error(`Unsupported binary operator: ${node.op}`);\n }\n }\n\n case 'FunctionCall': {\n return this.callFunction(node.name, node.args);\n }\n\n default:\n throw new Error(`Unknown AST node: ${(node as any).type}`);\n }\n }\n\n private callFunction(name: string, args: ASTNode[]): any {\n const fnName = name.toUpperCase();\n\n // Flatten helper for range/array args\n const evaluateAndFlatten = (): any[] => {\n const items: any[] = [];\n for (const arg of args) {\n const val = this.evaluateNode(arg);\n if (Array.isArray(val)) {\n items.push(...val);\n } else {\n items.push(val);\n }\n }\n return items;\n };\n\n switch (fnName) {\n case 'SUM': {\n const items = evaluateAndFlatten();\n let total = 0;\n for (const item of items) {\n const num = Number(item);\n if (!isNaN(num)) total += num;\n }\n return total;\n }\n\n case 'AVERAGE': {\n const items = evaluateAndFlatten();\n let total = 0;\n let count = 0;\n for (const item of items) {\n const num = Number(item);\n if (!isNaN(num) && item !== '' && item !== null && item !== undefined) {\n total += num;\n count++;\n }\n }\n return count === 0 ? 0 : total / count;\n }\n\n case 'COUNT': {\n const items = evaluateAndFlatten();\n let count = 0;\n for (const item of items) {\n const num = Number(item);\n if (!isNaN(num) && item !== '' && item !== null && item !== undefined) {\n count++;\n }\n }\n return count;\n }\n\n case 'COUNTA': {\n const items = evaluateAndFlatten();\n let count = 0;\n for (const item of items) {\n if (item !== '' && item !== null && item !== undefined) {\n count++;\n }\n }\n return count;\n }\n\n case 'MIN': {\n const items = evaluateAndFlatten().map(Number).filter((n) => !isNaN(n));\n return items.length === 0 ? 0 : Math.min(...items);\n }\n\n case 'MAX': {\n const items = evaluateAndFlatten().map(Number).filter((n) => !isNaN(n));\n return items.length === 0 ? 0 : Math.max(...items);\n }\n\n case 'IF': {\n if (args.length < 2) throw new Error('IF requires at least 2 arguments');\n const condition = Boolean(this.evaluateNode(args[0]));\n if (condition) {\n return this.evaluateNode(args[1]);\n } else {\n return args.length > 2 ? this.evaluateNode(args[2]) : false;\n }\n }\n\n case 'CONCAT': {\n const items = evaluateAndFlatten();\n return items.map((i) => (i === null || i === undefined ? '' : String(i))).join('');\n }\n\n case 'UPPER': {\n if (args.length !== 1) throw new Error('UPPER requires 1 argument');\n const val = this.evaluateNode(args[0]);\n return String(val ?? '').toUpperCase();\n }\n\n case 'LOWER': {\n if (args.length !== 1) throw new Error('LOWER requires 1 argument');\n const val = this.evaluateNode(args[0]);\n return String(val ?? '').toLowerCase();\n }\n\n case 'TRIM': {\n if (args.length !== 1) throw new Error('TRIM requires 1 argument');\n const val = this.evaluateNode(args[0]);\n return String(val ?? '').trim();\n }\n\n case 'LEN': {\n if (args.length !== 1) throw new Error('LEN requires 1 argument');\n const val = this.evaluateNode(args[0]);\n return String(val ?? '').length;\n }\n\n case 'ROUND': {\n if (args.length < 1) throw new Error('ROUND requires at least 1 argument');\n const num = Number(this.evaluateNode(args[0]));\n const decimals = args.length > 1 ? Number(this.evaluateNode(args[1])) : 0;\n const factor = Math.pow(10, decimals);\n return Math.round(num * factor) / factor;\n }\n\n case 'ABS': {\n if (args.length !== 1) throw new Error('ABS requires 1 argument');\n return Math.abs(Number(this.evaluateNode(args[0])));\n }\n\n case 'TODAY': {\n return new Date().toISOString().split('T')[0];\n }\n\n case 'DAYS': {\n if (args.length !== 2) throw new Error('DAYS requires 2 arguments (end_date, start_date)');\n const d1 = new Date(this.evaluateNode(args[0]));\n const d2 = new Date(this.evaluateNode(args[1]));\n const diffTime = d1.getTime() - d2.getTime();\n return Math.round(diffTime / (1000 * 60 * 60 * 24));\n }\n\n default:\n throw new Error(`Unknown function: ${fnName}`);\n }\n }\n}\n","import { ASTNode, parseFormula } from './parser';\nimport { colNameToIndex, indexToColName } from './evaluator';\n\nexport interface CellDep {\n col: string;\n row: number;\n}\n\nexport function extractCellDependencies(node: ASTNode): CellDep[] {\n const deps: CellDep[] = [];\n\n const visit = (curr: ASTNode) => {\n if (curr.type === 'CellRef') {\n deps.push({ col: curr.col, row: curr.row });\n } else if (curr.type === 'Range') {\n const startC = colNameToIndex(curr.startCol);\n const endC = colNameToIndex(curr.endCol);\n const minC = Math.min(startC, endC);\n const maxC = Math.max(startC, endC);\n const minR = Math.min(curr.startRow, curr.endRow);\n const maxR = Math.max(curr.startRow, curr.endRow);\n\n for (let c = minC; c <= maxC; c++) {\n for (let r = minR; r <= maxR; r++) {\n deps.push({ col: indexToColName(c), row: r });\n }\n }\n } else if (curr.type === 'BinaryOp') {\n visit(curr.left);\n visit(curr.right);\n } else if (curr.type === 'UnaryOp') {\n visit(curr.argument);\n } else if (curr.type === 'FunctionCall') {\n curr.args.forEach(visit);\n }\n };\n\n visit(node);\n return deps;\n}\n\nexport class DependencyGraph {\n // Map of cellKey (e.g. \"B2\") -> Set of cellKeys that this cell depends ON\n private dependencies = new Map<string, Set<string>>();\n // Map of cellKey (e.g. \"A1\") -> Set of cellKeys that depend ON this cell (dependents)\n private dependents = new Map<string, Set<string>>();\n\n public setCellFormula(cellKey: string, formulaStr: string | null): void {\n const key = cellKey.toUpperCase();\n\n // Clear existing dependencies\n const oldDeps = this.dependencies.get(key) || new Set();\n for (const dep of oldDeps) {\n this.dependents.get(dep)?.delete(key);\n }\n this.dependencies.delete(key);\n\n if (!formulaStr || !formulaStr.startsWith('=')) {\n return;\n }\n\n try {\n const ast = parseFormula(formulaStr);\n const deps = extractCellDependencies(ast);\n const newDeps = new Set<string>();\n\n for (const d of deps) {\n const depKey = `${d.col}${d.row}`.toUpperCase();\n newDeps.add(depKey);\n\n if (!this.dependents.has(depKey)) {\n this.dependents.set(depKey, new Set());\n }\n this.dependents.get(depKey)!.add(key);\n }\n\n this.dependencies.set(key, newDeps);\n } catch {\n // Syntax errors in formula have no valid dependencies\n }\n }\n\n public getDependencies(cellKey: string): string[] {\n return Array.from(this.dependencies.get(cellKey.toUpperCase()) || []);\n }\n\n public getDependents(cellKey: string): string[] {\n return Array.from(this.dependents.get(cellKey.toUpperCase()) || []);\n }\n\n /**\n * Detects if there is a cycle containing cellKey.\n */\n public hasCycle(cellKey: string): boolean {\n const key = cellKey.toUpperCase();\n const visited = new Set<string>();\n const recStack = new Set<string>();\n\n const dfs = (node: string): boolean => {\n visited.add(node);\n recStack.add(node);\n\n const deps = this.dependencies.get(node) || new Set();\n for (const neighbor of deps) {\n if (!visited.has(neighbor)) {\n if (dfs(neighbor)) return true;\n } else if (recStack.has(neighbor)) {\n return true;\n }\n }\n\n recStack.delete(node);\n return false;\n };\n\n return dfs(key);\n }\n\n /**\n * Returns cells affected by updating cellKey in topological order.\n */\n public getEvaluationOrder(startCellKey: string): { order: string[]; hasCycle: boolean } {\n const start = startCellKey.toUpperCase();\n const visited = new Set<string>();\n const recStack = new Set<string>();\n const order: string[] = [];\n let cycleDetected = false;\n\n // Collect all downstream affected cells (reachability via dependents)\n const affected = new Set<string>();\n const collectAffected = (node: string) => {\n affected.add(node);\n const directDependents = this.dependents.get(node) || new Set();\n for (const dep of directDependents) {\n if (!affected.has(dep)) {\n collectAffected(dep);\n }\n }\n };\n collectAffected(start);\n\n // Topological sort among affected cells\n const visit = (node: string) => {\n if (recStack.has(node)) {\n cycleDetected = true;\n return;\n }\n if (visited.has(node)) return;\n\n recStack.add(node);\n visited.add(node);\n\n // Visit nodes that this node depends on, IF they are in the affected set\n const deps = this.dependencies.get(node) || new Set();\n for (const neighbor of deps) {\n if (affected.has(neighbor)) {\n visit(neighbor);\n }\n }\n\n recStack.delete(node);\n order.push(node);\n };\n\n for (const node of affected) {\n if (!visited.has(node)) {\n visit(node);\n }\n }\n\n return { order, hasCycle: cycleDetected };\n }\n}\n","import { SpreadsheetDataSource, SpreadsheetRow, SpreadsheetColumn } from '../types';\n\nexport class DataSourceBinder {\n private dataSources = new Map<string, SpreadsheetDataSource>();\n\n public register(dataSource: SpreadsheetDataSource): void {\n this.dataSources.set(dataSource.id, dataSource);\n }\n\n public unregister(dataSourceId: string): void {\n this.dataSources.delete(dataSourceId);\n }\n\n public getDataSource(id: string): SpreadsheetDataSource | undefined {\n return this.dataSources.get(id);\n }\n\n /**\n * Generates or reconciles spreadsheet rows from a primary data source.\n */\n public syncRows(\n currentRows: SpreadsheetRow[],\n dataSourceId: string\n ): SpreadsheetRow[] {\n const ds = this.dataSources.get(dataSourceId);\n if (!ds) return currentRows;\n\n const records = ds.getRecords();\n const existingRecordRowMap = new Map<string, SpreadsheetRow>();\n const freeformRows: SpreadsheetRow[] = [];\n\n for (const row of currentRows) {\n if (row.type === 'record' && row.recordId) {\n existingRecordRowMap.set(row.recordId, row);\n } else {\n freeformRows.push(row);\n }\n }\n\n const nextRows: SpreadsheetRow[] = [];\n let rowIndex = 0;\n\n for (const record of records) {\n const existing = existingRecordRowMap.get(record.id);\n nextRows.push({\n id: existing?.id || `row_${record.id}`,\n index: rowIndex++,\n height: existing?.height || 32,\n recordId: record.id,\n type: 'record'\n });\n existingRecordRowMap.delete(record.id);\n }\n\n // Append preserved freeform rows\n for (const freeform of freeformRows) {\n nextRows.push({\n ...freeform,\n index: rowIndex++\n });\n }\n\n return nextRows;\n }\n\n /**\n * Resolves a record's bound field value.\n */\n public resolveBoundValue(\n dataSourceId: string,\n recordId: string,\n field: string\n ): any {\n const ds = this.dataSources.get(dataSourceId);\n if (!ds) return undefined;\n\n const records = ds.getRecords();\n const record = records.find((r) => r.id === recordId);\n return record ? record[field] : undefined;\n }\n\n /**\n * Dispatches an update to the underlying data source.\n */\n public async commitBoundValue(\n dataSourceId: string,\n recordId: string,\n field: string,\n value: any\n ): Promise<void> {\n const ds = this.dataSources.get(dataSourceId);\n if (!ds) return;\n await ds.updateRecord(recordId, field, value);\n }\n}\n","import {\n SpreadsheetDocument,\n SpreadsheetColumn,\n SpreadsheetRow,\n CellCoordinate,\n CellRange,\n CellData,\n SpreadsheetDataSource\n} from './types';\nimport {\n FormulaEvaluator,\n colNameToIndex,\n indexToColName,\n DependencyGraph\n} from './formula';\nimport { DataSourceBinder } from './datasource';\n\nexport interface SpreadsheetControllerOptions {\n document?: Partial<SpreadsheetDocument>;\n dataSources?: SpreadsheetDataSource[];\n primaryDataSourceId?: string;\n onDocumentChange?: (doc: SpreadsheetDocument) => void;\n onSelectionChange?: (activeCell: CellCoordinate | null, range: CellRange | null) => void;\n onCellCommit?: (rowId: string, colId: string, raw: string, value: any) => void;\n}\n\nexport class SpreadsheetController {\n public document: SpreadsheetDocument;\n public activeCell: CellCoordinate | null = null;\n public selectedRange: CellRange | null = null;\n public editingCell: CellCoordinate | null = null;\n public draftValue = '';\n\n public readonly binder = new DataSourceBinder();\n public readonly depGraph = new DependencyGraph();\n public readonly evaluator: FormulaEvaluator;\n\n private primaryDataSourceId?: string;\n private onDocumentChange?: (doc: SpreadsheetDocument) => void;\n private onSelectionChange?: (activeCell: CellCoordinate | null, range: CellRange | null) => void;\n private onCellCommit?: (rowId: string, colId: string, raw: string, value: any) => void;\n\n // History stack for undo/redo\n private undoStack: string[] = [];\n private redoStack: string[] = [];\n private isApplyingHistory = false;\n\n constructor(options: SpreadsheetControllerOptions = {}) {\n const defaultCols: SpreadsheetColumn[] = [\n { id: 'col_a', key: 'A', title: 'A', width: 120, type: 'freeform' },\n { id: 'col_b', key: 'B', title: 'B', width: 120, type: 'freeform' },\n { id: 'col_c', key: 'C', title: 'C', width: 120, type: 'freeform' },\n { id: 'col_d', key: 'D', title: 'D', width: 120, type: 'freeform' }\n ];\n\n const defaultRows: SpreadsheetRow[] = options.primaryDataSourceId ? [] : Array.from({ length: 10 }, (_, i) => ({\n id: `row_${i + 1}`,\n index: i,\n height: 32,\n type: 'freeform'\n }));\n\n this.document = {\n id: options.document?.id || `sheet_${Date.now()}`,\n name: options.document?.name || 'Sheet 1',\n columns: options.document?.columns || defaultCols,\n rows: options.document?.rows || defaultRows,\n cells: options.document?.cells || {},\n createdAt: options.document?.createdAt || Date.now(),\n updatedAt: options.document?.updatedAt || Date.now()\n };\n\n this.primaryDataSourceId = options.primaryDataSourceId;\n this.onDocumentChange = options.onDocumentChange;\n this.onSelectionChange = options.onSelectionChange;\n this.onCellCommit = options.onCellCommit;\n\n if (options.dataSources) {\n options.dataSources.forEach((ds) => this.binder.register(ds));\n }\n\n this.evaluator = new FormulaEvaluator({\n resolveCell: (colStr, rowNum) => this.resolveCellByCoord(colStr, rowNum),\n resolveRange: (sCol, sRow, eCol, eRow) => this.resolveRangeByCoords(sCol, sRow, eCol, eRow),\n resolveProperty: (prop) => this.resolveCurrentRowProperty(prop)\n });\n\n this.syncWithDataSource();\n this.recalculateAll();\n }\n\n public loadDocument(document: SpreadsheetDocument): void {\n this.document = JSON.parse(JSON.stringify(document));\n this.activeCell = null;\n this.selectedRange = null;\n this.editingCell = null;\n this.draftValue = '';\n this.undoStack = [];\n this.redoStack = [];\n this.syncWithDataSource();\n this.recalculateAll();\n this.notifyChange();\n }\n\n public registerDataSource(ds: SpreadsheetDataSource): void {\n this.binder.register(ds);\n this.syncWithDataSource();\n this.recalculateAll();\n }\n\n public setPrimaryDataSource(dataSourceId: string | undefined): void {\n this.primaryDataSourceId = dataSourceId;\n this.syncWithDataSource();\n this.recalculateAll();\n }\n\n public syncWithDataSource(): void {\n if (!this.primaryDataSourceId) return;\n this.document.rows = this.binder.syncRows(this.document.rows, this.primaryDataSourceId);\n this.recomputeRowIndices();\n }\n\n private recomputeRowIndices(): void {\n this.document.rows.forEach((r, idx) => {\n r.index = idx;\n });\n this.document.columns.forEach((c, idx) => {\n c.key = indexToColName(idx);\n });\n }\n\n public getColumn(colIdOrKey: string): SpreadsheetColumn | undefined {\n return this.document.columns.find(\n (c) => c.id === colIdOrKey || c.key.toUpperCase() === colIdOrKey.toUpperCase()\n );\n }\n\n public getRow(rowIdOrIndex: string | number): SpreadsheetRow | undefined {\n if (typeof rowIdOrIndex === 'number') {\n return this.document.rows[rowIdOrIndex];\n }\n return this.document.rows.find((r) => r.id === rowIdOrIndex);\n }\n\n public getCell(rowId: string, colId: string): CellData {\n const existing = this.document.cells[rowId]?.[colId];\n if (existing) return existing;\n\n // Check if column is bound to record\n const col = this.document.columns.find((c) => c.id === colId);\n const row = this.document.rows.find((r) => r.id === rowId);\n\n if (col && row && col.type === 'bound' && col.binding && row.recordId) {\n const boundVal = this.binder.resolveBoundValue(\n col.binding.dataSource,\n row.recordId,\n col.binding.field\n );\n return {\n raw: boundVal !== undefined ? String(boundVal) : '',\n value: boundVal ?? '',\n format: col.format\n };\n }\n\n // Check if column has a column-level formula\n if (col && col.type === 'formula' && col.formula) {\n return {\n raw: col.formula,\n value: '',\n format: col.format\n };\n }\n\n return { raw: '', value: '', format: col?.format };\n }\n\n public setCellValue(rowId: string, colId: string, raw: string): void {\n this.recordSnapshot();\n\n if (!this.document.cells[rowId]) {\n this.document.cells[rowId] = {};\n }\n\n const col = this.document.columns.find((c) => c.id === colId);\n const row = this.document.rows.find((r) => r.id === rowId);\n\n // If this is a bound column and row is bound to record, dispatch back to data source\n if (col?.type === 'bound' && col.binding && row?.recordId) {\n this.binder.commitBoundValue(\n col.binding.dataSource,\n row.recordId,\n col.binding.field,\n raw\n );\n }\n\n const cellKey = this.getCellKey(rowId, colId);\n this.depGraph.setCellFormula(cellKey, raw.startsWith('=') ? raw : null);\n\n this.document.cells[rowId][colId] = {\n raw,\n value: raw,\n format: col?.format\n };\n\n this.document.updatedAt = Date.now();\n this.recalculateCell(rowId, colId);\n this.notifyChange();\n\n const evaluatedVal = this.document.cells[rowId][colId]?.value;\n this.onCellCommit?.(rowId, colId, raw, evaluatedVal);\n }\n\n private getCellKey(rowId: string, colId: string): string {\n const row = this.document.rows.find((r) => r.id === rowId);\n const col = this.document.columns.find((c) => c.id === colId);\n if (!row || !col) return `${colId}_${rowId}`;\n return `${col.key}${row.index + 1}`.toUpperCase();\n }\n\n public recalculateCell(rowId: string, colId: string): void {\n const cellKey = this.getCellKey(rowId, colId);\n const { order, hasCycle } = this.depGraph.getEvaluationOrder(cellKey);\n\n if (hasCycle) {\n if (this.document.cells[rowId]?.[colId]) {\n this.document.cells[rowId][colId].error = '#CYCLE!';\n this.document.cells[rowId][colId].value = '#CYCLE!';\n }\n return;\n }\n\n for (const key of order) {\n this.evalSingleCellByKey(key);\n }\n }\n\n public recalculateAll(): void {\n for (const row of this.document.rows) {\n for (const col of this.document.columns) {\n const cell = this.getCell(row.id, col.id);\n const cellKey = `${col.key}${row.index + 1}`.toUpperCase();\n if (cell.raw.startsWith('=')) {\n this.depGraph.setCellFormula(cellKey, cell.raw);\n }\n }\n }\n\n for (const row of this.document.rows) {\n for (const col of this.document.columns) {\n const cellKey = `${col.key}${row.index + 1}`.toUpperCase();\n this.evalSingleCellByKey(cellKey);\n }\n }\n }\n\n private evalSingleCellByKey(cellKey: string): void {\n const match = cellKey.match(/^([A-Za-z]+)(\\d+)$/);\n if (!match) return;\n const colName = match[1].toUpperCase();\n const rowNum = parseInt(match[2], 10);\n\n const col = this.document.columns.find((c) => c.key.toUpperCase() === colName);\n const row = this.document.rows[rowNum - 1];\n if (!col || !row) return;\n\n const cell = this.getCell(row.id, col.id);\n if (!cell.raw.startsWith('=')) {\n if (cell.error === '#CYCLE!') {\n cell.error = undefined;\n }\n return;\n }\n\n try {\n const computed = this.evaluator.evaluate(cell.raw);\n if (!this.document.cells[row.id]) {\n this.document.cells[row.id] = {};\n }\n this.document.cells[row.id][col.id] = {\n ...cell,\n value: computed,\n error: undefined\n };\n } catch (err: any) {\n if (!this.document.cells[row.id]) {\n this.document.cells[row.id] = {};\n }\n this.document.cells[row.id][col.id] = {\n ...cell,\n value: '#ERROR!',\n error: err?.message || 'Formula error'\n };\n }\n }\n\n private resolveCellByCoord(colStr: string, rowNum: number): any {\n const col = this.document.columns.find((c) => c.key.toUpperCase() === colStr.toUpperCase());\n const row = this.document.rows[rowNum - 1];\n if (!col || !row) return 0;\n\n const cell = this.getCell(row.id, col.id);\n return cell.value !== undefined && cell.value !== '' ? cell.value : 0;\n }\n\n private resolveRangeByCoords(sCol: string, sRow: number, eCol: string, eRow: number): any[] {\n const startC = colNameToIndex(sCol);\n const endC = colNameToIndex(eCol);\n const minC = Math.min(startC, endC);\n const maxC = Math.max(startC, endC);\n const minR = Math.min(sRow, eRow);\n const maxR = Math.max(sRow, eRow);\n\n const results: any[] = [];\n for (let c = minC; c <= maxC; c++) {\n const colName = indexToColName(c);\n const col = this.document.columns.find((colDef) => colDef.key.toUpperCase() === colName);\n if (!col) continue;\n\n for (let r = minR; r <= maxR; r++) {\n const row = this.document.rows[r - 1];\n if (!row) continue;\n const cell = this.getCell(row.id, col.id);\n results.push(cell.value !== undefined && cell.value !== '' ? cell.value : 0);\n }\n }\n return results;\n }\n\n private resolveCurrentRowProperty(prop: string): any {\n if (!this.activeCell) return 0;\n const row = this.document.rows[this.activeCell.row];\n if (!row || !row.recordId || !this.primaryDataSourceId) return 0;\n return this.binder.resolveBoundValue(this.primaryDataSourceId, row.recordId, prop) ?? 0;\n }\n\n // --- Selection and Navigation ---\n\n public selectCell(row: number, col: number, extendSelection = false): void {\n const clampedRow = Math.max(0, Math.min(row, this.document.rows.length - 1));\n const clampedCol = Math.max(0, Math.min(col, this.document.columns.length - 1));\n\n const rowObj = this.document.rows[clampedRow];\n const colObj = this.document.columns[clampedCol];\n\n this.activeCell = {\n row: clampedRow,\n col: clampedCol,\n rowId: rowObj?.id,\n colId: colObj?.id\n };\n\n if (extendSelection && this.selectedRange) {\n this.selectedRange = {\n startRow: this.selectedRange.startRow,\n startCol: this.selectedRange.startCol,\n endRow: clampedRow,\n endCol: clampedCol\n };\n } else {\n this.selectedRange = {\n startRow: clampedRow,\n startCol: clampedCol,\n endRow: clampedRow,\n endCol: clampedCol\n };\n }\n\n this.onSelectionChange?.(this.activeCell, this.selectedRange);\n }\n\n public selectRange(range: CellRange): void {\n this.selectedRange = range;\n this.onSelectionChange?.(this.activeCell, this.selectedRange);\n }\n\n public startEditing(row?: number, col?: number, initialValue?: string): void {\n const targetRow = row ?? this.activeCell?.row ?? 0;\n const targetCol = col ?? this.activeCell?.col ?? 0;\n this.selectCell(targetRow, targetCol);\n\n const rowObj = this.document.rows[targetRow];\n const colObj = this.document.columns[targetCol];\n if (!rowObj || !colObj) return;\n\n this.editingCell = {\n row: targetRow,\n col: targetCol,\n rowId: rowObj.id,\n colId: colObj.id\n };\n\n const cell = this.getCell(rowObj.id, colObj.id);\n this.draftValue = initialValue !== undefined ? initialValue : cell.raw;\n }\n\n public commitEditing(valueToCommit?: string): void {\n if (!this.editingCell) return;\n const val = valueToCommit !== undefined ? valueToCommit : this.draftValue;\n if (this.editingCell.rowId && this.editingCell.colId) {\n this.setCellValue(this.editingCell.rowId, this.editingCell.colId, val);\n }\n this.editingCell = null;\n this.draftValue = '';\n }\n\n public cancelEditing(): void {\n this.editingCell = null;\n this.draftValue = '';\n }\n\n public moveCursor(\n direction: 'up' | 'down' | 'left' | 'right',\n extendSelection = false\n ): void {\n if (!this.activeCell) {\n this.selectCell(0, 0);\n return;\n }\n\n let nextRow = this.activeCell.row;\n let nextCol = this.activeCell.col;\n\n switch (direction) {\n case 'up':\n nextRow = Math.max(0, nextRow - 1);\n break;\n case 'down':\n nextRow = Math.min(this.document.rows.length - 1, nextRow + 1);\n break;\n case 'left':\n nextCol = Math.max(0, nextCol - 1);\n break;\n case 'right':\n nextCol = Math.min(this.document.columns.length - 1, nextCol + 1);\n break;\n }\n\n this.selectCell(nextRow, nextCol, extendSelection);\n }\n\n // --- Grid Structure Mutations ---\n\n public insertColumn(index: number, config?: Partial<SpreadsheetColumn>): void {\n this.recordSnapshot();\n const newId = config?.id || `col_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;\n const newCol: SpreadsheetColumn = {\n id: newId,\n key: indexToColName(index),\n title: config?.title || indexToColName(index),\n width: config?.width || 130,\n type: config?.type || 'freeform',\n binding: config?.binding,\n formula: config?.formula,\n format: config?.format || 'text',\n readOnly: config?.readOnly\n };\n\n this.document.columns.splice(index, 0, newCol);\n this.recomputeRowIndices();\n this.recalculateAll();\n this.notifyChange();\n }\n\n public deleteColumn(colId: string): void {\n this.recordSnapshot();\n this.document.columns = this.document.columns.filter((c) => c.id !== colId);\n for (const rowId of Object.keys(this.document.cells)) {\n delete this.document.cells[rowId][colId];\n }\n this.recomputeRowIndices();\n this.recalculateAll();\n this.notifyChange();\n }\n\n public insertRow(index: number, config?: Partial<SpreadsheetRow>): void {\n this.recordSnapshot();\n const newId = config?.id || `row_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;\n const newRow: SpreadsheetRow = {\n id: newId,\n index,\n height: config?.height || 32,\n recordId: config?.recordId,\n type: config?.type || 'freeform'\n };\n\n this.document.rows.splice(index, 0, newRow);\n this.recomputeRowIndices();\n this.recalculateAll();\n this.notifyChange();\n }\n\n public deleteRow(rowId: string): void {\n this.recordSnapshot();\n this.document.rows = this.document.rows.filter((r) => r.id !== rowId);\n delete this.document.cells[rowId];\n this.recomputeRowIndices();\n this.recalculateAll();\n this.notifyChange();\n }\n\n public setColumnWidth(colId: string, width: number): void {\n const col = this.document.columns.find((c) => c.id === colId);\n if (col) {\n col.width = Math.max(30, width);\n this.notifyChange();\n }\n }\n\n public autoFitColumnWidth(colId: string, customWidth?: number): void {\n if (customWidth !== undefined) {\n this.setColumnWidth(colId, customWidth);\n return;\n }\n const col = this.document.columns.find((c) => c.id === colId);\n if (!col) return;\n\n let maxLen = (col.title || '').length + (col.key ? col.key.length + 3 : 0);\n for (const row of this.document.rows) {\n const cell = this.getCell(row.id, col.id);\n const valStr = cell.value != null ? String(cell.value) : '';\n if (valStr.length > maxLen) {\n maxLen = valStr.length;\n }\n }\n const estimatedWidth = Math.min(600, Math.max(50, Math.ceil(maxLen * 8.5 + 32)));\n this.setColumnWidth(colId, estimatedWidth);\n }\n\n // --- Clipboard TSV/CSV ---\n\n public exportToTsv(): string {\n return this.document.rows\n .map((row) =>\n this.document.columns\n .map((col) => {\n const cell = this.getCell(row.id, col.id);\n return String(cell.value ?? '').replace(/\\t/g, ' ');\n })\n .join('\\t')\n )\n .join('\\n');\n }\n\n public importFromTsv(tsvData: string, startRow = 0, startCol = 0): void {\n this.recordSnapshot();\n const lines = tsvData.trim().split('\\n');\n\n lines.forEach((line, rIdx) => {\n const cells = line.split('\\t');\n const targetR = startRow + rIdx;\n\n while (targetR >= this.document.rows.length) {\n this.insertRow(this.document.rows.length);\n }\n const row = this.document.rows[targetR];\n\n cells.forEach((val, cIdx) => {\n const targetC = startCol + cIdx;\n while (targetC >= this.document.columns.length) {\n this.insertColumn(this.document.columns.length);\n }\n const col = this.document.columns[targetC];\n this.setCellValue(row.id, col.id, val);\n });\n });\n\n this.recalculateAll();\n this.notifyChange();\n }\n\n // --- Undo/Redo Snapshots ---\n\n private recordSnapshot(): void {\n if (this.isApplyingHistory) return;\n this.undoStack.push(JSON.stringify(this.document));\n if (this.undoStack.length > 50) this.undoStack.shift();\n this.redoStack = [];\n }\n\n public undo(): void {\n if (this.undoStack.length === 0) return;\n this.isApplyingHistory = true;\n this.redoStack.push(JSON.stringify(this.document));\n const previous = JSON.parse(this.undoStack.pop()!);\n this.document = previous;\n this.recalculateAll();\n this.notifyChange();\n this.isApplyingHistory = false;\n }\n\n public redo(): void {\n if (this.redoStack.length === 0) return;\n this.isApplyingHistory = true;\n this.undoStack.push(JSON.stringify(this.document));\n const next = JSON.parse(this.redoStack.pop()!);\n this.document = next;\n this.recalculateAll();\n this.notifyChange();\n this.isApplyingHistory = false;\n }\n\n private notifyChange(): void {\n this.onDocumentChange?.(this.document);\n }\n}\n","/**\n * Compares two values for structural equality.\n * Handles primitives, objects, arrays, and null/undefined.\n */\nexport function defaultIsEqual<T>(a: T, b: T): boolean {\n if (Object.is(a, b)) return true;\n if (\n typeof a !== \"object\" ||\n a === null ||\n typeof b !== \"object\" ||\n b === null\n ) {\n return false;\n }\n\n // Fast path for arrays\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!defaultIsEqual(a[i], b[i])) return false;\n }\n return true;\n }\n if (Array.isArray(a) !== Array.isArray(b)) {\n return false;\n }\n\n const keysA = Object.keys(a) as (keyof T)[];\n const keysB = Object.keys(b) as (keyof T)[];\n\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (!Object.prototype.hasOwnProperty.call(b, key)) return false;\n if (!defaultIsEqual(a[key], b[key])) return false;\n }\n\n return true;\n}\n\nexport interface DirtyTrackerOptions<T> {\n isEqual?: (a: T, b: T) => boolean;\n}\n\n/**\n * Tracks a baseline value and determines if the current state is dirty (modified).\n */\nexport class DirtyTracker<T = unknown> {\n private baseline: T;\n private readonly isEqual: (a: T, b: T) => boolean;\n\n constructor(\n initialBaseline: T,\n options?: DirtyTrackerOptions<T> | ((a: T, b: T) => boolean),\n ) {\n this.baseline = initialBaseline;\n if (typeof options === \"function\") {\n this.isEqual = options;\n } else {\n this.isEqual = options?.isEqual ?? defaultIsEqual;\n }\n }\n\n /**\n * Returns current baseline value.\n */\n public getBaseline(): T {\n return this.baseline;\n }\n\n /**\n * Sets a new baseline value without triggering any dirty state.\n */\n public setBaseline(value: T): void {\n this.baseline = value;\n }\n\n /**\n * Checks whether the given value differs from the baseline.\n */\n public isDirty(current: T): boolean {\n return !this.isEqual(this.baseline, current);\n }\n\n /**\n * Resets the baseline to the provided current value (or clears dirty status).\n */\n public reset(current: T): void {\n this.baseline = current;\n }\n}\n\n/**\n * Creates a DirtyTracker instance.\n */\nexport function createDirtyTracker<T>(\n initialBaseline: T,\n options?: DirtyTrackerOptions<T> | ((a: T, b: T) => boolean),\n): DirtyTracker<T> {\n return new DirtyTracker(initialBaseline, options);\n}\n","import {\n Command,\n HistoryManagerOptions,\n HistoryState,\n MergedExecutionOptions,\n SnapshotCommandOptions,\n} from \"./types\";\n\n/**\n * UI-agnostic History and Undo/Redo manager supporting command closures,\n * snapshot diffs, transaction batching, and high-frequency event coalescing.\n */\nexport class HistoryManager {\n private undoStack: Command[] = [];\n private redoStack: Command[] = [];\n private readonly maxDepth: number;\n private isApplying = false;\n private batchDepth = 0;\n private currentBatch: Command[] | null = null;\n private listeners: Set<(state: HistoryState) => void> = new Set();\n private onStateChange?: (state: HistoryState) => void;\n private cachedState: HistoryState;\n\n constructor(options: HistoryManagerOptions = {}) {\n this.maxDepth = options.maxDepth ?? 50;\n this.onStateChange = options.onStateChange;\n this.cachedState = this.computeState();\n }\n\n private computeState(): HistoryState {\n const canUndo = this.undoStack.length > 0;\n const canRedo = this.redoStack.length > 0;\n return {\n canUndo,\n canRedo,\n undoName: canUndo ? this.undoStack[this.undoStack.length - 1].name : \"\",\n redoName: canRedo ? this.redoStack[this.redoStack.length - 1].name : \"\",\n undoCount: this.undoStack.length,\n redoCount: this.redoStack.length,\n };\n }\n\n /**\n * Returns a snapshot of the current history state.\n * Cached to maintain referential equality across renders for useSyncExternalStore.\n */\n public getState(): HistoryState {\n return this.cachedState;\n }\n\n private notify(): void {\n this.cachedState = this.computeState();\n const state = this.cachedState;\n this.onStateChange?.(state);\n this.listeners.forEach((listener) => {\n try {\n listener(state);\n } catch (err) {\n console.error(\"[HistoryManager] Error in state listener:\", err);\n }\n });\n }\n\n /**\n * Executes a command and pushes it onto the undo stack.\n * Clears the redo stack.\n */\n public execute(command: Command): void {\n if (this.isApplying) {\n command.execute();\n return;\n }\n\n if (this.batchDepth > 0 && this.currentBatch) {\n command.execute();\n this.currentBatch.push({\n ...command,\n timestamp: command.timestamp ?? Date.now(),\n });\n return;\n }\n\n command.execute();\n\n this.undoStack.push({\n ...command,\n timestamp: command.timestamp ?? Date.now(),\n });\n\n if (this.undoStack.length > this.maxDepth) {\n this.undoStack.shift();\n }\n\n this.redoStack = [];\n this.notify();\n }\n\n /**\n * Executes a command, coalescing it with the previous command if they share\n * the same `tag` and occurred within `windowMs` (default: 300ms).\n * Useful for high-frequency interactions like slider scrubs or node drags.\n */\n public executeMerged(\n command: Command,\n options: MergedExecutionOptions = {},\n ): void {\n const windowMs = options.windowMs ?? 300;\n const now = Date.now();\n\n if (\n command.tag &&\n this.undoStack.length > 0 &&\n this.batchDepth === 0 &&\n !this.isApplying\n ) {\n const top = this.undoStack[this.undoStack.length - 1];\n const elapsed = top.timestamp ? now - top.timestamp : Infinity;\n\n if (top.tag === command.tag && elapsed <= windowMs) {\n command.execute();\n // Replace top with merged command keeping the original initial undo\n const initialUndo = top.undo;\n this.undoStack[this.undoStack.length - 1] = {\n name: command.name,\n tag: command.tag,\n timestamp: now,\n execute: command.execute,\n undo: initialUndo,\n redo: command.redo ?? command.execute,\n };\n this.redoStack = [];\n this.notify();\n return;\n }\n }\n\n this.execute({ ...command, timestamp: now });\n }\n\n /**\n * Batches multiple commands executed within `fn` into a single atomic undo entry.\n */\n public batch(name: string, fn: () => void): void {\n if (this.isApplying) {\n fn();\n return;\n }\n\n if (this.batchDepth > 0) {\n // Already inside a batch; execute directly\n fn();\n return;\n }\n\n this.batchDepth++;\n this.currentBatch = [];\n\n try {\n fn();\n } finally {\n this.batchDepth--;\n const batchCommands = this.currentBatch;\n this.currentBatch = null;\n\n if (batchCommands && batchCommands.length > 0) {\n const compoundCommand: Command = {\n name,\n timestamp: Date.now(),\n execute: () => {\n for (let i = 0; i < batchCommands.length; i++) {\n (batchCommands[i].redo ?? batchCommands[i].execute)();\n }\n },\n undo: () => {\n for (let i = batchCommands.length - 1; i >= 0; i--) {\n batchCommands[i].undo();\n }\n },\n redo: () => {\n for (let i = 0; i < batchCommands.length; i++) {\n (batchCommands[i].redo ?? batchCommands[i].execute)();\n }\n },\n };\n\n this.undoStack.push(compoundCommand);\n if (this.undoStack.length > this.maxDepth) {\n this.undoStack.shift();\n }\n this.redoStack = [];\n this.notify();\n }\n }\n }\n\n /**\n * Reverts the most recent command on the undo stack.\n * Returns true if a command was undone, false otherwise.\n */\n public undo(): boolean {\n if (this.undoStack.length === 0 || this.isApplying || this.batchDepth > 0) {\n return false;\n }\n\n this.isApplying = true;\n try {\n const command = this.undoStack.pop()!;\n command.undo();\n this.redoStack.push(command);\n return true;\n } finally {\n this.isApplying = false;\n this.notify();\n }\n }\n\n /**\n * Re-applies the most recent undone command on the redo stack.\n * Returns true if a command was redone, false otherwise.\n */\n public redo(): boolean {\n if (this.redoStack.length === 0 || this.isApplying || this.batchDepth > 0) {\n return false;\n }\n\n this.isApplying = true;\n try {\n const command = this.redoStack.pop()!;\n (command.redo ?? command.execute)();\n this.undoStack.push(command);\n return true;\n } finally {\n this.isApplying = false;\n this.notify();\n }\n }\n\n /**\n * Clears both undo and redo stacks.\n */\n public clear(): void {\n this.undoStack = [];\n this.redoStack = [];\n this.notify();\n }\n\n /**\n * Subscribes to history state changes.\n * The listener is immediately invoked with the current state.\n * Returns an unsubscribe function.\n */\n public subscribe(listener: (state: HistoryState) => void): () => void {\n this.listeners.add(listener);\n listener(this.getState());\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n /**\n * Utility helper to create a Command from before/after state snapshots.\n */\n public static createSnapshotCommand<T>(\n options: SnapshotCommandOptions<T>,\n ): Command {\n return {\n name: options.name,\n tag: options.tag,\n execute: () => options.apply(options.after),\n undo: () => options.apply(options.before),\n redo: () => options.apply(options.after),\n };\n }\n}\n\n/**\n * Creates and initializes a new HistoryManager instance.\n */\nexport function createHistoryManager(\n options: HistoryManagerOptions = {},\n): HistoryManager {\n return new HistoryManager(options);\n}\n","import dagre from '@dagrejs/dagre';\nimport type {\n\tCanvasEdge,\n\tCanvasLayoutOptions,\n\tCanvasNode,\n\tIncrementalLayoutOptions,\n\tPlaceBesideOptions,\n\tRect,\n\tSide,\n\tXYPosition\n} from './types.js';\n\nexport const DEFAULT_NODE_WIDTH = 200;\nexport const DEFAULT_NODE_HEIGHT = 60;\nexport const DEFAULT_PLACEMENT_GAP = 48;\n\n/**\n * Calculates upper-left flow coordinate for an element to be centered in the viewport.\n */\nexport function getCenteredNodePosition(\n\twidth = 0,\n\theight = 0,\n\tscreenToFlowPosition: (position: XYPosition) => XYPosition,\n\tscreenDimensions?: { width: number; height: number }\n): XYPosition {\n\tconst rect =\n\t\tscreenDimensions ??\n\t\t(typeof document !== 'undefined'\n\t\t\t? { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight }\n\t\t\t: { width: 1920, height: 1080 });\n\n\tconst flowPos = screenToFlowPosition({ x: rect.width / 2, y: rect.height / 2 });\n\treturn {\n\t\tx: flowPos.x - width / 2,\n\t\ty: flowPos.y - height / 2\n\t};\n}\n\n/**\n * Updates positions of nodes so their collective bounding box is centered in the current viewport.\n */\nexport function centerNodes<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[],\n\tscreenToFlowPosition: (position: XYPosition) => XYPosition,\n\tgetNodesBounds: (nodes: TNode[]) => Rect,\n\tscreenDimensions?: { width: number; height: number }\n): TNode[] {\n\tif (nodes.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst bounds = getNodesBounds(nodes);\n\tconst boundingBoxOrigin = { x: bounds.x, y: bounds.y };\n\n\tconst centeredPosition = getCenteredNodePosition(\n\t\tbounds.width,\n\t\tbounds.height,\n\t\tscreenToFlowPosition,\n\t\tscreenDimensions\n\t);\n\n\tconst deltaX = centeredPosition.x - boundingBoxOrigin.x;\n\tconst deltaY = centeredPosition.y - boundingBoxOrigin.y;\n\n\treturn nodes.map((node) => ({\n\t\t...node,\n\t\tposition: {\n\t\t\tx: node.position.x + deltaX,\n\t\t\ty: node.position.y + deltaY\n\t\t}\n\t}));\n}\n\n/**\n * Automatically calculates directed hierarchical layout of nodes and edges using Dagre.\n */\nexport function getLayoutedNodes<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[],\n\tgetNodesBounds?: (nodes: TNode[]) => Rect,\n\toptions: CanvasLayoutOptions = {}\n): TNode[] {\n\tif (nodes.length === 0) return [];\n\n\tconst {\n\t\tdirection = 'LR',\n\t\tranksep = 100,\n\t\tnodesep = 25,\n\t\tdefaultNodeWidth = DEFAULT_NODE_WIDTH,\n\t\tdefaultNodeHeight = DEFAULT_NODE_HEIGHT\n\t} = options;\n\n\tconst dagreGraph = new dagre.graphlib.Graph();\n\tdagreGraph.setDefaultEdgeLabel(() => ({}));\n\tdagreGraph.setGraph({ rankdir: direction, ranksep, nodesep });\n\n\tconst nodeIds = new Set(nodes.map((node) => node.id));\n\n\tnodes.forEach((node) => {\n\t\tconst nodeWidth = node.measured?.width ?? (node as any).width ?? defaultNodeWidth;\n\t\tconst nodeHeight = node.measured?.height ?? (node as any).height ?? defaultNodeHeight;\n\t\tdagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight });\n\t});\n\n\tedges.forEach((edge) => {\n\t\tif (nodeIds.has(edge.source) && nodeIds.has(edge.target)) {\n\t\t\tdagreGraph.setEdge(edge.source, edge.target);\n\t\t}\n\t});\n\n\tdagre.layout(dagreGraph);\n\n\treturn nodes.map((node) => {\n\t\tconst nodeWithPosition = dagreGraph.node(node.id);\n\t\tconst nodeWidth = node.measured?.width ?? (node as any).width ?? defaultNodeWidth;\n\t\tconst nodeHeight = node.measured?.height ?? (node as any).height ?? defaultNodeHeight;\n\n\t\treturn {\n\t\t\t...node,\n\t\t\tposition: {\n\t\t\t\tx: nodeWithPosition.x - nodeWidth / 2,\n\t\t\t\ty: nodeWithPosition.y - nodeHeight / 2\n\t\t\t}\n\t\t};\n\t});\n}\n\n/**\n * Heuristic text-based node size estimator when DOM measurement is not available.\n */\nexport function estimateNodeSize(\n\tnode: CanvasNode,\n\tdefaultWidth = DEFAULT_NODE_WIDTH,\n\tdefaultHeight = DEFAULT_NODE_HEIGHT\n): { width: number; height: number } {\n\tconst label = String(node.data?.label ?? node.data?.title ?? node.id ?? '');\n\tconst lines = label.split(/\\n|<br\\s*\\/?>/);\n\tconst longest = Math.max(...lines.map((l) => l.replace(/<[^>]+>/g, '').length), 1);\n\tconst width = Math.min(480, Math.max(defaultWidth, longest * 8 + 48));\n\tconst height = Math.max(defaultHeight, lines.length * 20 + 24);\n\treturn { width, height };\n}\n\n/**\n * Computes bounding rectangle of an array of rectangles.\n */\nexport function boundsOf(rects: Rect[]): Rect | null {\n\tif (!rects.length) return null;\n\tconst minX = Math.min(...rects.map((r) => r.x));\n\tconst minY = Math.min(...rects.map((r) => r.y));\n\tconst maxX = Math.max(...rects.map((r) => r.x + r.width));\n\tconst maxY = Math.max(...rects.map((r) => r.y + r.height));\n\treturn { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\n/**\n * Center coordinate of a rectangle.\n */\nexport function centre(r: Rect): XYPosition {\n\treturn { x: r.x + r.width / 2, y: r.y + r.height / 2 };\n}\n\n/**\n * Determines whether two rectangles overlap, including an optional padding distance.\n */\nexport function overlaps(a: Rect, b: Rect, pad = 16): boolean {\n\treturn (\n\t\ta.x < b.x + b.width + pad &&\n\t\ta.x + a.width + pad > b.x &&\n\t\ta.y < b.y + b.height + pad &&\n\t\ta.y + a.height + pad > b.y\n\t);\n}\n\n/**\n * Maps directed layout flow to its natural forward growth side.\n */\nexport function flowSide(direction: 'LR' | 'TB' | 'RL' | 'BT' = 'LR'): Side {\n\tswitch (direction) {\n\t\tcase 'LR':\n\t\t\treturn 'right';\n\t\tcase 'RL':\n\t\t\treturn 'left';\n\t\tcase 'BT':\n\t\t\treturn 'above';\n\t\tcase 'TB':\n\t\tdefault:\n\t\t\treturn 'below';\n\t}\n}\n\n/**\n * Incremental layout blending:\n * Keeps established/manual node positions intact. Runs Dagre on the entire graph,\n * computes the centroid translation offset between auto and stored positions of existing nodes,\n * and places unpositioned/new nodes at (auto + offset).\n */\nexport function ensureLayout<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[],\n\toptions: IncrementalLayoutOptions = {}\n): TNode[] {\n\tif (nodes.length === 0) return [];\n\n\tconst stored = options.storedPositions ?? {};\n\tconst missing = nodes.filter((n) => !stored[n.id]);\n\n\t// Case 1: Every node has an established coordinate -> preserve verbatim\n\tif (missing.length === 0) {\n\t\treturn nodes.map((n) => ({\n\t\t\t...n,\n\t\t\tposition: { ...stored[n.id]! }\n\t\t}));\n\t}\n\n\t// Calculate full dagre auto-layout\n\tconst autoLayouted = getLayoutedNodes(nodes, edges, undefined, options);\n\tconst autoMap = new Map<string, XYPosition>(\n\t\tautoLayouted.map((n) => [n.id, n.position])\n\t);\n\n\t// Case 2: No nodes have stored coordinates -> return auto layout directly\n\tconst both = nodes.filter((n) => stored[n.id] && autoMap.has(n.id));\n\tif (both.length === 0) {\n\t\treturn autoLayouted;\n\t}\n\n\t// Case 3: Blend! Align on centroid translation offset of overlapping nodes\n\tlet dx = 0;\n\tlet dy = 0;\n\tfor (const n of both) {\n\t\tconst s = stored[n.id]!;\n\t\tconst a = autoMap.get(n.id)!;\n\t\tdx += s.x - a.x;\n\t\tdy += s.y - a.y;\n\t}\n\tdx /= both.length;\n\tdy /= both.length;\n\n\treturn nodes.map((node) => {\n\t\tif (stored[node.id]) {\n\t\t\treturn {\n\t\t\t\t...node,\n\t\t\t\tposition: { ...stored[node.id]! }\n\t\t\t};\n\t\t}\n\t\tconst autoPos = autoMap.get(node.id) ?? { x: 0, y: 0 };\n\t\treturn {\n\t\t\t...node,\n\t\t\tposition: {\n\t\t\t\tx: Math.round(autoPos.x + dx),\n\t\t\t\ty: Math.round(autoPos.y + dy)\n\t\t\t}\n\t\t};\n\t});\n}\n\n/**\n * Finds a free top-left coordinate for a node of `size` adjacent to `nearNodeId` (or the cluster),\n * sliding along the perpendicular axis past any intersecting bounding boxes to guarantee non-overlapping placement.\n */\nexport function placeBeside(\n\trects: Record<string, Rect>,\n\tsize: { width: number; height: number },\n\tside: Side,\n\tnearNodeId?: string,\n\toptions: PlaceBesideOptions = {}\n): XYPosition {\n\tconst {\n\t\tgap = DEFAULT_PLACEMENT_GAP,\n\t\tignore = [],\n\t\tmaxAttempts = 32\n\t} = options;\n\n\tconst skip = new Set([nearNodeId, ...ignore].filter(Boolean));\n\tconst obstacles = Object.entries(rects)\n\t\t.filter(([id]) => !skip.has(id))\n\t\t.map(([, r]) => r);\n\n\tconst anchor =\n\t\t(nearNodeId && rects[nearNodeId]) ||\n\t\tboundsOf(Object.values(rects)) ||\n\t\t{ x: 0, y: 0, width: 0, height: 0 };\n\n\tconst anchorCenter = centre(anchor);\n\n\tlet baseX: number;\n\tlet baseY: number;\n\n\tswitch (side) {\n\t\tcase 'right':\n\t\t\tbaseX = anchor.x + anchor.width + gap;\n\t\t\tbaseY = anchorCenter.y - size.height / 2;\n\t\t\tbreak;\n\t\tcase 'left':\n\t\t\tbaseX = anchor.x - gap - size.width;\n\t\t\tbaseY = anchorCenter.y - size.height / 2;\n\t\t\tbreak;\n\t\tcase 'above':\n\t\t\tbaseX = anchorCenter.x - size.width / 2;\n\t\t\tbaseY = anchor.y - gap - size.height;\n\t\t\tbreak;\n\t\tcase 'below':\n\t\tdefault:\n\t\t\tbaseX = anchorCenter.x - size.width / 2;\n\t\t\tbaseY = anchor.y + anchor.height + gap;\n\t\t\tbreak;\n\t}\n\n\t// Slide perpendicular to growth direction, alternating positive and negative steps (+1, -1, +2, -2...)\n\tconst isHorizontal = side === 'right' || side === 'left';\n\tconst step = (isHorizontal ? size.height : size.width) + 20;\n\n\tfor (let i = 0; i < maxAttempts; i++) {\n\t\tconst offset = i === 0 ? 0 : Math.ceil(i / 2) * step * (i % 2 === 1 ? 1 : -1);\n\t\tconst candidateBox: Rect = {\n\t\t\tx: isHorizontal ? baseX : baseX + offset,\n\t\t\ty: isHorizontal ? baseY + offset : baseY,\n\t\t\twidth: size.width,\n\t\t\theight: size.height\n\t\t};\n\n\t\tif (!obstacles.some((obstacle) => overlaps(candidateBox, obstacle, 8))) {\n\t\t\treturn {\n\t\t\t\tx: Math.round(candidateBox.x),\n\t\t\t\ty: Math.round(candidateBox.y)\n\t\t\t};\n\t\t}\n\t}\n\n\treturn {\n\t\tx: Math.round(baseX),\n\t\ty: Math.round(baseY)\n\t};\n}\n","/**\n * The time source that canvas animations and agent performances play on.\n *\n * Defaults to `realClock` (requestAnimationFrame and setTimeout).\n * A `ManualClock` moves only when told to via `advance(ms)` or `tick(fps)`,\n * enabling deterministic frame-by-frame stepping for testing, video generation,\n * or headless server environments.\n */\n\nexport interface Clock {\n\t/** Current time in milliseconds. */\n\tnow(): number;\n\t/** Resolves on the next animation frame. */\n\tframe(): Promise<void>;\n\t/** Resolves after `ms` milliseconds of this clock's time. */\n\tsleep(ms: number): Promise<void>;\n\t/**\n\t * Whether the clock follows wall time. Live clocks stop or degrade when the\n\t * tab is in the background (browsers pause animation frames), so transitions\n\t * can commit immediately rather than leaving operations hanging.\n\t */\n\treadonly live: boolean;\n}\n\n/** Whether the browser tab is hidden (where RAF pauses). */\nexport const pageHidden = (): boolean =>\n\ttypeof document !== 'undefined' && document.hidden;\n\n/** Real-time clock using requestAnimationFrame and setTimeout. */\nexport const realClock: Clock = {\n\tlive: true,\n\tnow: () => (typeof performance !== 'undefined' ? performance.now() : Date.now()),\n\tframe: () =>\n\t\tnew Promise<void>((resolve) => {\n\t\t\tif (typeof requestAnimationFrame === 'function' && !pageHidden()) {\n\t\t\t\trequestAnimationFrame(() => resolve());\n\t\t\t} else {\n\t\t\t\tsetTimeout(resolve, 16);\n\t\t\t}\n\t\t}),\n\tsleep: (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, Math.max(0, ms)))\n};\n\nconst settle = () => new Promise<void>((resolve) => setTimeout(resolve, 0));\n\n/**\n * A deterministic clock that only moves forward when `advance` or `tick` is called.\n * Allows step-by-step frame testing and video rendering without waiting for real time.\n */\nexport class ManualClock implements Clock {\n\treadonly live = false;\n\tprivate time: number;\n\tprivate frames: (() => void)[] = [];\n\tprivate sleepers: { at: number; seq: number; resolve: () => void }[] = [];\n\tprivate seq = 0;\n\n\tconstructor(start = 0) {\n\t\tthis.time = start;\n\t}\n\n\tpublic now(): number {\n\t\treturn this.time;\n\t}\n\n\tpublic frame(): Promise<void> {\n\t\treturn new Promise<void>((resolve) => this.frames.push(resolve));\n\t}\n\n\tpublic sleep(ms: number): Promise<void> {\n\t\treturn new Promise<void>((resolve) =>\n\t\t\tthis.sleepers.push({\n\t\t\t\tat: this.time + Math.max(0, ms),\n\t\t\t\tseq: this.seq++,\n\t\t\t\tresolve\n\t\t\t})\n\t\t);\n\t}\n\n\t/** Whether any frames or sleep timers are currently pending. */\n\tpublic get pending(): boolean {\n\t\treturn this.frames.length > 0 || this.sleepers.length > 0;\n\t}\n\n\t/** Advances time by `ms`, resolving due sleep timers in order, followed by queued frames. */\n\tpublic async advance(ms: number): Promise<void> {\n\t\tconst end = this.time + Math.max(0, ms);\n\t\tawait settle();\n\n\t\twhile (true) {\n\t\t\tlet next: (typeof this.sleepers)[number] | undefined;\n\t\t\tfor (const s of this.sleepers) {\n\t\t\t\tif (s.at <= end && (!next || s.at < next.at || (s.at === next.at && s.seq < next.seq))) {\n\t\t\t\t\tnext = s;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!next) break;\n\n\t\t\tthis.sleepers.splice(this.sleepers.indexOf(next), 1);\n\t\t\tthis.time = Math.max(this.time, next.at);\n\t\t\tnext.resolve();\n\t\t\tawait settle();\n\t\t}\n\n\t\tthis.time = end;\n\t\tconst dueFrames = this.frames.splice(0, this.frames.length);\n\t\tfor (const resolveFrame of dueFrames) {\n\t\t\tresolveFrame();\n\t\t}\n\t\tawait settle();\n\t}\n\n\t/** Convenience method to advance by 1 frame at a given fps (default: 60fps = 16.67ms). */\n\tpublic async tick(fps = 60): Promise<void> {\n\t\tawait this.advance(Math.round(1000 / fps));\n\t}\n}\n","import type {\n\tCanvasNode,\n\tFanOutTrajectoryOptions,\n\tNodeTransition,\n\tTrajectoryFunction,\n\tTrajectoryPoint,\n\tXYPosition\n} from './types.js';\n\n/**\n * Standard cubic ease-out function (pure math, framework-agnostic).\n */\nexport const defaultEasing = (t: number): number => --t * t * t + 1;\n\n/**\n * Standard linear trajectory: straight line interpolation with linear scale & opacity progression.\n */\nexport const linearTrajectory: TrajectoryFunction = (\n\torigin: XYPosition,\n\ttarget: XYPosition,\n\tprogress: number\n): TrajectoryPoint => {\n\treturn {\n\t\tposition: {\n\t\t\tx: origin.x + (target.x - origin.x) * progress,\n\t\t\ty: origin.y + (target.y - origin.y) * progress\n\t\t},\n\t\tscale: progress,\n\t\topacity: Math.min(1, progress * 1.5)\n\t};\n};\n\n/**\n * Linear position trajectory: pure position interpolation without altering scale or opacity.\n */\nexport const linearPositionTrajectory: TrajectoryFunction = (\n\torigin: XYPosition,\n\ttarget: XYPosition,\n\tprogress: number\n): TrajectoryPoint => {\n\treturn {\n\t\tposition: {\n\t\t\tx: origin.x + (target.x - origin.x) * progress,\n\t\t\ty: origin.y + (target.y - origin.y) * progress\n\t\t}\n\t};\n};\n\n/**\n * Creates a fan-out trajectory where nodes arc outward from origin to target.\n */\nexport function createFanOutTrajectory(options: FanOutTrajectoryOptions = {}): TrajectoryFunction {\n\tconst {\n\t\tcurvature = 0.4,\n\t\tstartScale = 0,\n\t\tendScale = 1,\n\t\tstartOpacity = 0,\n\t\tendOpacity = 1\n\t} = options;\n\n\treturn (\n\t\torigin: XYPosition,\n\t\ttarget: XYPosition,\n\t\tprogress: number,\n\t\tindex: number,\n\t\ttotal: number\n\t): TrajectoryPoint => {\n\t\tconst dx = target.x - origin.x;\n\t\tconst dy = target.y - origin.y;\n\n\t\t// Normalized index from -1 (top) to +1 (bottom)\n\t\tconst normIndex = total > 1 ? (index - (total - 1) / 2) / ((total - 1) / 2) : 0;\n\n\t\t// Perpendicular control point offset to create smooth fan arc\n\t\tconst midX = origin.x + dx * 0.4;\n\t\tconst midY = origin.y + dy * 0.1 - normIndex * Math.abs(dx) * 0.15 * curvature;\n\n\t\t// Quadratic Bezier interpolation: B(t) = (1-t)^2 * P0 + 2(1-t)t * P1 + t^2 * P2\n\t\tconst t = progress;\n\t\tconst oneMinusT = 1 - t;\n\n\t\tconst x = oneMinusT * oneMinusT * origin.x + 2 * oneMinusT * t * midX + t * t * target.x;\n\t\tconst y = oneMinusT * oneMinusT * origin.y + 2 * oneMinusT * t * midY + t * t * target.y;\n\n\t\tconst scale = startScale + (endScale - startScale) * progress;\n\t\tconst opacity = startOpacity + (endOpacity - startOpacity) * progress;\n\n\t\treturn {\n\t\t\tposition: { x, y },\n\t\t\tscale,\n\t\t\topacity\n\t\t};\n\t};\n}\n\n/**\n * Creates a custom quadratic Bezier trajectory with a specified control point resolver.\n */\nexport function createBezierTrajectory(\n\tgetControlPoint: (origin: XYPosition, target: XYPosition) => XYPosition\n): TrajectoryFunction {\n\treturn (origin: XYPosition, target: XYPosition, progress: number): TrajectoryPoint => {\n\t\tconst cp = getControlPoint(origin, target);\n\t\tconst t = progress;\n\t\tconst oneMinusT = 1 - t;\n\n\t\tconst x = oneMinusT * oneMinusT * origin.x + 2 * oneMinusT * t * cp.x + t * t * target.x;\n\t\tconst y = oneMinusT * oneMinusT * origin.y + 2 * oneMinusT * t * cp.y + t * t * target.y;\n\n\t\treturn {\n\t\t\tposition: { x, y },\n\t\t\tscale: progress,\n\t\t\topacity: progress\n\t\t};\n\t};\n}\n\nimport { realClock, type Clock } from './clock.js';\n\n/**\n * Coordinates and animates multiple node transitions simultaneously with zero per-frame array allocations.\n */\nexport function runMultiNodeTransition<TNode extends CanvasNode = CanvasNode>(\n\ttransitions: NodeTransition<TNode>[],\n\toptions: {\n\t\tdefaultDuration?: number;\n\t\tdefaultEasing?: (t: number) => number;\n\t\tclock?: Clock;\n\t\tonUpdate?: () => void;\n\t\tonComplete?: () => void;\n\t} = {}\n): () => void {\n\tif (transitions.length === 0) {\n\t\toptions.onComplete?.();\n\t\treturn () => {};\n\t}\n\n\tconst {\n\t\tdefaultDuration = 400,\n\t\tdefaultEasing: easingFunc = defaultEasing,\n\t\tclock = realClock,\n\t\tonUpdate,\n\t\tonComplete\n\t} = options;\n\n\tlet isCancelled = false;\n\tconst startTime = clock.now();\n\n\tconst items = transitions.map((tr, i) => ({\n\t\t...tr,\n\t\tindex: tr.index ?? i,\n\t\ttotal: tr.total ?? transitions.length,\n\t\tduration: tr.duration ?? defaultDuration,\n\t\teasing: tr.easing ?? easingFunc,\n\t\tdelay: tr.delay ?? 0,\n\t\ttrajectory: tr.trajectory ?? linearTrajectory\n\t}));\n\n\tfunction frame() {\n\t\tif (isCancelled) return;\n\n\t\tconst now = clock.now();\n\t\tlet allCompleted = true;\n\n\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\tconst item = items[i];\n\t\t\tconst elapsed = now - (startTime + item.delay);\n\n\t\t\tif (elapsed < 0) {\n\t\t\t\tallCompleted = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Guard zero duration and division by zero (referenced in GOTCHAS.md)\n\t\t\tconst rawProgress = item.duration <= 0 ? 1 : Math.min(elapsed / item.duration, 1);\n\t\t\tconst progress = item.duration <= 0 ? 1 : item.easing(rawProgress);\n\n\t\t\tconst point = item.trajectory(item.from, item.to, progress, item.index, item.total);\n\n\t\t\titem.node.position = { ...point.position };\n\n\t\t\tif (point.scale !== undefined || point.opacity !== undefined) {\n\t\t\t\tif (!item.node.data) {\n\t\t\t\t\titem.node.data = {} as any;\n\t\t\t\t}\n\t\t\t\tif (point.scale !== undefined) {\n\t\t\t\t\t(item.node.data as any).scale = point.scale;\n\t\t\t\t}\n\t\t\t\tif (point.opacity !== undefined) {\n\t\t\t\t\t(item.node.data as any).opacity = point.opacity;\n\t\t\t\t\tconst currentStyle = (item.node.style || '').replace(/opacity:\\s*[^;]+;?/g, '').trim();\n\t\t\t\t\titem.node.style = `${currentStyle ? currentStyle + '; ' : ''}opacity: ${point.opacity};`;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rawProgress < 1) {\n\t\t\t\tallCompleted = false;\n\t\t\t}\n\t\t}\n\n\t\tonUpdate?.();\n\n\t\tif (!allCompleted) {\n\t\t\tclock.frame().then(frame);\n\t\t} else {\n\t\t\tonComplete?.();\n\t\t}\n\t}\n\n\tframe();\n\n\treturn () => {\n\t\tisCancelled = true;\n\t};\n}\n","import dagre from '@dagrejs/dagre';\nimport type {\n\tCanvasEdge,\n\tCanvasNode,\n\tDirectionalDisplacementOptions,\n\tRect,\n\tReflowDisplacementOptions,\n\tXYPosition\n} from './types.js';\n\n/**\n * Calculates a bounding rectangle for a set of nodes if not provided by getNodesBounds.\n */\nexport function computeNodesBoundingBox<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[],\n\tdefaultWidth = 200,\n\tdefaultHeight = 60\n): Rect {\n\tif (nodes.length === 0) {\n\t\treturn { x: 0, y: 0, width: 0, height: 0 };\n\t}\n\n\tlet minX = Infinity;\n\tlet minY = Infinity;\n\tlet maxX = -Infinity;\n\tlet maxY = -Infinity;\n\n\tfor (const node of nodes) {\n\t\tconst width = node.measured?.width ?? (node as any).width ?? defaultWidth;\n\t\tconst height = node.measured?.height ?? (node as any).height ?? defaultHeight;\n\n\t\tminX = Math.min(minX, node.position.x);\n\t\tminY = Math.min(minY, node.position.y);\n\t\tmaxX = Math.max(maxX, node.position.x + width);\n\t\tmaxY = Math.max(maxY, node.position.y + height);\n\t}\n\n\treturn {\n\t\tx: minX,\n\t\ty: minY,\n\t\twidth: maxX - minX,\n\t\theight: maxY - minY\n\t};\n}\n\n/**\n * Pure directional displacement calculation.\n * Shifts downstream or surrounding nodes along an axis to clear space for newly inserted child nodes.\n */\nexport function calculateDirectionalDisplacement<TNode extends CanvasNode = CanvasNode>(params: {\n\texistingNodes: TNode[];\n\toriginNode: TNode;\n\tchildNodes: TNode[];\n\tgetNodesBounds?: (nodes: TNode[]) => Rect;\n\toptions?: DirectionalDisplacementOptions;\n}): Map<string, XYPosition> {\n\tconst {\n\t\texistingNodes,\n\t\toriginNode,\n\t\tchildNodes,\n\t\tgetNodesBounds,\n\t\toptions = {}\n\t} = params;\n\n\tconst {\n\t\tdirection = 'right',\n\t\tgap = 40,\n\t\tspreadSiblingLanes = false,\n\t\tsiblingTolerance = 50,\n\t\tminY\n\t} = options;\n\n\tconst displacedMap = new Map<string, XYPosition>();\n\tif (childNodes.length === 0 || existingNodes.length === 0) {\n\t\treturn displacedMap;\n\t}\n\n\tconst childBounds = getNodesBounds\n\t\t? getNodesBounds(childNodes)\n\t\t: computeNodesBoundingBox(childNodes);\n\n\tconst originWidth = originNode.measured?.width ?? (originNode as any).width ?? 200;\n\tconst originHeight = originNode.measured?.height ?? (originNode as any).height ?? 60;\n\n\t// The delta space required along primary axis\n\tconst deltaPrimary =\n\t\tdirection === 'right' || direction === 'left'\n\t\t\t? childBounds.width + gap\n\t\t\t: childBounds.height + gap;\n\n\t// Vertical displacement parameters: upward and downward row clearance\n\tconst deltaUp = Math.max(0, originNode.position.y - childBounds.y + gap);\n\tconst deltaDown = Math.max(\n\t\t0,\n\t\tchildBounds.y + childBounds.height - (originNode.position.y + originHeight) + gap\n\t);\n\n\t// Both above and below displace equally so the row expands symmetrically\n\tconst equalDelta = Math.max(deltaUp, deltaDown);\n\n\tfor (const node of existingNodes) {\n\t\tif (node.id === originNode.id) continue;\n\n\t\tconst isSiblingRow =\n\t\t\tMath.abs(node.position.y - originNode.position.y) < siblingTolerance;\n\n\t\tswitch (direction) {\n\t\t\tcase 'right': {\n\t\t\t\tif (node.position.x > originNode.position.x) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x + deltaPrimary,\n\t\t\t\t\t\ty: node.position.y\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'left': {\n\t\t\t\tif (node.position.x < originNode.position.x) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x - deltaPrimary,\n\t\t\t\t\t\ty: node.position.y\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'down': {\n\t\t\t\tif (node.position.y > originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y + deltaPrimary\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'up': {\n\t\t\t\tif (node.position.y < originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y - deltaPrimary\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'vertical': {\n\t\t\t\tif (isSiblingRow) break;\n\n\t\t\t\tif (node.position.y < originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y - equalDelta\n\t\t\t\t\t});\n\t\t\t\t} else if (node.position.y > originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y + equalDelta\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Sibling lane spreading to avoid overlap among child nodes\n\tif (spreadSiblingLanes && (direction === 'right' || direction === 'left')) {\n\t\tfor (const [nodeId, pos] of displacedMap.entries()) {\n\t\t\tconst node = existingNodes.find((n) => n.id === nodeId);\n\t\t\tif (node && Math.abs(node.position.y - originNode.position.y) < siblingTolerance) {\n\t\t\t\tconst isAbove = node.position.y < originNode.position.y;\n\t\t\t\tdisplacedMap.set(nodeId, {\n\t\t\t\t\tx: pos.x,\n\t\t\t\t\ty: pos.y + (isAbove ? -deltaUp : deltaDown)\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// Floor constraint\n\tif (minY !== undefined) {\n\t\tfor (const [nodeId, pos] of displacedMap.entries()) {\n\t\t\tif (pos.y < minY) {\n\t\t\t\tdisplacedMap.set(nodeId, { x: pos.x, y: minY });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn displacedMap;\n}\n\n/**\n * Calculates Dagre reflow displacement preserving the position of an anchor node.\n */\nexport function calculateDagreReflowDisplacement<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(params: {\n\tcurrentNodes: TNode[];\n\tcurrentEdges: TEdge[];\n\tfutureNodes: TNode[];\n\tfutureEdges: TEdge[];\n\toptions: ReflowDisplacementOptions;\n\tgetNodesBounds?: (nodes: TNode[]) => Rect;\n}): Map<string, XYPosition> {\n\tconst {\n\t\tcurrentNodes,\n\t\tfutureNodes,\n\t\tfutureEdges,\n\t\toptions\n\t} = params;\n\n\tconst {\n\t\tanchorNodeId,\n\t\tdirection = 'LR',\n\t\tranksep = 100,\n\t\tnodesep = 25,\n\t\tdefaultNodeWidth = 200,\n\t\tdefaultNodeHeight = 60\n\t} = options;\n\n\tconst anchorNode = currentNodes.find((n) => n.id === anchorNodeId);\n\tif (!anchorNode) return new Map();\n\n\tconst g = new dagre.graphlib.Graph();\n\tg.setDefaultEdgeLabel(() => ({}));\n\tg.setGraph({ rankdir: direction, ranksep, nodesep });\n\n\tconst nodeIds = new Set(futureNodes.map((n) => n.id));\n\n\tfutureNodes.forEach((node) => {\n\t\tconst nodeWidth = node.measured?.width ?? (node as any).width ?? defaultNodeWidth;\n\t\tconst nodeHeight = node.measured?.height ?? (node as any).height ?? defaultNodeHeight;\n\t\tg.setNode(node.id, { width: nodeWidth, height: nodeHeight });\n\t});\n\n\tfutureEdges.forEach((edge) => {\n\t\tif (nodeIds.has(edge.source) && nodeIds.has(edge.target)) {\n\t\t\tg.setEdge(edge.source, edge.target);\n\t\t}\n\t});\n\n\tdagre.layout(g);\n\n\tconst anchorLayoutPos = g.node(anchorNodeId);\n\tif (!anchorLayoutPos) return new Map();\n\n\tconst anchorWidth = anchorNode.measured?.width ?? (anchorNode as any).width ?? defaultNodeWidth;\n\tconst anchorHeight = anchorNode.measured?.height ?? (anchorNode as any).height ?? defaultNodeHeight;\n\n\tconst anchorLayoutUpperLeft = {\n\t\tx: anchorLayoutPos.x - anchorWidth / 2,\n\t\ty: anchorLayoutPos.y - anchorHeight / 2\n\t};\n\n\tconst deltaX = anchorNode.position.x - anchorLayoutUpperLeft.x;\n\tconst deltaY = anchorNode.position.y - anchorLayoutUpperLeft.y;\n\n\tconst displacementMap = new Map<string, XYPosition>();\n\n\tcurrentNodes.forEach((node) => {\n\t\tif (node.id === anchorNodeId) return;\n\n\t\tconst layoutNode = g.node(node.id);\n\t\tif (!layoutNode) return;\n\n\t\tconst nodeWidth = node.measured?.width ?? (node as any).width ?? defaultNodeWidth;\n\t\tconst nodeHeight = node.measured?.height ?? (node as any).height ?? defaultNodeHeight;\n\n\t\tconst upperLeftX = layoutNode.x - nodeWidth / 2 + deltaX;\n\t\tconst upperLeftY = layoutNode.y - nodeHeight / 2 + deltaY;\n\n\t\tif (\n\t\t\tMath.abs(upperLeftX - node.position.x) > 1 ||\n\t\t\tMath.abs(upperLeftY - node.position.y) > 1\n\t\t) {\n\t\t\tdisplacementMap.set(node.id, { x: upperLeftX, y: upperLeftY });\n\t\t}\n\t});\n\n\treturn displacementMap;\n}\n","import type {\n\tCanvasClipboardPayload,\n\tCanvasEdge,\n\tCanvasNode,\n\tXYPosition\n} from './types.js';\n\n/**\n * Checks if an event originated from a text input, textarea, contenteditable element, or rich editor.\n */\nexport function isEventFromTextInput(event: Event | { target: EventTarget | null }): boolean {\n\tconst target = (event as any).target as HTMLElement | null;\n\tif (!target) return false;\n\tif (\n\t\ttarget.tagName === 'INPUT' ||\n\t\ttarget.tagName === 'TEXTAREA' ||\n\t\ttarget.tagName === 'SELECT' ||\n\t\ttarget.isContentEditable ||\n\t\ttarget.closest?.('[contenteditable=\"true\"]') ||\n\t\ttarget.closest?.('.ProseMirror')\n\t) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/**\n * Validates that an object conforms to minimal CanvasNode shape.\n */\nexport function isValidCanvasNode(obj: unknown): obj is CanvasNode {\n\treturn (\n\t\ttypeof obj === 'object' &&\n\t\tobj !== null &&\n\t\t'id' in obj &&\n\t\ttypeof (obj as any).id === 'string' &&\n\t\t'position' in obj &&\n\t\ttypeof (obj as any).position === 'object' &&\n\t\t(obj as any).position !== null &&\n\t\t'x' in (obj as any).position &&\n\t\t'y' in (obj as any).position\n\t);\n}\n\n/**\n * Checks if a string is a valid HTTP/HTTPS URL.\n */\nexport function isValidUrl(url: string): boolean {\n\ttry {\n\t\tconst parsed = new URL(url);\n\t\treturn parsed.protocol === 'http:' || parsed.protocol === 'https:';\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Serializes nodes and optional edges into clipboard JSON payload.\n */\nexport function serializeCanvasNodes<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(nodes: TNode[], edges?: TEdge[]): string {\n\tconst payload: CanvasClipboardPayload<TNode, TEdge> = {\n\t\tversion: 1,\n\t\tnodes,\n\t\tedges\n\t};\n\treturn JSON.stringify(payload);\n}\n\n/**\n * Parses raw JSON string into a CanvasClipboardPayload if valid.\n */\nexport function parseCanvasClipboardData<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(raw: string): CanvasClipboardPayload<TNode, TEdge> | null {\n\ttry {\n\t\tconst parsed = JSON.parse(raw);\n\t\tif (\n\t\t\ttypeof parsed === 'object' &&\n\t\t\tparsed !== null &&\n\t\t\tArray.isArray(parsed.nodes) &&\n\t\t\tparsed.nodes.length > 0 &&\n\t\t\tparsed.nodes.every(isValidCanvasNode)\n\t\t) {\n\t\t\treturn parsed as CanvasClipboardPayload<TNode, TEdge>;\n\t\t}\n\t} catch {\n\t\t// Not JSON or invalid payload\n\t}\n\treturn null;\n}\n\n/**\n * Generates unique new IDs for pasted nodes and updates edge references accordingly.\n */\nexport function remapPastedNodes<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[] = [],\n\toffset: XYPosition = { x: 30, y: 30 },\n\tidGenerator: () => string = () => `node-${Math.random().toString(36).substring(2, 9)}`\n): { nodes: TNode[]; edges: TEdge[] } {\n\tconst idMap = new Map<string, string>();\n\n\tconst newNodes = nodes.map((node) => {\n\t\tconst newId = idGenerator();\n\t\tidMap.set(node.id, newId);\n\t\treturn {\n\t\t\t...node,\n\t\t\tid: newId,\n\t\t\tposition: {\n\t\t\t\tx: node.position.x + offset.x,\n\t\t\t\ty: node.position.y + offset.y\n\t\t\t},\n\t\t\tselected: true\n\t\t};\n\t});\n\n\tconst newEdges = edges\n\t\t.filter((e) => idMap.has(e.source) && idMap.has(e.target))\n\t\t.map((edge) => ({\n\t\t\t...edge,\n\t\t\tid: `edge-${Math.random().toString(36).substring(2, 9)}`,\n\t\t\tsource: idMap.get(edge.source)!,\n\t\t\ttarget: idMap.get(edge.target)!,\n\t\t\tselected: false\n\t\t}));\n\n\treturn { nodes: newNodes, edges: newEdges };\n}\n\n/**\n * Repositions nodes so their bounding box origin matches the given target position.\n */\nexport function repositionNodesTo<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[],\n\ttargetOrigin: XYPosition\n): TNode[] {\n\tif (nodes.length === 0) return [];\n\tconst minX = Math.min(...nodes.map((n) => n.position.x));\n\tconst minY = Math.min(...nodes.map((n) => n.position.y));\n\tconst deltaX = targetOrigin.x - minX;\n\tconst deltaY = targetOrigin.y - minY;\n\n\treturn nodes.map((n) => ({\n\t\t...n,\n\t\tposition: {\n\t\t\tx: n.position.x + deltaX,\n\t\t\ty: n.position.y + deltaY\n\t\t}\n\t}));\n}\n","import type { CanvasEdge, CanvasNode, Rect } from './types.js';\n\nexport interface CanvasHeightOptions {\n\t/** Smallest height returned (default 320). */\n\tmin?: number;\n\t/** Largest height returned; taller content is scaled/zoomed (default 560). */\n\tmax?: number;\n\t/** Extra padding around the content (default 48). */\n\tpadding?: number;\n}\n\nfunction clampHeight(contentHeight: number, options: CanvasHeightOptions = {}): number {\n\tconst { min = 320, max = 560, padding = 48 } = options;\n\treturn Math.round(Math.min(max, Math.max(min, contentHeight + padding)));\n}\n\n/**\n * Calculates the bounding box extent of all positioned nodes, or `null` for an empty graph.\n */\nexport function layoutBounds<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[]\n): Rect | null {\n\tif (nodes.length === 0) return null;\n\n\tlet minX = Infinity;\n\tlet minY = Infinity;\n\tlet maxX = -Infinity;\n\tlet maxY = -Infinity;\n\n\tfor (const node of nodes) {\n\t\tconst x = node.position.x;\n\t\tconst y = node.position.y;\n\t\tconst width = node.width ?? 180;\n\t\tconst height = node.height ?? 80;\n\n\t\tminX = Math.min(minX, x);\n\t\tminY = Math.min(minY, y);\n\t\tmaxX = Math.max(maxX, x + width);\n\t\tmaxY = Math.max(maxY, y + height);\n\t}\n\n\tif (minX === Infinity) return null;\n\treturn { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\n/**\n * Returns a clamped container height that fits the layout at 1:1 scale without overflow.\n */\nexport function canvasHeight<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[],\n\toptions?: CanvasHeightOptions\n): number {\n\treturn clampHeight(layoutBounds(nodes)?.height ?? 0, options);\n}\n\nconst DEFAULT_RANK_HEIGHT = 80 + 72; // Average node height + default rank separation\nconst NODES_PER_RANK = 2;\n\n/**\n * Estimates the container height to reserve before layout calculation finishes,\n * based on node and edge counts alone. Prevents layout shift (CLS).\n */\nexport function estimateCanvasHeight<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[],\n\toptions?: CanvasHeightOptions\n): number {\n\tconst ranks = Math.max(1, Math.ceil(nodes.length / NODES_PER_RANK));\n\treturn clampHeight(ranks * DEFAULT_RANK_HEIGHT, options);\n}\n\nfunction mix(a: number, b: number, t: number): number {\n\treturn a + (b - a) * t;\n}\n\n/**\n * Interpolates node positions and sizes between two layouts partway at progress `t` (0 = from, 1 = to).\n * Nodes present in both interpolate smoothly; nodes newly added in `to` snap to target.\n */\nexport function blendLayout<TNode extends CanvasNode = CanvasNode>(\n\tfrom: TNode[],\n\tto: TNode[],\n\tt: number\n): TNode[] {\n\tif (t >= 1) return to;\n\n\tconst fromMap = new Map<string, TNode>(from.map((n) => [n.id, n]));\n\n\treturn to.map((target) => {\n\t\tconst origin = fromMap.get(target.id);\n\t\tif (!origin) return target;\n\n\t\treturn {\n\t\t\t...target,\n\t\t\tposition: {\n\t\t\t\tx: mix(origin.position.x, target.position.x, t),\n\t\t\t\ty: mix(origin.position.y, target.position.y, t)\n\t\t\t},\n\t\t\twidth:\n\t\t\t\torigin.width !== undefined && target.width !== undefined\n\t\t\t\t\t? mix(origin.width, target.width, t)\n\t\t\t\t\t: target.width,\n\t\t\theight:\n\t\t\t\torigin.height !== undefined && target.height !== undefined\n\t\t\t\t\t? mix(origin.height, target.height, t)\n\t\t\t\t\t: target.height\n\t\t};\n\t});\n}\n\n/**\n * Filters out nodes that are not touched by any edge.\n *\n * During LLM streaming, nodes often arrive a chunk or token before the edge\n * that connects them. Displaying them immediately causes them to be placed as root\n * nodes only to jump into their correct position once the edge arrives.\n * Hiding orphan nodes during active streaming keeps the layout calm and jitter-free.\n */\nexport function connectedOnly<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[]\n): TNode[] {\n\tif (edges.length === 0) return nodes;\n\n\tconst linkedNodeIds = new Set<string>();\n\tfor (const edge of edges) {\n\t\tlinkedNodeIds.add(edge.source);\n\t\tlinkedNodeIds.add(edge.target);\n\t}\n\n\tconst filtered = nodes.filter((node) => linkedNodeIds.has(node.id));\n\t// If filtering would remove everything, return the original nodes\n\treturn filtered.length > 0 ? filtered : nodes;\n}\n","import { realClock, type Clock } from './clock.js';\nimport { ensureLayout } from './layout.js';\nimport { linearPositionTrajectory, runMultiNodeTransition } from './trajectory.js';\nimport type { CanvasEdge, CanvasNode, IncrementalLayoutOptions, NodeTransition, XYPosition } from './types.js';\nimport { connectedOnly } from './view.js';\n\nexport interface StreamingLayoutManagerOptions {\n\tthrottleMs?: number;\n\tglideDurationMs?: number;\n\tconnectedOnly?: boolean;\n\tclock?: Clock;\n\tlayoutOptions?: IncrementalLayoutOptions;\n\tonLayoutUpdated?: (positions: Map<string, XYPosition>) => void;\n}\n\n/**\n * Manages throttled incremental layout recalculation and smooth tweened node gliding\n * during active streaming (e.g. LLM streaming or graph generation).\n */\nexport class StreamingLayoutManager<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n> {\n\tprivate throttleMs: number;\n\tprivate glideDurationMs: number;\n\tprivate connectedOnly: boolean;\n\tprivate clock: Clock;\n\tprivate layoutOptions: IncrementalLayoutOptions;\n\tprivate onLayoutUpdated?: (positions: Map<string, XYPosition>) => void;\n\n\tprivate pendingTimer: any = null;\n\tprivate activeTransitionCancel: (() => void) | null = null;\n\tprivate targetPositions = new Map<string, XYPosition>();\n\n\tconstructor(options: StreamingLayoutManagerOptions = {}) {\n\t\tthis.throttleMs = options.throttleMs ?? 200;\n\t\tthis.glideDurationMs = options.glideDurationMs ?? 300;\n\t\tthis.connectedOnly = options.connectedOnly ?? false;\n\t\tthis.clock = options.clock ?? realClock;\n\t\tthis.layoutOptions = options.layoutOptions ?? { direction: 'LR' };\n\t\tthis.onLayoutUpdated = options.onLayoutUpdated;\n\t}\n\n\t/**\n\t * Feed incoming nodes and edges into the streaming manager.\n\t * Coalesces rapid streaming bursts and triggers smooth layout gliding.\n\t */\n\tpublic pushStreamUpdate(\n\t\tnodes: TNode[],\n\t\tedges: TEdge[],\n\t\tcurrentPositions: Map<string, XYPosition>\n\t): void {\n\t\tif (this.pendingTimer) {\n\t\t\tclearTimeout(this.pendingTimer);\n\t\t}\n\n\t\tthis.pendingTimer = setTimeout(() => {\n\t\t\tthis.pendingTimer = null;\n\t\t\tthis.recalculateAndGlide(nodes, edges, currentPositions);\n\t\t}, this.throttleMs);\n\t}\n\n\t/**\n\t * Forces immediate calculation and cancels pending throttled timers.\n\t */\n\tpublic flush(\n\t\tnodes: TNode[],\n\t\tedges: TEdge[],\n\t\tcurrentPositions: Map<string, XYPosition>\n\t): void {\n\t\tif (this.pendingTimer) {\n\t\t\tclearTimeout(this.pendingTimer);\n\t\t\tthis.pendingTimer = null;\n\t\t}\n\t\tthis.recalculateAndGlide(nodes, edges, currentPositions);\n\t}\n\n\tprivate recalculateAndGlide(\n\t\tnodes: TNode[],\n\t\tedges: TEdge[],\n\t\tcurrentPositions: Map<string, XYPosition>\n\t): void {\n\t\tconst targetNodes = this.connectedOnly ? connectedOnly(nodes, edges) : nodes;\n\t\tif (targetNodes.length === 0) return;\n\n\t\t// Cancel any currently running RAF glide\n\t\tif (this.activeTransitionCancel) {\n\t\t\tthis.activeTransitionCancel();\n\t\t\tthis.activeTransitionCancel = null;\n\t\t}\n\n\t\t// Incremental layout preserves existing nodes and aligns new nodes\n\t\tconst stored: Record<string, XYPosition> = {};\n\t\tfor (const [id, pos] of currentPositions.entries()) {\n\t\t\tstored[id] = pos;\n\t\t}\n\n\t\tconst layouted = ensureLayout(targetNodes, edges, {\n\t\t\t...this.layoutOptions,\n\t\t\tstoredPositions: stored\n\t\t});\n\n\t\tconst nextPositions = new Map<string, XYPosition>();\n\t\tconst transitions: NodeTransition<TNode>[] = [];\n\n\t\tfor (const node of layouted) {\n\t\t\tconst target = node.position;\n\t\t\tnextPositions.set(node.id, target);\n\n\t\t\tconst current = currentPositions.get(node.id) ?? target;\n\t\t\tconst distance = Math.hypot(target.x - current.x, target.y - current.y);\n\n\t\t\tif (distance > 2) {\n\t\t\t\ttransitions.push({\n\t\t\t\t\tnode,\n\t\t\t\t\tfrom: current,\n\t\t\t\t\tto: target,\n\t\t\t\t\ttrajectory: linearPositionTrajectory,\n\t\t\t\t\tduration: this.glideDurationMs\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis.targetPositions = nextPositions;\n\n\t\tif (transitions.length > 0) {\n\t\t\tthis.activeTransitionCancel = runMultiNodeTransition(transitions, {\n\t\t\t\tclock: this.clock,\n\t\t\t\tonUpdate: () => {\n\t\t\t\t\t// Broadcast updated positions during RAF\n\t\t\t\t\tconst liveMap = new Map<string, XYPosition>(currentPositions);\n\t\t\t\t\tfor (const trans of transitions) {\n\t\t\t\t\t\tliveMap.set(trans.node.id, { ...trans.node.position });\n\t\t\t\t\t}\n\t\t\t\t\tthis.onLayoutUpdated?.(liveMap);\n\t\t\t\t},\n\t\t\t\tonComplete: () => {\n\t\t\t\t\tthis.activeTransitionCancel = null;\n\t\t\t\t\tthis.onLayoutUpdated?.(nextPositions);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tthis.onLayoutUpdated?.(nextPositions);\n\t\t}\n\t}\n\n\tpublic destroy(): void {\n\t\tif (this.pendingTimer) {\n\t\t\tclearTimeout(this.pendingTimer);\n\t\t\tthis.pendingTimer = null;\n\t\t}\n\t\tif (this.activeTransitionCancel) {\n\t\t\tthis.activeTransitionCancel();\n\t\t\tthis.activeTransitionCancel = null;\n\t\t}\n\t}\n}\n","import { ensureLayout, getLayoutedNodes, placeBeside } from '../canvas/layout.js';\nimport type { CanvasEdge, CanvasNode, Rect } from '../canvas/types.js';\nimport type { AgentCommand, AgentStep, EditorSnapshot } from './types.js';\n\n/**\n * Plans a sequence of atomic execution steps from a high-level agent command.\n */\nexport function planAgentCommand<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tcommand: AgentCommand<TNode, TEdge>,\n\tsnapshot: EditorSnapshot<TNode, TEdge>,\n\toptions: {\n\t\tdefaultNodeSize?: { width: number; height: number };\n\t\tidGenerator?: () => string;\n\t} = {}\n): AgentStep<TNode, TEdge>[] {\n\tconst defaultNodeSize = options.defaultNodeSize ?? { width: 200, height: 60 };\n\tconst idGen = options.idGenerator ?? (() => `node-${Math.random().toString(36).substring(2, 9)}`);\n\tconst edgeIdGen = () => `edge-${Math.random().toString(36).substring(2, 9)}`;\n\n\tconst nodes = snapshot.canvas?.nodes ?? [];\n\tconst edges = snapshot.canvas?.edges ?? [];\n\n\tswitch (command.type) {\n\t\tcase 'canvas:add_node': {\n\t\t\tlet pos = command.node.position;\n\n\t\t\tif (!pos) {\n\t\t\t\tif (command.nearNodeId) {\n\t\t\t\t\t// Use collision-aware directional placement\n\t\t\t\t\tconst rects: Record<string, Rect> = {};\n\t\t\t\t\tfor (const n of nodes) {\n\t\t\t\t\t\trects[n.id] = {\n\t\t\t\t\t\t\tx: n.position.x,\n\t\t\t\t\t\t\ty: n.position.y,\n\t\t\t\t\t\t\twidth: n.measured?.width ?? (n as any).width ?? defaultNodeSize.width,\n\t\t\t\t\t\t\theight: n.measured?.height ?? (n as any).height ?? defaultNodeSize.height\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tpos = placeBeside(\n\t\t\t\t\t\trects,\n\t\t\t\t\t\tdefaultNodeSize,\n\t\t\t\t\t\tcommand.side ?? 'right',\n\t\t\t\t\t\tcommand.nearNodeId\n\t\t\t\t\t);\n\t\t\t\t} else if (nodes.length > 0) {\n\t\t\t\t\t// Default beside the last node\n\t\t\t\t\tconst lastNode = nodes[nodes.length - 1];\n\t\t\t\t\tconst rects: Record<string, Rect> = {};\n\t\t\t\t\tfor (const n of nodes) {\n\t\t\t\t\t\trects[n.id] = {\n\t\t\t\t\t\t\tx: n.position.x,\n\t\t\t\t\t\t\ty: n.position.y,\n\t\t\t\t\t\t\twidth: n.measured?.width ?? (n as any).width ?? defaultNodeSize.width,\n\t\t\t\t\t\t\theight: n.measured?.height ?? (n as any).height ?? defaultNodeSize.height\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tpos = placeBeside(rects, defaultNodeSize, 'right', lastNode.id);\n\t\t\t\t} else {\n\t\t\t\t\tpos = { x: 100, y: 100 };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst fullNode: TNode = {\n\t\t\t\t...command.node,\n\t\t\t\tid: command.node.id || idGen(),\n\t\t\t\tposition: pos\n\t\t\t} as TNode;\n\n\t\t\tconst steps: AgentStep<TNode, TEdge>[] = [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:canvas_add_node',\n\t\t\t\t\tnode: fullNode\n\t\t\t\t}\n\t\t\t];\n\n\t\t\t// If attached to nearNode, optionally automatically connect\n\t\t\tif (command.nearNodeId) {\n\t\t\t\tsteps.push({\n\t\t\t\t\ttype: 'step:canvas_add_edge',\n\t\t\t\t\tedge: {\n\t\t\t\t\t\tid: edgeIdGen(),\n\t\t\t\t\t\tsource: command.nearNodeId,\n\t\t\t\t\t\ttarget: fullNode.id\n\t\t\t\t\t} as TEdge\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn steps;\n\t\t}\n\n\t\tcase 'canvas:remove_nodes': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:canvas_remove_nodes',\n\t\t\t\t\tnodeIds: command.nodeIds\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'canvas:connect': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:canvas_add_edge',\n\t\t\t\t\tedge: {\n\t\t\t\t\t\tid: edgeIdGen(),\n\t\t\t\t\t\tsource: command.source,\n\t\t\t\t\t\ttarget: command.target,\n\t\t\t\t\t\tlabel: command.label\n\t\t\t\t\t} as TEdge\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'canvas:update_node': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:canvas_update_node',\n\t\t\t\t\tid: command.id,\n\t\t\t\t\tdata: command.data\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'canvas:layout': {\n\t\t\tconst dir = command.direction ?? 'LR';\n\t\t\tlet layouted: TNode[];\n\n\t\t\tif (command.incremental) {\n\t\t\t\tconst stored: Record<string, { x: number; y: number }> = {};\n\t\t\t\tfor (const n of nodes) {\n\t\t\t\t\tif (n.position && (n.position.x !== 0 || n.position.y !== 0)) {\n\t\t\t\t\t\tstored[n.id] = { ...n.position };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlayouted = ensureLayout(nodes, edges, {\n\t\t\t\t\tdirection: dir,\n\t\t\t\t\tstoredPositions: stored\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tlayouted = getLayoutedNodes(nodes, edges, undefined, { direction: dir });\n\t\t\t}\n\n\t\t\tconst positions: Record<string, { x: number; y: number }> = {};\n\t\t\tfor (const node of layouted) {\n\t\t\t\tpositions[node.id] = { ...node.position };\n\t\t\t}\n\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:canvas_move_nodes',\n\t\t\t\t\tpositions\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'canvas:select': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:canvas_select',\n\t\t\t\t\tnodeIds: command.nodeIds\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'canvas:highlight': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:canvas_highlight',\n\t\t\t\t\tnodeIds: command.nodeIds,\n\t\t\t\t\tcolor: command.color ?? '#3b82f6',\n\t\t\t\t\tdurationMs: command.durationMs ?? 2000\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'prompt:insert_text': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:prompt_insert',\n\t\t\t\t\ttext: command.text,\n\t\t\t\t\tat: command.at\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'prompt:replace_range': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:prompt_replace',\n\t\t\t\t\tfrom: command.from,\n\t\t\t\t\tto: command.to,\n\t\t\t\t\ttext: command.text\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'prompt:set_variable': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:prompt_set_variable',\n\t\t\t\t\tname: command.name,\n\t\t\t\t\tvalue: command.value\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'prompt:select': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:prompt_select',\n\t\t\t\t\tfrom: command.from,\n\t\t\t\t\tto: command.to\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'choreography:say': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:say',\n\t\t\t\t\ttext: command.text,\n\t\t\t\t\tatNodeId: command.atNodeId,\n\t\t\t\t\tposition: command.position\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'choreography:wait': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:wait',\n\t\t\t\t\tms: command.ms\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tdefault: {\n\t\t\treturn [];\n\t\t}\n\t}\n}\n","/**\n * Standard MCP Tool Definitions for @pixerate/editor.\n * Compatible with the Model Context Protocol (MCP) tool specification schema.\n */\n\nexport const MCP_TOOL_GET_EDITOR_STATE = {\n\tname: 'get_editor_state',\n\tdescription:\n\t\t'Retrieves the current state of the document, variables, selection, and canvas graph (nodes and edges).',\n\tinputSchema: {\n\t\ttype: 'object',\n\t\tproperties: {\n\t\t\tincludeDocument: {\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdescription: 'Whether to include the prompt document text and variables (default: true).'\n\t\t\t},\n\t\t\tincludeCanvas: {\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdescription: 'Whether to include the canvas nodes and edges (default: true).'\n\t\t\t}\n\t\t}\n\t}\n} as const;\n\nexport const MCP_TOOL_EDIT_CANVAS = {\n\tname: 'edit_canvas',\n\tdescription:\n\t\t'Applies high-level structural operations to the visual canvas (adding nodes, connecting edges, organizing layout, or moving elements).',\n\tinputSchema: {\n\t\ttype: 'object',\n\t\tproperties: {\n\t\t\toperation: {\n\t\t\t\ttype: 'string',\n\t\t\t\tenum: [\n\t\t\t\t\t'add_node',\n\t\t\t\t\t'remove_nodes',\n\t\t\t\t\t'connect',\n\t\t\t\t\t'update_node',\n\t\t\t\t\t'layout',\n\t\t\t\t\t'select',\n\t\t\t\t\t'highlight'\n\t\t\t\t],\n\t\t\t\tdescription: 'The canvas operation to execute.'\n\t\t\t},\n\t\t\tnode: {\n\t\t\t\ttype: 'object',\n\t\t\t\tdescription: 'Node definition when operation is add_node. Can omit position to auto-place.'\n\t\t\t},\n\t\t\tnearNodeId: {\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Anchor node ID to position beside using collision-aware placement.'\n\t\t\t},\n\t\t\tside: {\n\t\t\t\ttype: 'string',\n\t\t\t\tenum: ['top', 'right', 'bottom', 'left'],\n\t\t\t\tdescription: 'Side of the anchor node to place the new node beside.'\n\t\t\t},\n\t\t\tnodeIds: {\n\t\t\t\ttype: 'array',\n\t\t\t\titems: { type: 'string' },\n\t\t\t\tdescription: 'Array of node IDs for remove_nodes, select, or highlight.'\n\t\t\t},\n\t\t\tsource: {\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Source node ID for connect operation.'\n\t\t\t},\n\t\t\ttarget: {\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Target node ID for connect operation.'\n\t\t\t},\n\t\t\tlabel: {\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Optional edge label for connect operation.'\n\t\t\t},\n\t\t\tdirection: {\n\t\t\t\ttype: 'string',\n\t\t\t\tenum: ['LR', 'TB', 'RL', 'BT'],\n\t\t\t\tdescription: 'Layout direction (default LR).'\n\t\t\t},\n\t\t\tincremental: {\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdescription: 'Preserve existing node coordinates and blend layout (default true).'\n\t\t\t}\n\t\t},\n\t\trequired: ['operation']\n\t}\n} as const;\n\nexport const MCP_TOOL_EDIT_PROMPT = {\n\tname: 'edit_prompt',\n\tdescription:\n\t\t'Applies edits to the prompt template document, including inserting text, replacing ranges, and setting variables.',\n\tinputSchema: {\n\t\ttype: 'object',\n\t\tproperties: {\n\t\t\toperation: {\n\t\t\t\ttype: 'string',\n\t\t\t\tenum: ['insert_text', 'replace_range', 'set_variable', 'select'],\n\t\t\t\tdescription: 'The prompt operation to execute.'\n\t\t\t},\n\t\t\ttext: {\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Text to insert or replace.'\n\t\t\t},\n\t\t\tat: {\n\t\t\t\ttype: 'number',\n\t\t\t\tdescription: 'Position to insert text at.'\n\t\t\t},\n\t\t\tfrom: {\n\t\t\t\ttype: 'number',\n\t\t\t\tdescription: 'Start offset for replace_range or select.'\n\t\t\t},\n\t\t\tto: {\n\t\t\t\ttype: 'number',\n\t\t\t\tdescription: 'End offset for replace_range or select.'\n\t\t\t},\n\t\t\tname: {\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Variable name for set_variable.'\n\t\t\t},\n\t\t\tvalue: {\n\t\t\t\tdescription: 'Variable value for set_variable.'\n\t\t\t}\n\t\t},\n\t\trequired: ['operation']\n\t}\n} as const;\n\nexport const MCP_TOOL_VIEW_EDITOR = {\n\tname: 'view_editor',\n\tdescription:\n\t\t'Captures a visual image snapshot (JPEG or PNG) of the editor canvas or viewport for multimodal evaluation. Active agent cursor indicators are automatically excluded from the snapshot.',\n\tinputSchema: {\n\t\ttype: 'object',\n\t\tproperties: {\n\t\t\tscope: {\n\t\t\t\ttype: 'string',\n\t\t\t\tenum: ['viewport', 'canvas'],\n\t\t\t\tdescription: 'Whether to capture only the visible viewport or the full canvas bounding box (default: viewport).'\n\t\t\t},\n\t\t\tformat: {\n\t\t\t\ttype: 'string',\n\t\t\t\tenum: ['jpeg', 'png'],\n\t\t\t\tdescription: 'Image format of the base64 snapshot (default: jpeg).'\n\t\t\t},\n\t\t\tmaxEdge: {\n\t\t\t\ttype: 'integer',\n\t\t\t\tdescription: 'Maximum width or height dimension in pixels (default: 1024).'\n\t\t\t}\n\t\t}\n\t}\n} as const;\n\n/**\n * CSS selectors for ephemeral UI overlays (such as agent cursors, presence tags, and transient bubbles)\n * that should be excluded during canvas image export and visual snapshot generation.\n */\nexport const EXPORT_EXCLUDED_SELECTORS = [\n\t'.pixerate-presence',\n\t'.agent-presence',\n\t'.ursula-presence'\n] as const;\n\nexport const EDITOR_MCP_TOOLS = [\n\tMCP_TOOL_GET_EDITOR_STATE,\n\tMCP_TOOL_EDIT_CANVAS,\n\tMCP_TOOL_EDIT_PROMPT,\n\tMCP_TOOL_VIEW_EDITOR\n] as const;\n\n","import type { DepthMaskOptions, ImageAdjustments } from './types';\n\nfunction clamp(value: number, min = 0, max = 255): number {\n return Math.max(min, Math.min(max, value));\n}\n\n/**\n * Applies color and tone adjustments (brightness, contrast, saturation, exposure, temperature, opacity, blur)\n * directly to the pixel data of an ImageData buffer.\n */\nexport function applyAdjustments(imageData: ImageData, adjustments: ImageAdjustments): void {\n const { brightness, contrast, saturation, exposure, temperature, opacity, blur } = adjustments;\n const data = imageData.data;\n const len = data.length;\n\n const hasBrightness = brightness !== 0;\n const hasContrast = contrast !== 0;\n const hasSaturation = saturation !== 0;\n const hasExposure = exposure !== 0;\n const hasTemperature = temperature !== 0;\n const hasOpacity = opacity < 1;\n\n // Pre-calculate contrast factor\n const contrastFactor = hasContrast\n ? (259 * (contrast + 255)) / (255 * (259 - contrast))\n : 1;\n\n // Pre-calculate exposure multiplier\n const exposureMultiplier = hasExposure ? Math.pow(2, exposure / 50) : 1;\n\n // Pre-calculate saturation multiplier\n const satMultiplier = hasSaturation ? 1 + saturation / 100 : 1;\n\n // Pre-calculate temperature offsets\n const tempOffset = hasTemperature ? temperature * 0.8 : 0;\n\n if (hasBrightness || hasContrast || hasSaturation || hasExposure || hasTemperature || hasOpacity) {\n for (let i = 0; i < len; i += 4) {\n let r = data[i];\n let g = data[i + 1];\n let b = data[i + 2];\n let a = data[i + 3];\n\n // Exposure\n if (hasExposure) {\n r = clamp(r * exposureMultiplier);\n g = clamp(g * exposureMultiplier);\n b = clamp(b * exposureMultiplier);\n }\n\n // Brightness\n if (hasBrightness) {\n const bOffset = brightness * 2.55;\n r = clamp(r + bOffset);\n g = clamp(g + bOffset);\n b = clamp(b + bOffset);\n }\n\n // Contrast\n if (hasContrast) {\n r = clamp(contrastFactor * (r - 128) + 128);\n g = clamp(contrastFactor * (g - 128) + 128);\n b = clamp(contrastFactor * (b - 128) + 128);\n }\n\n // Saturation\n if (hasSaturation) {\n const luminance = 0.2989 * r + 0.587 * g + 0.114 * b;\n r = clamp(luminance + (r - luminance) * satMultiplier);\n g = clamp(luminance + (g - luminance) * satMultiplier);\n b = clamp(luminance + (b - luminance) * satMultiplier);\n }\n\n // Temperature / Warmth\n if (hasTemperature) {\n r = clamp(r + tempOffset);\n b = clamp(b - tempOffset);\n }\n\n // Opacity\n if (hasOpacity) {\n a = clamp(a * opacity);\n }\n\n data[i] = r;\n data[i + 1] = g;\n data[i + 2] = b;\n data[i + 3] = a;\n }\n }\n\n // Apply blur if requested\n if (blur > 0) {\n applyFastBoxBlur(imageData, Math.min(Math.round(blur), 40));\n }\n}\n\n/**\n * Fast separable box blur running horizontally and vertically.\n */\nfunction applyFastBoxBlur(imageData: ImageData, radius: number): void {\n if (radius < 1) return;\n const w = imageData.width;\n const h = imageData.height;\n const src = imageData.data;\n const temp = new Uint8ClampedArray(src.length);\n\n // Horizontal blur pass\n for (let y = 0; y < h; y++) {\n for (let x = 0; x < w; x++) {\n let r = 0, g = 0, b = 0, a = 0;\n let count = 0;\n for (let k = -radius; k <= radius; k++) {\n const px = Math.min(w - 1, Math.max(0, x + k));\n const idx = (y * w + px) * 4;\n r += src[idx];\n g += src[idx + 1];\n b += src[idx + 2];\n a += src[idx + 3];\n count++;\n }\n const dstIdx = (y * w + x) * 4;\n temp[dstIdx] = Math.round(r / count);\n temp[dstIdx + 1] = Math.round(g / count);\n temp[dstIdx + 2] = Math.round(b / count);\n temp[dstIdx + 3] = Math.round(a / count);\n }\n }\n\n // Vertical blur pass back into src\n for (let x = 0; x < w; x++) {\n for (let y = 0; y < h; y++) {\n let r = 0, g = 0, b = 0, a = 0;\n let count = 0;\n for (let k = -radius; k <= radius; k++) {\n const py = Math.min(h - 1, Math.max(0, y + k));\n const idx = (py * w + x) * 4;\n r += temp[idx];\n g += temp[idx + 1];\n b += temp[idx + 2];\n a += temp[idx + 3];\n count++;\n }\n const dstIdx = (y * w + x) * 4;\n src[dstIdx] = Math.round(r / count);\n src[dstIdx + 1] = Math.round(g / count);\n src[dstIdx + 2] = Math.round(b / count);\n src[dstIdx + 3] = Math.round(a / count);\n }\n }\n}\n\n/**\n * Blends a depth/alpha mask into the main image data based on Gleamforge depth masking.\n * Supports threshold range with softness gradation, brightness mode, and optional inversion.\n */\nexport function applyDepthMask(\n mainImageData: ImageData,\n maskImageData: ImageData,\n options: DepthMaskOptions\n): void {\n const { mode, depthRange, softness, invert } = options;\n const mainData = mainImageData.data;\n const maskData = maskImageData.data;\n const len = Math.min(mainData.length, maskData.length);\n const effectiveSoftness = Math.max(1, softness || 10);\n const minDepth = depthRange[0];\n const maxDepth = depthRange[1];\n\n for (let i = 0; i < len; i += 4) {\n let maskValue = maskData[i]; // Use red channel of mask (or grayscale)\n if (invert) {\n maskValue = 255 - maskValue;\n }\n\n let alphaValue: number;\n\n if (mode === 'threshold') {\n if (maskValue >= maxDepth + effectiveSoftness) {\n alphaValue = 0;\n } else if (maskValue > maxDepth) {\n alphaValue = Math.round(((maxDepth + effectiveSoftness - maskValue) / effectiveSoftness) * 255);\n } else if (maskValue >= minDepth) {\n alphaValue = 255;\n } else if (maskValue < minDepth - effectiveSoftness) {\n alphaValue = 0;\n } else {\n alphaValue = Math.round(((maskValue - (minDepth - effectiveSoftness)) / effectiveSoftness) * 255);\n }\n } else {\n // Brightness mode\n alphaValue = clamp(maskValue + minDepth);\n }\n\n // Multiply existing alpha with mask alpha\n mainData[i + 3] = clamp((mainData[i + 3] * alphaValue) / 255);\n }\n}\n\n/**\n * Removes alpha channel by setting all alpha bytes to 255 (completely opaque).\n * From Gleamforge image-filters.ts.\n */\nexport function removeAlpha(imageData: ImageData): void {\n const data = imageData.data;\n const len = data.length;\n for (let i = 3; i < len; i += 4) {\n data[i] = 255;\n }\n}\n","import type {\n Annotation,\n CropBox,\n ExportOptions,\n ImageEditorState,\n ImageTransform,\n PenAnnotation,\n RectAnnotation,\n CircleAnnotation,\n ArrowAnnotation,\n LineAnnotation,\n TextAnnotation,\n ImageAnnotation,\n} from './types';\nimport { applyAdjustments, applyDepthMask } from './filters';\n\nexport interface RenderOptions {\n viewportWidth?: number;\n viewportHeight?: number;\n showCropOverlay?: boolean;\n showSelectionOverlay?: boolean;\n interactive?: boolean;\n draftAnnotation?: Annotation | null;\n draftCrop?: CropBox | null;\n}\n\n/**\n * Image Cache to avoid refetching HTMLImageElement objects repeatedly during re-renders.\n */\nclass ImageCache {\n private cache = new Map<string, HTMLImageElement>();\n\n public async get(src: string): Promise<HTMLImageElement> {\n const existing = this.cache.get(src);\n if (existing && existing.complete) {\n return existing;\n }\n\n return new Promise((resolve, reject) => {\n if (typeof window === 'undefined' || typeof Image === 'undefined') {\n reject(new Error('Image loading is only supported in browser/DOM environments'));\n return;\n }\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.onload = () => {\n this.cache.set(src, img);\n resolve(img);\n };\n img.onerror = (e) => reject(new Error(`Failed to load image from: ${src}`));\n img.src = src;\n\n // In JSDOM or test environments where Image resource loading is inactive, resolve promptly\n if (typeof navigator !== 'undefined' && /jsdom/i.test(navigator.userAgent)) {\n setTimeout(() => {\n try {\n Object.defineProperty(img, 'naturalWidth', { value: 800, configurable: true });\n Object.defineProperty(img, 'naturalHeight', { value: 600, configurable: true });\n Object.defineProperty(img, 'complete', { value: true, configurable: true });\n } catch {\n // Ignore definition errors in restrictive environments\n }\n this.cache.set(src, img);\n resolve(img);\n }, 10);\n }\n });\n }\n\n public set(src: string, img: HTMLImageElement): void {\n this.cache.set(src, img);\n }\n\n public clear(): void {\n this.cache.clear();\n }\n}\n\nexport const globalImageCache = new ImageCache();\n\n/**\n * Renders an image with all its transformations, filters, depth masks, and annotations\n * to a target HTMLCanvasElement.\n */\nexport class ImageEditorRenderer {\n public imageCache = globalImageCache;\n private cachedBaseCanvas: HTMLCanvasElement | null = null;\n private cachedBaseKey = '';\n\n /**\n * Helper to create a canvas element safely in browser/JSDOM.\n */\n public createCanvas(width: number, height: number): HTMLCanvasElement {\n if (typeof document !== 'undefined' && document.createElement) {\n const c = document.createElement('canvas');\n c.width = Math.max(1, Math.round(width));\n c.height = Math.max(1, Math.round(height));\n return c;\n }\n // Fallback for non-DOM / headless\n return {\n width: Math.max(1, Math.round(width)),\n height: Math.max(1, Math.round(height)),\n getContext: () => null,\n toDataURL: () => '',\n toBlob: () => {},\n } as unknown as HTMLCanvasElement;\n }\n\n /**\n * Renders the editor state onto a canvas (viewport or preview).\n */\n public async renderToCanvas(\n targetCanvas: HTMLCanvasElement,\n imageSource: CanvasImageSource | string,\n state: ImageEditorState,\n options: RenderOptions = {}\n ): Promise<void> {\n const ctx = targetCanvas.getContext('2d');\n if (!ctx) return;\n\n let img: CanvasImageSource;\n if (typeof imageSource === 'string') {\n img = await this.imageCache.get(imageSource);\n } else {\n img = imageSource;\n }\n\n const naturalWidth = (img as any).naturalWidth || (img as any).videoWidth || (img as any).width || 800;\n const naturalHeight = (img as any).naturalHeight || (img as any).videoHeight || (img as any).height || 600;\n\n const { crop, transform, adjustments, depthMask, annotations, selectedAnnotationId, zoom, pan, isOriginalCompared } = state;\n\n // Viewport dimensions\n const vpWidth = options.viewportWidth || targetCanvas.width;\n const vpHeight = options.viewportHeight || targetCanvas.height;\n\n targetCanvas.width = vpWidth;\n targetCanvas.height = vpHeight;\n\n ctx.clearRect(0, 0, vpWidth, vpHeight);\n\n // If in compare mode, render original image directly and exit\n if (isOriginalCompared) {\n this.drawFittedImage(ctx, img, naturalWidth, naturalHeight, vpWidth, vpHeight, zoom, pan);\n return;\n }\n\n // Determine working base dimensions based on crop or natural\n // When actively in crop tool or overlay requested, show full image so user can adjust the crop box\n const isActivelyCropping = Boolean(options.showCropOverlay || state.activeTool === 'crop');\n const cropX = (!isActivelyCropping && crop) ? Math.max(0, crop.x) : 0;\n const cropY = (!isActivelyCropping && crop) ? Math.max(0, crop.y) : 0;\n const cropW = (!isActivelyCropping && crop) ? Math.min(naturalWidth - cropX, crop.width) : naturalWidth;\n const cropH = (!isActivelyCropping && crop) ? Math.min(naturalHeight - cropY, crop.height) : naturalHeight;\n\n const angle = ((transform.rotate % 360) + 360) % 360;\n const isSwapped = angle === 90 || angle === 270;\n const baseW = isSwapped ? cropH : cropW;\n const baseH = isSwapped ? cropW : cropH;\n\n // 1. Offscreen canvas for Base Image + Transform (Flip/Rotate) + Crop + Adjustments\n const baseKey = `${state.sourceUrl}-${naturalWidth}x${naturalHeight}-${cropX},${cropY},${cropW},${cropH}-${angle},${transform.flipH},${transform.flipV}-${adjustments.brightness},${adjustments.contrast},${adjustments.saturation},${adjustments.exposure},${adjustments.temperature},${adjustments.blur},${adjustments.opacity}-${depthMask.enabled},${depthMask.depthRange?.[0]}-${depthMask.depthRange?.[1]},${depthMask.softness},${depthMask.invert},${depthMask.mode}`;\n\n let baseCanvas = this.cachedBaseCanvas;\n if (!baseCanvas || this.cachedBaseKey !== baseKey) {\n baseCanvas = this.createCanvas(baseW, baseH);\n const baseCtx = baseCanvas.getContext('2d');\n\n if (baseCtx) {\n baseCtx.save();\n\n // Handle Flip & Rotate\n const rad = (angle * Math.PI) / 180;\n baseCtx.translate(baseW / 2, baseH / 2);\n baseCtx.rotate(rad);\n baseCtx.scale(transform.flipH ? -1 : 1, transform.flipV ? -1 : 1);\n\n // Draw the cropped portion centered\n baseCtx.drawImage(\n img,\n cropX, cropY, cropW, cropH,\n -cropW / 2, -cropH / 2, cropW, cropH\n );\n\n baseCtx.restore();\n\n // 2. Pixel adjustments & Depth Masking\n const imageData = baseCtx.getImageData(0, 0, baseW, baseH);\n if (imageData) {\n applyAdjustments(imageData, adjustments);\n\n if (depthMask.enabled && depthMask.maskSource) {\n try {\n const maskImg = await this.imageCache.get(depthMask.maskSource);\n const maskCanvas = this.createCanvas(baseW, baseH);\n const maskCtx = maskCanvas.getContext('2d');\n if (maskCtx) {\n maskCtx.drawImage(maskImg, cropX, cropY, cropW, cropH, 0, 0, baseW, baseH);\n const maskData = maskCtx.getImageData(0, 0, baseW, baseH);\n if (maskData) {\n applyDepthMask(imageData, maskData, depthMask);\n }\n }\n } catch {\n // Mask failed to load; continue without crashing\n }\n }\n\n baseCtx.putImageData(imageData, 0, 0);\n }\n }\n this.cachedBaseCanvas = baseCanvas;\n this.cachedBaseKey = baseKey;\n }\n\n // 3. Render base canvas onto target canvas with viewport zoom & pan\n ctx.save();\n // Center of canvas\n ctx.translate(vpWidth / 2 + pan.x, vpHeight / 2 + pan.y);\n ctx.scale(zoom, zoom);\n\n // Calculate fitted dimensions\n const fitScale = Math.min((vpWidth * 0.85) / baseW, (vpHeight * 0.85) / baseH, 1);\n const renderW = baseW * fitScale;\n const renderH = baseH * fitScale;\n\n // Draw base image\n ctx.drawImage(baseCanvas, -renderW / 2, -renderH / 2, renderW, renderH);\n\n // 4. Render Annotations scaled to fit image space\n const scaleFactor = fitScale;\n ctx.save();\n ctx.translate(-renderW / 2, -renderH / 2);\n ctx.scale(scaleFactor, scaleFactor);\n\n for (const ann of annotations) {\n await this.drawAnnotation(ctx, ann);\n if (options.showSelectionOverlay && ann.id === selectedAnnotationId) {\n this.drawAnnotationSelection(ctx, ann);\n }\n }\n\n // Render active live draft annotation\n if (options.draftAnnotation) {\n await this.drawAnnotation(ctx, options.draftAnnotation);\n }\n\n ctx.restore();\n\n ctx.restore();\n\n // 5. Draw Crop Grid Overlay if crop overlay is requested\n const isCroppingActive = Boolean(options.showCropOverlay || state.activeTool === 'crop');\n const activeCrop =\n (options.draftCrop !== undefined && options.draftCrop !== null)\n ? options.draftCrop\n : (crop ?? (isCroppingActive ? {\n x: 0,\n y: 0,\n width: naturalWidth,\n height: naturalHeight,\n } : null));\n\n if (isCroppingActive && activeCrop) {\n this.drawCropOverlay(ctx, state, vpWidth, vpHeight, naturalWidth, naturalHeight, activeCrop);\n }\n }\n\n /**\n * Draws an individual annotation onto the canvas.\n */\n public async drawAnnotation(ctx: CanvasRenderingContext2D, ann: Annotation): Promise<void> {\n ctx.save();\n if (ann.opacity !== undefined) {\n ctx.globalAlpha = ann.opacity;\n }\n\n if (ann.rotation) {\n ctx.translate(ann.x, ann.y);\n ctx.rotate((ann.rotation * Math.PI) / 180);\n ctx.translate(-ann.x, -ann.y);\n }\n\n switch (ann.type) {\n case 'pen': {\n const pen = ann as PenAnnotation;\n if (pen.points.length > 0) {\n ctx.beginPath();\n ctx.strokeStyle = pen.strokeColor;\n ctx.lineWidth = pen.strokeWidth;\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n ctx.moveTo(pen.points[0].x, pen.points[0].y);\n for (let i = 1; i < pen.points.length; i++) {\n ctx.lineTo(pen.points[i].x, pen.points[i].y);\n }\n ctx.stroke();\n }\n break;\n }\n\n case 'rect': {\n const rect = ann as RectAnnotation;\n ctx.strokeStyle = rect.strokeColor;\n ctx.lineWidth = rect.strokeWidth;\n if (rect.fillColor) {\n ctx.fillStyle = rect.fillColor;\n ctx.fillRect(rect.x, rect.y, rect.width, rect.height);\n }\n if (rect.strokeWidth > 0) {\n ctx.strokeRect(rect.x, rect.y, rect.width, rect.height);\n }\n break;\n }\n\n case 'circle': {\n const circle = ann as CircleAnnotation;\n ctx.beginPath();\n ctx.strokeStyle = circle.strokeColor;\n ctx.lineWidth = circle.strokeWidth;\n ctx.ellipse(circle.x, circle.y, Math.abs(circle.radiusX), Math.abs(circle.radiusY), 0, 0, 2 * Math.PI);\n if (circle.fillColor) {\n ctx.fillStyle = circle.fillColor;\n ctx.fill();\n }\n if (circle.strokeWidth > 0) {\n ctx.stroke();\n }\n break;\n }\n\n case 'arrow': {\n const arrow = ann as ArrowAnnotation;\n ctx.strokeStyle = arrow.strokeColor;\n ctx.fillStyle = arrow.strokeColor;\n ctx.lineWidth = arrow.strokeWidth;\n\n // Line body\n ctx.beginPath();\n ctx.moveTo(arrow.x, arrow.y);\n ctx.lineTo(arrow.endX, arrow.endY);\n ctx.stroke();\n\n // Arrow head\n const angle = Math.atan2(arrow.endY - arrow.y, arrow.endX - arrow.x);\n const headLen = Math.max(12, arrow.strokeWidth * 3);\n ctx.beginPath();\n ctx.moveTo(arrow.endX, arrow.endY);\n ctx.lineTo(\n arrow.endX - headLen * Math.cos(angle - Math.PI / 6),\n arrow.endY - headLen * Math.sin(angle - Math.PI / 6)\n );\n ctx.lineTo(\n arrow.endX - headLen * Math.cos(angle + Math.PI / 6),\n arrow.endY - headLen * Math.sin(angle + Math.PI / 6)\n );\n ctx.closePath();\n ctx.fill();\n break;\n }\n\n case 'line': {\n const line = ann as LineAnnotation;\n ctx.beginPath();\n ctx.strokeStyle = line.strokeColor;\n ctx.lineWidth = line.strokeWidth;\n ctx.moveTo(line.x, line.y);\n ctx.lineTo(line.endX, line.endY);\n ctx.stroke();\n break;\n }\n\n case 'text': {\n const textAnn = ann as TextAnnotation;\n ctx.font = `${textAnn.fontWeight || 'normal'} ${textAnn.fontSize}px ${textAnn.fontFamily || 'sans-serif'}`;\n ctx.fillStyle = textAnn.color;\n ctx.textBaseline = 'top';\n ctx.fillText(textAnn.text, textAnn.x, textAnn.y);\n break;\n }\n\n case 'image': {\n const imgAnn = ann as ImageAnnotation;\n try {\n const loadedImg = await this.imageCache.get(imgAnn.src);\n ctx.drawImage(loadedImg, imgAnn.x, imgAnn.y, imgAnn.width, imgAnn.height);\n } catch {\n // Skip if watermark image failed to load\n }\n break;\n }\n }\n\n ctx.restore();\n }\n\n /**\n * Draws selection box around active annotation.\n */\n private drawAnnotationSelection(ctx: CanvasRenderingContext2D, ann: Annotation): void {\n ctx.save();\n ctx.strokeStyle = '#3b82f6'; // Tailwind blue-500\n ctx.lineWidth = 1.5;\n ctx.setLineDash([4, 4]);\n\n const bounds = this.getAnnotationBounds(ann);\n const pad = 4;\n ctx.strokeRect(bounds.x - pad, bounds.y - pad, bounds.width + pad * 2, bounds.height + pad * 2);\n\n // Draw handles\n ctx.fillStyle = '#ffffff';\n ctx.strokeStyle = '#3b82f6';\n ctx.setLineDash([]);\n const handleSize = 6;\n const corners = [\n { x: bounds.x - pad, y: bounds.y - pad },\n { x: bounds.x + bounds.width + pad, y: bounds.y - pad },\n { x: bounds.x - pad, y: bounds.y + bounds.height + pad },\n { x: bounds.x + bounds.width + pad, y: bounds.y + bounds.height + pad },\n ];\n for (const c of corners) {\n ctx.fillRect(c.x - handleSize / 2, c.y - handleSize / 2, handleSize, handleSize);\n ctx.strokeRect(c.x - handleSize / 2, c.y - handleSize / 2, handleSize, handleSize);\n }\n\n ctx.restore();\n }\n\n public getAnnotationBounds(ann: Annotation): { x: number; y: number; width: number; height: number } {\n switch (ann.type) {\n case 'rect':\n return { x: ann.x, y: ann.y, width: ann.width, height: ann.height };\n case 'circle':\n return {\n x: ann.x - Math.abs(ann.radiusX),\n y: ann.y - Math.abs(ann.radiusY),\n width: Math.abs(ann.radiusX) * 2,\n height: Math.abs(ann.radiusY) * 2,\n };\n case 'arrow':\n case 'line': {\n const minX = Math.min(ann.x, ann.endX);\n const minY = Math.min(ann.y, ann.endY);\n return {\n x: minX,\n y: minY,\n width: Math.max(Math.abs(ann.endX - ann.x), 10),\n height: Math.max(Math.abs(ann.endY - ann.y), 10),\n };\n }\n case 'pen': {\n if (!ann.points.length) return { x: ann.x, y: ann.y, width: 0, height: 0 };\n let minX = ann.points[0].x, maxX = ann.points[0].x;\n let minY = ann.points[0].y, maxY = ann.points[0].y;\n for (const pt of ann.points) {\n if (pt.x < minX) minX = pt.x;\n if (pt.x > maxX) maxX = pt.x;\n if (pt.y < minY) minY = pt.y;\n if (pt.y > maxY) maxY = pt.y;\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n }\n case 'text':\n return {\n x: ann.x,\n y: ann.y,\n width: (ann.text.length * ann.fontSize * 0.6),\n height: ann.fontSize * 1.2,\n };\n case 'image':\n return { x: ann.x, y: ann.y, width: ann.width, height: ann.height };\n }\n }\n\n /**\n * Draws a rule-of-thirds crop grid overlay.\n */\n private drawCropOverlay(\n ctx: CanvasRenderingContext2D,\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n imgWidth: number,\n imgHeight: number,\n cropOverride?: CropBox | null\n ): void {\n const crop =\n (cropOverride !== undefined && cropOverride !== null)\n ? cropOverride\n : (state.crop ?? {\n x: 0,\n y: 0,\n width: imgWidth,\n height: imgHeight,\n });\n if (!crop) return;\n\n const { transform, pan, zoom } = state;\n const angle = ((transform.rotate % 360) + 360) % 360;\n const isSwapped = angle === 90 || angle === 270;\n const baseW = isSwapped ? imgHeight : imgWidth;\n const baseH = isSwapped ? imgWidth : imgHeight;\n\n ctx.save();\n ctx.translate(vpWidth / 2 + pan.x, vpHeight / 2 + pan.y);\n ctx.scale(zoom, zoom);\n\n const fitScale = Math.min((vpWidth * 0.85) / baseW, (vpHeight * 0.85) / baseH, 1);\n const renderW = baseW * fitScale;\n const renderH = baseH * fitScale;\n\n const startX = -renderW / 2 + (crop.x / imgWidth) * renderW;\n const startY = -renderH / 2 + (crop.y / imgHeight) * renderH;\n const cropBoxW = (crop.width / imgWidth) * renderW;\n const cropBoxH = (crop.height / imgHeight) * renderH;\n\n // Dark semi-transparent scrim outside crop box\n ctx.fillStyle = 'rgba(0, 0, 0, 0.45)';\n // Top\n ctx.fillRect(-renderW / 2, -renderH / 2, renderW, startY - (-renderH / 2));\n // Bottom\n ctx.fillRect(-renderW / 2, startY + cropBoxH, renderW, renderH / 2 - (startY + cropBoxH));\n // Left\n ctx.fillRect(-renderW / 2, startY, startX - (-renderW / 2), cropBoxH);\n // Right\n ctx.fillRect(startX + cropBoxW, startY, renderW / 2 - (startX + cropBoxW), cropBoxH);\n\n // Crop border\n ctx.strokeStyle = '#ffffff';\n ctx.lineWidth = 2;\n ctx.strokeRect(startX, startY, cropBoxW, cropBoxH);\n\n // Rule of thirds lines\n ctx.strokeStyle = 'rgba(255, 255, 255, 0.4)';\n ctx.lineWidth = 1;\n ctx.beginPath();\n // Vertical lines\n ctx.moveTo(startX + cropBoxW / 3, startY);\n ctx.lineTo(startX + cropBoxW / 3, startY + cropBoxH);\n ctx.moveTo(startX + (cropBoxW * 2) / 3, startY);\n ctx.lineTo(startX + (cropBoxW * 2) / 3, startY + cropBoxH);\n // Horizontal lines\n ctx.moveTo(startX, startY + cropBoxH / 3);\n ctx.lineTo(startX + cropBoxW, startY + cropBoxH / 3);\n ctx.moveTo(startX, startY + (cropBoxH * 2) / 3);\n ctx.lineTo(startX + cropBoxW, startY + (cropBoxH * 2) / 3);\n ctx.stroke();\n\n // Corner and edge handles\n ctx.fillStyle = '#ffffff';\n ctx.strokeStyle = '#0284c7';\n ctx.lineWidth = 1.5;\n const handleSize = 10;\n const handles = [\n // Corners\n { x: startX, y: startY },\n { x: startX + cropBoxW, y: startY },\n { x: startX, y: startY + cropBoxH },\n { x: startX + cropBoxW, y: startY + cropBoxH },\n // Edges\n { x: startX + cropBoxW / 2, y: startY },\n { x: startX + cropBoxW / 2, y: startY + cropBoxH },\n { x: startX, y: startY + cropBoxH / 2 },\n { x: startX + cropBoxW, y: startY + cropBoxH / 2 },\n ];\n for (const h of handles) {\n ctx.fillRect(h.x - handleSize / 2, h.y - handleSize / 2, handleSize, handleSize);\n ctx.strokeRect(h.x - handleSize / 2, h.y - handleSize / 2, handleSize, handleSize);\n }\n\n ctx.restore();\n }\n\n private drawFittedImage(\n ctx: CanvasRenderingContext2D,\n img: CanvasImageSource,\n imgW: number,\n imgH: number,\n vpW: number,\n vpH: number,\n zoom: number,\n pan: { x: number; y: number }\n ): void {\n ctx.save();\n ctx.translate(vpW / 2 + pan.x, vpH / 2 + pan.y);\n ctx.scale(zoom, zoom);\n const fitScale = Math.min((vpW * 0.85) / imgW, (vpH * 0.85) / imgH, 1);\n const renderW = imgW * fitScale;\n const renderH = imgH * fitScale;\n ctx.drawImage(img, -renderW / 2, -renderH / 2, renderW, renderH);\n ctx.restore();\n }\n\n /**\n * Performs an export render at exact pixel dimensions without zoom/pan viewport offsets.\n */\n public async renderExport(\n imageSource: CanvasImageSource | string,\n state: ImageEditorState,\n options: ExportOptions = {}\n ): Promise<HTMLCanvasElement> {\n let img: CanvasImageSource;\n if (typeof imageSource === 'string') {\n img = await this.imageCache.get(imageSource);\n } else {\n img = imageSource;\n }\n\n const naturalWidth = (img as any).naturalWidth || (img as any).videoWidth || (img as any).width || 800;\n const naturalHeight = (img as any).naturalHeight || (img as any).videoHeight || (img as any).height || 600;\n\n const { crop, transform, adjustments, depthMask, annotations } = state;\n\n const cropX = crop ? Math.max(0, crop.x) : 0;\n const cropY = crop ? Math.max(0, crop.y) : 0;\n const cropW = crop ? Math.min(naturalWidth - cropX, crop.width) : naturalWidth;\n const cropH = crop ? Math.min(naturalHeight - cropY, crop.height) : naturalHeight;\n\n const angle = ((transform.rotate % 360) + 360) % 360;\n const isSwapped = angle === 90 || angle === 270;\n const baseW = isSwapped ? cropH : cropW;\n const baseH = isSwapped ? cropW : cropH;\n\n const exportW = options.width || baseW;\n const exportH = options.height || baseH;\n\n const exportCanvas = this.createCanvas(exportW, exportH);\n const ctx = exportCanvas.getContext('2d');\n if (!ctx) return exportCanvas;\n\n // Draw transformed base image\n const intermediateCanvas = this.createCanvas(baseW, baseH);\n const interCtx = intermediateCanvas.getContext('2d');\n if (interCtx) {\n interCtx.save();\n const rad = (angle * Math.PI) / 180;\n interCtx.translate(baseW / 2, baseH / 2);\n interCtx.rotate(rad);\n interCtx.scale(transform.flipH ? -1 : 1, transform.flipV ? -1 : 1);\n interCtx.drawImage(img, cropX, cropY, cropW, cropH, -cropW / 2, -cropH / 2, cropW, cropH);\n interCtx.restore();\n\n // Apply adjustments\n const imageData = interCtx.getImageData(0, 0, baseW, baseH);\n if (imageData) {\n applyAdjustments(imageData, adjustments);\n\n if (depthMask.enabled && depthMask.maskSource) {\n try {\n const maskImg = await this.imageCache.get(depthMask.maskSource);\n const maskCanvas = this.createCanvas(baseW, baseH);\n const maskCtx = maskCanvas.getContext('2d');\n if (maskCtx) {\n maskCtx.drawImage(maskImg, cropX, cropY, cropW, cropH, 0, 0, baseW, baseH);\n const maskData = maskCtx.getImageData(0, 0, baseW, baseH);\n if (maskData) {\n applyDepthMask(imageData, maskData, depthMask);\n }\n }\n } catch {\n // Mask skip\n }\n }\n\n interCtx.putImageData(imageData, 0, 0);\n }\n }\n\n // Scale to target export dimensions\n ctx.drawImage(intermediateCanvas, 0, 0, baseW, baseH, 0, 0, exportW, exportH);\n\n // Draw annotations if included\n if (options.includeAnnotations !== false && annotations.length > 0) {\n const annScaleX = exportW / baseW;\n const annScaleY = exportH / baseH;\n ctx.save();\n ctx.scale(annScaleX, annScaleY);\n for (const ann of annotations) {\n await this.drawAnnotation(ctx, ann);\n }\n ctx.restore();\n }\n\n return exportCanvas;\n }\n\n /**\n * Generates a binary mask canvas (white for mask/selected area, black for unmasked).\n * Useful for AI inpainting and selective generative fill.\n */\n public async renderMask(\n state: ImageEditorState,\n options?: { useAnnotations?: boolean; useCrop?: boolean }\n ): Promise<HTMLCanvasElement> {\n const naturalWidth = state.imageDimensions.width;\n const naturalHeight = state.imageDimensions.height;\n const maskCanvas = this.createCanvas(naturalWidth, naturalHeight);\n const ctx = maskCanvas.getContext('2d');\n if (!ctx) return maskCanvas;\n\n // Background: unmasked (black)\n ctx.fillStyle = '#000000';\n ctx.fillRect(0, 0, naturalWidth, naturalHeight);\n\n const useCrop = options?.useCrop ?? true;\n const useAnnotations = options?.useAnnotations ?? true;\n\n // Crop box mask (if active)\n if (useCrop && state.crop) {\n ctx.fillStyle = '#ffffff';\n ctx.fillRect(state.crop.x, state.crop.y, state.crop.width, state.crop.height);\n }\n\n // Annotation masks (drawn in solid white)\n if (useAnnotations && state.annotations.length > 0) {\n for (const ann of state.annotations) {\n ctx.save();\n if (ann.rotation) {\n ctx.translate(ann.x, ann.y);\n ctx.rotate((ann.rotation * Math.PI) / 180);\n ctx.translate(-ann.x, -ann.y);\n }\n\n if (ann.type === 'pen') {\n const pen = ann as PenAnnotation;\n if (pen.points.length > 0) {\n ctx.beginPath();\n ctx.strokeStyle = '#ffffff';\n ctx.lineWidth = Math.max(pen.strokeWidth, 8);\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n ctx.moveTo(pen.points[0].x, pen.points[0].y);\n for (let i = 1; i < pen.points.length; i++) {\n ctx.lineTo(pen.points[i].x, pen.points[i].y);\n }\n ctx.stroke();\n }\n } else if (ann.type === 'rect') {\n const rect = ann as RectAnnotation;\n ctx.fillStyle = '#ffffff';\n ctx.fillRect(rect.x, rect.y, rect.width, rect.height);\n } else if (ann.type === 'circle') {\n const circ = ann as CircleAnnotation;\n ctx.fillStyle = '#ffffff';\n ctx.beginPath();\n ctx.ellipse(circ.x, circ.y, circ.radiusX, circ.radiusY, 0, 0, Math.PI * 2);\n ctx.fill();\n } else {\n ctx.strokeStyle = '#ffffff';\n ctx.fillStyle = '#ffffff';\n await this.drawAnnotation(ctx, ann);\n }\n ctx.restore();\n }\n }\n\n return maskCanvas;\n }\n}\n\n","import {\n Annotation,\n CreateAnnotationPayload,\n AspectRatio,\n CropBox,\n DepthMaskOptions,\n ExportOptions,\n ImageAdjustments,\n ImageDimensions,\n ImageEditorOptions,\n ImageEditorState,\n ImageEditorTool,\n ImageTransform,\n ImagePoint,\n SerializedImageEditorState,\n} from './types';\nimport { ImageEditorRenderer, RenderOptions } from './renderer';\n\nexport const DEFAULT_ADJUSTMENTS: ImageAdjustments = {\n brightness: 0,\n contrast: 0,\n saturation: 0,\n exposure: 0,\n temperature: 0,\n blur: 0,\n opacity: 1,\n};\n\nexport const DEFAULT_TRANSFORM: ImageTransform = {\n rotate: 0,\n flipH: false,\n flipV: false,\n};\n\nexport const DEFAULT_DEPTH_MASK: DepthMaskOptions = {\n enabled: false,\n maskSource: null,\n mode: 'threshold',\n depthRange: [0, 255],\n softness: 10,\n invert: false,\n};\n\n/**\n * ImageEditorController manages the complete lifecycle, canvas rendering pipeline,\n * tool interaction states, undo/redo history, serialization, and image export.\n */\nexport class ImageEditorController {\n private state: ImageEditorState;\n private renderer: ImageEditorRenderer;\n private imageElement: CanvasImageSource | null = null;\n private listeners = new Set<(state: ImageEditorState) => void>();\n private onStateChange?: (state: ImageEditorState) => void;\n\n // History stacks\n private undoStack: SerializedImageEditorState[] = [];\n private redoStack: SerializedImageEditorState[] = [];\n private maxHistoryDepth: number;\n private isApplyingHistory = false;\n private initialSnapshot: SerializedImageEditorState;\n\n constructor(options: ImageEditorOptions = {}) {\n this.maxHistoryDepth = options.maxHistoryDepth ?? 50;\n this.onStateChange = options.onStateChange;\n this.renderer = new ImageEditorRenderer();\n\n const initialAdjustments: ImageAdjustments = {\n ...DEFAULT_ADJUSTMENTS,\n ...options.initialState?.adjustments,\n };\n\n const initialTransform: ImageTransform = {\n ...DEFAULT_TRANSFORM,\n ...options.initialState?.transform,\n };\n\n const initialDepthMask: DepthMaskOptions = {\n ...DEFAULT_DEPTH_MASK,\n ...options.initialState?.depthMask,\n };\n\n this.state = {\n sourceUrl: typeof options.image === 'string' ? options.image : null,\n imageDimensions: { width: 800, height: 600 },\n crop: options.initialState?.crop ?? null,\n transform: initialTransform,\n adjustments: initialAdjustments,\n depthMask: initialDepthMask,\n annotations: options.initialState?.annotations ?? [],\n selectedAnnotationId: null,\n activeTool: 'select',\n zoom: 1,\n pan: { x: 0, y: 0 },\n isOriginalCompared: false,\n };\n\n if (options.image instanceof Object && 'width' in options.image) {\n this.imageElement = options.image as CanvasImageSource;\n this.state.imageDimensions = {\n width: (options.image as any).naturalWidth || (options.image as any).width || 800,\n height: (options.image as any).naturalHeight || (options.image as any).height || 600,\n };\n }\n\n this.initialSnapshot = this.serializeState();\n\n if (typeof options.image === 'string') {\n this.loadImage(options.image);\n }\n }\n\n // --- Image Loading ---\n\n public async loadImage(src: string | HTMLImageElement): Promise<void> {\n if (typeof src === 'string') {\n this.state.sourceUrl = src;\n try {\n const img = await this.renderer.imageCache.get(src);\n this.imageElement = img;\n this.state.imageDimensions = {\n width: img.naturalWidth || img.width || 800,\n height: img.naturalHeight || img.height || 600,\n };\n } catch (err) {\n // In SSR / non-DOM environments, retain default dimensions\n }\n } else {\n this.imageElement = src;\n this.state.sourceUrl = (src as any).src || null;\n this.state.imageDimensions = {\n width: src.naturalWidth || src.width || 800,\n height: src.naturalHeight || src.height || 600,\n };\n }\n\n this.initialSnapshot = this.serializeState();\n this.notify();\n }\n\n public getImageElement(): CanvasImageSource | null {\n return this.imageElement;\n }\n\n // --- State & Subscription ---\n\n public getState(): ImageEditorState {\n return this.state;\n }\n\n public subscribe(listener: (state: ImageEditorState) => void): () => void {\n this.listeners.add(listener);\n listener(this.state);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private notify(): void {\n const currentState = { ...this.state };\n this.onStateChange?.(currentState);\n this.listeners.forEach((l) => l(currentState));\n }\n\n // --- History (Undo / Redo / Reset) ---\n\n private recordHistory(): void {\n if (this.isApplyingHistory) return;\n this.undoStack.push(this.serializeState());\n if (this.undoStack.length > this.maxHistoryDepth) {\n this.undoStack.shift();\n }\n this.redoStack = [];\n }\n\n public get canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n public get canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n public undo(): boolean {\n if (!this.canUndo) return false;\n this.isApplyingHistory = true;\n const current = this.serializeState();\n this.redoStack.push(current);\n\n const prev = this.undoStack.pop()!;\n this.applySerializedState(prev);\n this.isApplyingHistory = false;\n this.notify();\n return true;\n }\n\n public redo(): boolean {\n if (!this.canRedo) return false;\n this.isApplyingHistory = true;\n const current = this.serializeState();\n this.undoStack.push(current);\n\n const next = this.redoStack.pop()!;\n this.applySerializedState(next);\n this.isApplyingHistory = false;\n this.notify();\n return true;\n }\n\n public reset(): void {\n this.recordHistory();\n this.applySerializedState(this.initialSnapshot);\n this.state.zoom = 1;\n this.state.pan = { x: 0, y: 0 };\n this.state.activeTool = 'select';\n this.state.selectedAnnotationId = null;\n this.notify();\n }\n\n // --- Active Tool ---\n\n public setTool(tool: ImageEditorTool): void {\n if (this.state.activeTool === tool) return;\n this.state.activeTool = tool;\n if (tool !== 'select') {\n this.state.selectedAnnotationId = null;\n }\n // If switching to crop tool and no crop is defined, initialize crop to full image\n if (tool === 'crop' && !this.state.crop) {\n this.state.crop = {\n x: 0,\n y: 0,\n width: this.state.imageDimensions.width,\n height: this.state.imageDimensions.height,\n };\n }\n this.notify();\n }\n\n // --- Crop ---\n\n public setCrop(crop: CropBox | null, addToHistory = true): void {\n if (addToHistory) {\n this.recordHistory();\n }\n this.state.crop = crop;\n this.notify();\n }\n\n public applyCropPreset(ratio: AspectRatio): void {\n this.recordHistory();\n const { width, height } = this.state.imageDimensions;\n if (!ratio) {\n // Freeform: full image\n this.state.crop = { x: 0, y: 0, width, height };\n } else {\n let targetW = width;\n let targetH = targetW / ratio;\n\n if (targetH > height) {\n targetH = height;\n targetW = targetH * ratio;\n }\n\n const x = Math.max(0, Math.round((width - targetW) / 2));\n const y = Math.max(0, Math.round((height - targetH) / 2));\n this.state.crop = {\n x,\n y,\n width: Math.round(targetW),\n height: Math.round(targetH),\n };\n }\n this.notify();\n }\n\n public resetCrop(): void {\n this.recordHistory();\n this.state.crop = null;\n this.notify();\n }\n\n // --- Transformations (Rotate / Flip) ---\n\n public rotate(degrees: number): void {\n this.recordHistory();\n const current = this.state.transform.rotate;\n this.state.transform.rotate = (current + degrees) % 360;\n this.notify();\n }\n\n public setRotation(degrees: number): void {\n this.recordHistory();\n this.state.transform.rotate = degrees % 360;\n this.notify();\n }\n\n public flipHorizontal(): void {\n this.recordHistory();\n this.state.transform.flipH = !this.state.transform.flipH;\n this.notify();\n }\n\n public flipVertical(): void {\n this.recordHistory();\n this.state.transform.flipV = !this.state.transform.flipV;\n this.notify();\n }\n\n // --- Adjustments ---\n\n public setAdjustments(partial: Partial<ImageAdjustments>, commitToHistory = true): void {\n if (commitToHistory) {\n this.recordHistory();\n }\n this.state.adjustments = {\n ...this.state.adjustments,\n ...partial,\n };\n this.notify();\n }\n\n public resetAdjustments(): void {\n this.recordHistory();\n this.state.adjustments = { ...DEFAULT_ADJUSTMENTS };\n this.notify();\n }\n\n // --- Depth Masking (Gleamforge) ---\n\n public setDepthMask(partial: Partial<DepthMaskOptions>): void {\n this.recordHistory();\n this.state.depthMask = {\n ...this.state.depthMask,\n ...partial,\n };\n this.notify();\n }\n\n public resetDepthMask(): void {\n this.recordHistory();\n this.state.depthMask = { ...DEFAULT_DEPTH_MASK };\n this.notify();\n }\n\n // --- Annotations & Layers ---\n\n public addAnnotation(annotation: CreateAnnotationPayload): string {\n this.recordHistory();\n const id = `ann_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;\n const fullAnnotation = { ...annotation, id } as Annotation;\n this.state.annotations = [...this.state.annotations, fullAnnotation];\n this.state.selectedAnnotationId = id;\n this.notify();\n return id;\n }\n\n public updateAnnotation(id: string, partial: Partial<Annotation>, commitToHistory = true): void {\n if (commitToHistory) {\n this.recordHistory();\n }\n this.state.annotations = this.state.annotations.map((ann) => {\n if (ann.id === id) {\n return { ...ann, ...partial } as Annotation;\n }\n return ann;\n });\n this.notify();\n }\n\n public removeAnnotation(id: string): void {\n this.recordHistory();\n this.state.annotations = this.state.annotations.filter((ann) => ann.id !== id);\n if (this.state.selectedAnnotationId === id) {\n this.state.selectedAnnotationId = null;\n }\n this.notify();\n }\n\n public clearAnnotations(): void {\n this.recordHistory();\n this.state.annotations = [];\n this.state.selectedAnnotationId = null;\n this.notify();\n }\n\n public selectAnnotation(id: string | null): void {\n this.state.selectedAnnotationId = id;\n this.notify();\n }\n\n // --- Zoom & Pan ---\n\n public setZoom(zoom: number): void {\n this.state.zoom = Math.max(0.1, Math.min(10, zoom));\n this.notify();\n }\n\n public zoomIn(factor = 1.2): void {\n this.setZoom(this.state.zoom * factor);\n }\n\n public zoomOut(factor = 1.2): void {\n this.setZoom(this.state.zoom / factor);\n }\n\n public resetZoom(): void {\n this.state.zoom = 1;\n this.state.pan = { x: 0, y: 0 };\n this.notify();\n }\n\n public setPan(pan: ImagePoint): void {\n this.state.pan = pan;\n this.notify();\n }\n\n public setComparing(comparing: boolean): void {\n if (this.state.isOriginalCompared === comparing) return;\n this.state.isOriginalCompared = comparing;\n this.notify();\n }\n\n // --- Rendering & Export ---\n\n public async render(targetCanvas: HTMLCanvasElement, options?: RenderOptions): Promise<void> {\n const source = this.imageElement || this.state.sourceUrl;\n if (!source) return;\n try {\n await this.renderer.renderToCanvas(targetCanvas, source, this.state, options);\n } catch {\n // In non-DOM or test mock environments without image loading, safely ignore\n }\n }\n\n public async renderExport(options?: ExportOptions): Promise<HTMLCanvasElement> {\n const source = this.imageElement || this.state.sourceUrl;\n if (!source) {\n return this.renderer.createCanvas(1, 1);\n }\n return this.renderer.renderExport(source, this.state, options);\n }\n\n public async toDataURL(options: ExportOptions = {}): Promise<string> {\n const canvas = await this.renderExport(options);\n const format = options.format || 'image/png';\n const quality = options.quality ?? 0.92;\n return canvas.toDataURL(format, quality);\n }\n\n public async toBlob(options: ExportOptions = {}): Promise<Blob> {\n const canvas = await this.renderExport(options);\n const format = options.format || 'image/png';\n const quality = options.quality ?? 0.92;\n\n return new Promise((resolve, reject) => {\n if (canvas.toBlob) {\n canvas.toBlob((blob) => {\n if (blob) resolve(blob);\n else reject(new Error('Failed to create Blob from canvas'));\n }, format, quality);\n } else {\n // Fallback for environments lacking canvas.toBlob\n try {\n const dataUrl = canvas.toDataURL(format, quality);\n const parts = dataUrl.split(',');\n const byteStr = atob(parts[1]);\n const ab = new ArrayBuffer(byteStr.length);\n const ia = new Uint8Array(ab);\n for (let i = 0; i < byteStr.length; i++) {\n ia[i] = byteStr.charCodeAt(i);\n }\n resolve(new Blob([ab], { type: format }));\n } catch (err) {\n reject(err);\n }\n }\n });\n }\n\n // --- AI Masking & Transformation Helpers ---\n\n public async renderMask(options?: { useAnnotations?: boolean; useCrop?: boolean }): Promise<HTMLCanvasElement> {\n return this.renderer.renderMask(this.state, options);\n }\n\n public async toMaskDataURL(options?: { useAnnotations?: boolean; useCrop?: boolean }): Promise<string> {\n const canvas = await this.renderMask(options);\n return canvas.toDataURL('image/png');\n }\n\n public async applyInpaintedImage(newDataUrl: string): Promise<void> {\n this.recordHistory();\n await this.loadImage(newDataUrl);\n this.clearAnnotations();\n }\n\n public async applyBackgroundRemovedImage(newDataUrl: string): Promise<void> {\n this.recordHistory();\n await this.loadImage(newDataUrl);\n }\n\n\n // --- Serialization ---\n\n public toJSON(): SerializedImageEditorState {\n return this.serializeState();\n }\n\n public loadJSON(data: SerializedImageEditorState): void {\n this.recordHistory();\n this.applySerializedState(data);\n this.notify();\n }\n\n private serializeState(): SerializedImageEditorState {\n return {\n version: 1,\n crop: this.state.crop ? { ...this.state.crop } : null,\n transform: { ...this.state.transform },\n adjustments: { ...this.state.adjustments },\n depthMask: {\n ...this.state.depthMask,\n depthRange: [...this.state.depthMask.depthRange] as [number, number],\n },\n annotations: JSON.parse(JSON.stringify(this.state.annotations)),\n };\n }\n\n private applySerializedState(data: SerializedImageEditorState): void {\n this.state.crop = data.crop ? { ...data.crop } : null;\n this.state.transform = { ...data.transform };\n this.state.adjustments = { ...data.adjustments };\n this.state.depthMask = {\n ...data.depthMask,\n depthRange: [...data.depthMask.depthRange] as [number, number],\n };\n this.state.annotations = JSON.parse(JSON.stringify(data.annotations || []));\n }\n}\n","import type { CropBox, ImageEditorState, ImagePoint } from './types';\n\nexport type CropHandle = 'nw' | 'ne' | 'se' | 'sw' | 'n' | 's' | 'e' | 'w' | 'inside' | null;\n\nexport interface ViewportMetrics {\n vpWidth: number;\n vpHeight: number;\n centerX: number;\n centerY: number;\n baseW: number;\n baseH: number;\n fitScale: number;\n renderW: number;\n renderH: number;\n totalScale: number;\n imageRect: { x: number; y: number; width: number; height: number };\n cropRect: { x: number; y: number; width: number; height: number } | null;\n}\n\n/**\n * Calculates current viewport projection metrics for canvas <-> image coordinate mapping.\n */\nexport function getViewportMetrics(\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping = false,\n cropOverride?: CropBox | null\n): ViewportMetrics {\n const { imageDimensions, crop: stateCrop, transform, zoom, pan } = state;\n const naturalWidth = imageDimensions.width || 800;\n const naturalHeight = imageDimensions.height || 600;\n const activeCrop =\n (cropOverride !== undefined && cropOverride !== null)\n ? cropOverride\n : (stateCrop ?? (isActivelyCropping ? { x: 0, y: 0, width: naturalWidth, height: naturalHeight } : null));\n\n const cropW = (!isActivelyCropping && activeCrop) ? activeCrop.width : naturalWidth;\n const cropH = (!isActivelyCropping && activeCrop) ? activeCrop.height : naturalHeight;\n\n const angle = ((transform.rotate % 360) + 360) % 360;\n const isSwapped = angle === 90 || angle === 270;\n const baseW = isSwapped ? cropH : cropW;\n const baseH = isSwapped ? cropW : cropH;\n\n const fitScale = Math.min((vpWidth * 0.85) / baseW, (vpHeight * 0.85) / baseH, 1);\n const renderW = baseW * fitScale;\n const renderH = baseH * fitScale;\n const totalScale = zoom * fitScale;\n\n const centerX = vpWidth / 2 + pan.x;\n const centerY = vpHeight / 2 + pan.y;\n\n const imageRect = {\n x: centerX - (renderW * zoom) / 2,\n y: centerY - (renderH * zoom) / 2,\n width: renderW * zoom,\n height: renderH * zoom,\n };\n\n let cropRect: { x: number; y: number; width: number; height: number } | null = null;\n if (activeCrop) {\n const startX = -renderW / 2 + (activeCrop.x / naturalWidth) * renderW;\n const startY = -renderH / 2 + (activeCrop.y / naturalHeight) * renderH;\n const cropBoxW = (activeCrop.width / naturalWidth) * renderW;\n const cropBoxH = (activeCrop.height / naturalHeight) * renderH;\n\n cropRect = {\n x: centerX + zoom * startX,\n y: centerY + zoom * startY,\n width: zoom * cropBoxW,\n height: zoom * cropBoxH,\n };\n }\n\n return {\n vpWidth,\n vpHeight,\n centerX,\n centerY,\n baseW,\n baseH,\n fitScale,\n renderW,\n renderH,\n totalScale,\n imageRect,\n cropRect,\n };\n}\n\n/**\n * Converts a point on the canvas (in internal canvas pixel space) to image/annotation pixel space.\n */\nexport function canvasToImagePoint(\n canvasPt: ImagePoint,\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping = false\n): ImagePoint {\n const metrics = getViewportMetrics(state, vpWidth, vpHeight, isActivelyCropping);\n const unzoomedX = (canvasPt.x - metrics.centerX) / state.zoom;\n const unzoomedY = (canvasPt.y - metrics.centerY) / state.zoom;\n\n const x = (unzoomedX + metrics.renderW / 2) / metrics.fitScale;\n const y = (unzoomedY + metrics.renderH / 2) / metrics.fitScale;\n\n return { x: Math.round(x), y: Math.round(y) };\n}\n\n/**\n * Converts a point in image/annotation pixel space to internal canvas pixel space.\n */\nexport function imageToCanvasPoint(\n imgPt: ImagePoint,\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping = false\n): ImagePoint {\n const metrics = getViewportMetrics(state, vpWidth, vpHeight, isActivelyCropping);\n const unzoomedX = (imgPt.x - metrics.baseW / 2) * metrics.fitScale;\n const unzoomedY = (imgPt.y - metrics.baseH / 2) * metrics.fitScale;\n\n const canvasX = metrics.centerX + unzoomedX * state.zoom;\n const canvasY = metrics.centerY + unzoomedY * state.zoom;\n\n return { x: Math.round(canvasX), y: Math.round(canvasY) };\n}\n\n/**\n * Hit-tests the crop box and its corner/edge handles given a canvas point.\n */\nexport function hitTestCrop(\n canvasPt: ImagePoint,\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n handleThreshold = 14,\n cropOverride?: CropBox | null\n): CropHandle {\n const metrics = getViewportMetrics(state, vpWidth, vpHeight, true, cropOverride);\n if (!metrics.cropRect) return null;\n\n const { x, y, width: w, height: h } = metrics.cropRect;\n const px = canvasPt.x;\n const py = canvasPt.y;\n\n // 1. Corners (highest priority)\n const dist = (x1: number, y1: number, x2: number, y2: number) =>\n Math.hypot(x1 - x2, y1 - y2);\n\n if (dist(px, py, x, y) <= handleThreshold) return 'nw';\n if (dist(px, py, x + w, y) <= handleThreshold) return 'ne';\n if (dist(px, py, x + w, y + h) <= handleThreshold) return 'se';\n if (dist(px, py, x, y + h) <= handleThreshold) return 'sw';\n\n // 2. Edges\n const nearX = px >= x - handleThreshold && px <= x + w + handleThreshold;\n const nearY = py >= y - handleThreshold && py <= y + h + handleThreshold;\n\n if (nearX && Math.abs(py - y) <= handleThreshold) return 'n';\n if (nearX && Math.abs(py - (y + h)) <= handleThreshold) return 's';\n if (nearY && Math.abs(px - x) <= handleThreshold) return 'w';\n if (nearY && Math.abs(px - (x + w)) <= handleThreshold) return 'e';\n\n // 3. Inside crop region\n if (px >= x && px <= x + w && py >= y && py <= y + h) {\n return 'inside';\n }\n\n return null;\n}\n\n/**\n * Returns CSS cursor style corresponding to a crop handle.\n */\nexport function getCropCursor(handle: CropHandle): string {\n switch (handle) {\n case 'nw':\n case 'se':\n return 'nwse-resize';\n case 'ne':\n case 'sw':\n return 'nesw-resize';\n case 'n':\n case 's':\n return 'ns-resize';\n case 'e':\n case 'w':\n return 'ew-resize';\n case 'inside':\n return 'move';\n default:\n return 'crosshair';\n }\n}\n\n/**\n * Calculates updated crop rectangle given a drag interaction.\n */\nexport function calculateCropDrag(\n startCrop: CropBox,\n handle: CropHandle,\n startImgPt: ImagePoint,\n currentImgPt: ImagePoint,\n imgWidth: number,\n imgHeight: number,\n aspectRatio?: number | null\n): CropBox {\n const dx = currentImgPt.x - startImgPt.x;\n const dy = currentImgPt.y - startImgPt.y;\n\n // Whole crop box move\n if (handle === 'inside') {\n const maxX = Math.max(0, imgWidth - startCrop.width);\n const maxY = Math.max(0, imgHeight - startCrop.height);\n const newX = Math.max(0, Math.min(maxX, startCrop.x + dx));\n const newY = Math.max(0, Math.min(maxY, startCrop.y + dy));\n return {\n x: Math.round(newX),\n y: Math.round(newY),\n width: startCrop.width,\n height: startCrop.height,\n };\n }\n\n // Handle resizing\n let left = startCrop.x;\n let top = startCrop.y;\n let right = startCrop.x + startCrop.width;\n let bottom = startCrop.y + startCrop.height;\n\n const minSize = 20;\n\n if (handle === 'e' || handle === 'ne' || handle === 'se') {\n right = Math.min(imgWidth, Math.max(left + minSize, startCrop.x + startCrop.width + dx));\n }\n if (handle === 'w' || handle === 'nw' || handle === 'sw') {\n left = Math.max(0, Math.min(right - minSize, startCrop.x + dx));\n }\n if (handle === 's' || handle === 'se' || handle === 'sw') {\n bottom = Math.min(imgHeight, Math.max(top + minSize, startCrop.y + startCrop.height + dy));\n }\n if (handle === 'n' || handle === 'nw' || handle === 'ne') {\n top = Math.max(0, Math.min(bottom - minSize, startCrop.y + dy));\n }\n\n // Maintain aspect ratio if requested\n if (aspectRatio && aspectRatio > 0) {\n let currentW = right - left;\n let currentH = bottom - top;\n\n if (handle === 'e' || handle === 'w') {\n currentH = Math.min(imgHeight, currentW / aspectRatio);\n bottom = Math.min(imgHeight, top + currentH);\n } else if (handle === 'n' || handle === 's') {\n currentW = Math.min(imgWidth, currentH * aspectRatio);\n right = Math.min(imgWidth, left + currentW);\n } else {\n // Corner resizing\n const targetH = currentW / aspectRatio;\n if (top + targetH <= imgHeight) {\n bottom = top + targetH;\n } else {\n const targetW = currentH * aspectRatio;\n right = Math.min(imgWidth, left + targetW);\n }\n }\n }\n\n return {\n x: Math.round(left),\n y: Math.round(top),\n width: Math.round(Math.max(minSize, right - left)),\n height: Math.round(Math.max(minSize, bottom - top)),\n };\n}\n\n/**\n * Calculates bounding box of an annotation.\n */\nexport function getAnnotationBounds(ann: import('./types').Annotation): { x: number; y: number; width: number; height: number } {\n switch (ann.type) {\n case 'rect':\n return { x: ann.x, y: ann.y, width: ann.width, height: ann.height };\n case 'circle':\n return {\n x: ann.x - ann.radiusX,\n y: ann.y - ann.radiusY,\n width: ann.radiusX * 2,\n height: ann.radiusY * 2,\n };\n case 'arrow':\n case 'line': {\n const minX = Math.min(ann.x, ann.endX);\n const minY = Math.min(ann.y, ann.endY);\n return {\n x: minX,\n y: minY,\n width: Math.max(Math.abs(ann.endX - ann.x), 10),\n height: Math.max(Math.abs(ann.endY - ann.y), 10),\n };\n }\n case 'pen': {\n if (!ann.points.length) return { x: ann.x, y: ann.y, width: 0, height: 0 };\n let minX = ann.points[0].x;\n let maxX = ann.points[0].x;\n let minY = ann.points[0].y;\n let maxY = ann.points[0].y;\n for (const pt of ann.points) {\n if (pt.x < minX) minX = pt.x;\n if (pt.x > maxX) maxX = pt.x;\n if (pt.y < minY) minY = pt.y;\n if (pt.y > maxY) maxY = pt.y;\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n }\n case 'text':\n return {\n x: ann.x,\n y: ann.y,\n width: ann.text.length * ann.fontSize * 0.6,\n height: ann.fontSize * 1.2,\n };\n case 'image':\n return { x: ann.x, y: ann.y, width: ann.width, height: ann.height };\n }\n}\n\n/**\n * Hit tests if a point in image space is within an annotation's bounds.\n */\nexport function hitTestAnnotation(imgPt: ImagePoint, ann: import('./types').Annotation, padding = 10): boolean {\n const b = getAnnotationBounds(ann);\n return (\n imgPt.x >= b.x - padding &&\n imgPt.x <= b.x + b.width + padding &&\n imgPt.y >= b.y - padding &&\n imgPt.y <= b.y + b.height + padding\n );\n}\n\n"],"mappings":"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","names":["overlaps","Plugin","Extension","Node","Extension","Extension","Plugin","Decoration","DecorationSet","Extension","MarkdownTightLists","Extension","create","name","addOptions","tight","tightClass","listTypes","addGlobalAttributes","types","options","attributes","default","parseHTML","element","getAttribute","querySelector","renderHTML","class","addCommands","_this","toggleTight","arguments","length","undefined","_ref","editor","commands","isActive","attrs","getAttributes","updateAttributes","some","md","markdownit","scanDelims","text","pos","inline","State","prototype","call","src","posMax","state","shiftDelim","delim","start","offset","res","substring","trimStart","from","to","can_open","trimEnd","can_close","trimInline","MarkdownSerializerState","BaseMarkdownSerializerState","constructor","nodes","marks","inTable","inlines","render","node","parent","index","top","end","delimiter","normalizeInline","out","pop","markString","mark","open","info","type","expelEnclosingWhitespace","push","charAt","match","Mark","addStorage","markdown","serialize","_getMarkTags$","_getMarkTags","storage","html","console","warn","getMarkTags","close","_getMarkTags$2","_getMarkTags2","parse","schema","getHTMLFromFragment","Fragment","elementFromString","value","wrappedValue","window","DOMParser","parseFromString","body","escapeHTML","replace","extractElement","parentElement","prepend","cloneNode","firstChild","appendChild","childNodes","insertBefore","remove","unwrapElement","parentNode","removeChild","Node","write","serializeHTML","isBlock","closeBlock","topNodeType","formatBlock","dom","firstElementChild","innerHTML","trim","outerHTML","Blockquote","extend","defaultMarkdownSerializer","blockquote","BulletList","renderList","bulletListMarker","CodeBlock","language","textContent","ensureNewLine","setup","_this$options$languag","set","langPrefix","languageClassPrefix","updateDOM","HardBreak","i","childCount","child","HTMLNode","Heading","heading","HorizontalRule","horizontal_rule","Image","image","ListItem","list_item","OrderedList","findIndexOfAdjacentNode","maxW","String","space","repeat","adjacentIndex","separator","nStr","Paragraph","paragraph","_node$content$content","_node$content","content","Table","isMarkdownSerializable","forEach","row","p","col","j","cellContent","renderInline","delimiterRow","Array","map","join","hasSpan","colspan","rowspan","rows","firstRow","bodyRows","slice","cell","TaskItem","check","checked","renderContent","querySelectorAll","item","input","setAttribute","TaskList","use","taskListPlugin","list","Text","Bold","strong","Code","code","Italic","em","Link","link","Strike","HTMLMark","getMarkdownSpec","extension","_extension$storage","_markdownExtensions$f","markdownSpec","defaultMarkdownSpec","markdownExtensions","find","e","MarkdownSerializer","hardBreakNodeName","_this$editor$extensio","Object","fromEntries","keys","serializeNode","extensionManager","extensions","filter","_this$editor$extensio2","serializeMark","_getMarkdownSpec","bind","_getMarkdownSpec2","MarkdownParser","linkify","breaks","withPatchedRenderer","renderedHTML","normalizeDOM","_ref2","normalizeBlocks","el","_el$nextSibling","nextSibling","nodeType","TEXT_NODE","closest","blocks","values","selector","block","_block$spec$parseDOM","spec","parseDOM","tag","flat","Boolean","matches","_node$firstElementChi","_content$match$","_content$match","_content$match$2","_content$match2","firstParagraph","nextElementSibling","startSpaces","endSpaces","withoutNewLine","renderer","rendered","rules","hardbreak","softbreak","fence","code_block","renderToken","MarkdownClipboard","transformPastedText","transformCopiedText","addProseMirrorPlugins","Plugin","key","PluginKey","props","clipboardTextParser","context","plainText","parsed","parser","fromSchema","parseSlice","preserveWhitespace","clipboardTextSerializer","serializer","Markdown","priority","tightLists","tightListClass","Commands","config","setContent","emitUpdate","parseOptions","insertContentAt","range","onBeforeCreate","getMarkdown","doc","initialContent","onCreate","addExtensions","configure","Markdown","Plugin","PluginKey","resolveExt","Image","resolveExt","Link","TaskList","TaskItem","extensions","Markdown","Image","match","md","Fragment","Fragment","extensions","document","dagre","childNodes"]}
|
|
1
|
+
{"version":3,"sources":["../src/grammar/tokens.ts","../src/grammar/tokenizer.ts","../src/grammar/resolver.ts","../src/grammar/sourcemap.ts","../src/extensions/gradient-text.ts","../src/extensions/slash-commands.ts","../src/extensions/template-suggestions.ts","../src/extensions/loading-node.ts","../src/extensions/SmilieReplacer.ts","../src/extensions/ColorHighlighter.ts","../src/extensions/FontSize.ts","../src/extensions/rich-text-preset.ts","../src/extensions/mention.ts","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/tiptap/tight-lists.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/util/markdown.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/serialize/state.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/marks/html.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/util/dom.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/html.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/blockquote.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/bullet-list.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/code-block.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/hard-break.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/heading.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/horizontal-rule.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/image.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/list-item.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/ordered-list.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/paragraph.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/util/prosemirror.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/table.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/task-item.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/task-list.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/nodes/text.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/marks/bold.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/marks/code.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/marks/italic.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/marks/link.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/marks/strike.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/index.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/util/extensions.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/serialize/MarkdownSerializer.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/parse/MarkdownParser.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/extensions/tiptap/clipboard.js","../../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/src/Markdown.js","../src/extensions/markdown.ts","../src/extensions/image.ts","../src/serializers/mentions.ts","../src/serializers/plain-text.ts","../src/serializers/markdown.ts","../src/controller.ts","../src/spreadsheet/formula/lexer.ts","../src/spreadsheet/formula/parser.ts","../src/spreadsheet/formula/evaluator.ts","../src/spreadsheet/formula/dependency-graph.ts","../src/spreadsheet/datasource/index.ts","../src/spreadsheet/controller.ts","../src/dirty.ts","../src/history/HistoryManager.ts","../src/canvas/layout.ts","../src/canvas/clock.ts","../src/canvas/trajectory.ts","../src/canvas/displacement.ts","../src/canvas/clipboard.ts","../src/canvas/view.ts","../src/canvas/streaming.ts","../src/agent/planner.ts","../src/agent/tools.ts","../src/image-editor/filters.ts","../src/image-editor/renderer.ts","../src/image-editor/controller.ts","../src/image-editor/geometry.ts"],"sourcesContent":["/**\n * Canonical regex patterns for prompt editing tokens.\n */\nexport const TEMPLATE_REGEX = /{{\\s*([^}]+?)\\s*}}/g;\nexport const VARIABLE_REGEX = /(?<!\\{)\\{([^{}]+)\\}(?!\\})/g;\nexport const INSTRUCTION_REGEX = /__(.+?)__/g;\n\n// Backward-compatible camelCase aliases\nexport const templateRegex = TEMPLATE_REGEX;\nexport const variableRegex = VARIABLE_REGEX;\nexport const instructionRegex = INSTRUCTION_REGEX;\n\nexport type TokenType = \"template\" | \"variable\" | \"instruction\" | \"text\";\n\nexport interface Token {\n type: TokenType;\n raw: string;\n value: string;\n start: number;\n end: number;\n}\n\nexport interface TemplateVersion {\n id: string;\n version: string | number;\n body: string;\n createdAt?: any;\n [key: string]: any;\n}\n\nexport interface Template {\n id?: string;\n name: string;\n body?: string;\n latestVersion?: string | number;\n versions?: TemplateVersion[];\n color?: string;\n [key: string]: any;\n}\n\nexport interface ColorGradient {\n from: string;\n to: string;\n}\n","import {\n TEMPLATE_REGEX,\n VARIABLE_REGEX,\n INSTRUCTION_REGEX,\n Token,\n} from \"./tokens\";\n\ninterface RawMatch {\n type: \"template\" | \"variable\" | \"instruction\";\n raw: string;\n value: string;\n start: number;\n end: number;\n}\n\n/**\n * Parses any prompt string into an array of typed tokens in linear order.\n * Plain text between tokens is preserved as `{ type: 'text' }`.\n */\nexport function tokenizePrompt(text: string): Token[] {\n if (!text) {\n return [];\n }\n\n const rawMatches: RawMatch[] = [];\n\n // Match {{template}}\n const tmplRegex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = tmplRegex.exec(text)) !== null) {\n rawMatches.push({\n type: \"template\",\n raw: match[0],\n value: match[1].trim(),\n start: match.index,\n end: match.index + match[0].length,\n });\n }\n\n // Match {variable}\n const varRegex = new RegExp(VARIABLE_REGEX.source, VARIABLE_REGEX.flags);\n while ((match = varRegex.exec(text)) !== null) {\n // Avoid double matching if overlapping with template\n const start = match.index;\n const end = start + match[0].length;\n const overlaps = rawMatches.some(\n (m) => !(end <= m.start || start >= m.end),\n );\n if (!overlaps) {\n rawMatches.push({\n type: \"variable\",\n raw: match[0],\n value: match[1].trim(),\n start,\n end,\n });\n }\n }\n\n // Match __instruction__\n const instRegex = new RegExp(\n INSTRUCTION_REGEX.source,\n INSTRUCTION_REGEX.flags,\n );\n while ((match = instRegex.exec(text)) !== null) {\n const start = match.index;\n const end = start + match[0].length;\n const overlaps = rawMatches.some(\n (m) => !(end <= m.start || start >= m.end),\n );\n if (!overlaps) {\n rawMatches.push({\n type: \"instruction\",\n raw: match[0],\n value: match[1].trim(),\n start,\n end,\n });\n }\n }\n\n // Sort matches by start index\n rawMatches.sort((a, b) => a.start - b.start);\n\n const tokens: Token[] = [];\n let currentIdx = 0;\n\n for (const m of rawMatches) {\n if (m.start > currentIdx) {\n const textChunk = text.slice(currentIdx, m.start);\n tokens.push({\n type: \"text\",\n raw: textChunk,\n value: textChunk,\n start: currentIdx,\n end: m.start,\n });\n }\n tokens.push({\n type: m.type,\n raw: m.raw,\n value: m.value,\n start: m.start,\n end: m.end,\n });\n currentIdx = m.end;\n }\n\n if (currentIdx < text.length) {\n const textChunk = text.slice(currentIdx);\n tokens.push({\n type: \"text\",\n raw: textChunk,\n value: textChunk,\n start: currentIdx,\n end: text.length,\n });\n }\n\n return tokens;\n}\n","import {\n TEMPLATE_REGEX,\n VARIABLE_REGEX,\n INSTRUCTION_REGEX,\n Template,\n TemplateVersion,\n} from \"./tokens\";\n\n/**\n * Finds the latest version of a template based on `latestVersion` or last version entry.\n */\nexport function getLatestVersion(\n template: Template,\n): TemplateVersion | undefined {\n if (!template.versions || template.versions.length === 0) {\n if (template.body !== undefined) {\n return {\n id: template.id || \"default\",\n version: \"1.0\",\n body: template.body,\n };\n }\n return undefined;\n }\n if (template.latestVersion) {\n const found = template.versions.find(\n (v) => v.version === template.latestVersion,\n );\n if (found) return found;\n }\n return template.versions[template.versions.length - 1];\n}\n\nexport interface ResolveTemplatesOptions {\n bindings?: Record<string, string>;\n maxDepth?: number;\n}\n\n/** Marker substituted for a template tag that would recurse into itself. */\nexport const TEMPLATE_LOOP_ERROR = \"[Template loop detected]\";\n/** Marker substituted for a template tag nested deeper than `maxDepth`. */\nexport const TEMPLATE_DEPTH_ERROR = \"[Template max depth exceeded]\";\n\n/**\n * Returns the body a template tag resolves to, honoring version bindings.\n */\nexport function getTemplateBody(\n template: Template,\n bindings?: Record<string, string>,\n): string | undefined {\n const boundVersionId = bindings?.[template.name];\n if (boundVersionId && template.versions) {\n const boundVersion = template.versions.find(\n (v) => v.id === boundVersionId || v.version === boundVersionId,\n );\n return boundVersion?.body;\n }\n return getLatestVersion(template)?.body ?? template.body;\n}\n\n/**\n * Recursively resolves template tags `{{template_name}}` in a given text.\n * A tag that would recurse into itself is replaced with `TEMPLATE_LOOP_ERROR`,\n * and a tag nested deeper than `maxDepth` with `TEMPLATE_DEPTH_ERROR`; the rest\n * of the text still resolves normally.\n */\nexport function resolveTemplates(\n text: string,\n templates: Template[] = [],\n options?: ResolveTemplatesOptions,\n): string {\n const templateMap = new Map<string, Template>();\n for (const t of templates) {\n templateMap.set(t.name, t);\n }\n\n const maxDepth = options?.maxDepth ?? 10;\n\n function resolveRecursive(\n currentText: string,\n visited: Set<string>,\n depth: number,\n ): string {\n const regex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n\n // A function replacer keeps `$&`, `$'` etc. in template bodies literal.\n return currentText.replace(regex, (fullMatch, rawTemplateName: string) => {\n const templateName = rawTemplateName.trim();\n\n if (visited.has(templateName)) {\n return TEMPLATE_LOOP_ERROR;\n }\n\n const template = templateMap.get(templateName);\n if (!template) {\n return fullMatch;\n }\n\n const versionBody = getTemplateBody(template, options?.bindings);\n if (versionBody === undefined) {\n return fullMatch;\n }\n\n if (depth + 1 > maxDepth) {\n return TEMPLATE_DEPTH_ERROR;\n }\n\n const nextVisited = new Set(visited);\n nextVisited.add(templateName);\n\n return resolveRecursive(versionBody, nextVisited, depth + 1);\n });\n }\n\n return resolveRecursive(text, new Set(), 0);\n}\n\n/**\n * Replaces `{variableName}` with values from a dictionary.\n */\nexport function resolveVariables(\n text: string,\n values: Record<string, string | number>,\n): string {\n if (!text) return \"\";\n return text.replace(\n new RegExp(VARIABLE_REGEX.source, VARIABLE_REGEX.flags),\n (fullMatch, varName) => {\n const key = varName.trim();\n if (Object.prototype.hasOwnProperty.call(values, key)) {\n return String(values[key]);\n }\n return fullMatch;\n },\n );\n}\n\n/**\n * Extracts unique template names referenced in text.\n */\nexport function extractTemplateNames(text: string): string[] {\n if (!text) return [];\n const set = new Set<string>();\n const regex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n set.add(match[1].trim());\n }\n return Array.from(set);\n}\n\n/**\n * Extracts unique variable names referenced in text.\n */\nexport function extractVariableNames(text: string): string[] {\n if (!text) return [];\n const set = new Set<string>();\n const regex = new RegExp(VARIABLE_REGEX.source, VARIABLE_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n set.add(match[1].trim());\n }\n return Array.from(set);\n}\n\n/**\n * Extracts unique instruction names referenced in text.\n */\nexport function extractInstructionNames(text: string): string[] {\n if (!text) return [];\n const set = new Set<string>();\n const regex = new RegExp(INSTRUCTION_REGEX.source, INSTRUCTION_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n set.add(match[1].trim());\n }\n return Array.from(set);\n}\n","import { TEMPLATE_REGEX, Template } from \"./tokens\";\nimport {\n getTemplateBody,\n resolveTemplates,\n type ResolveTemplatesOptions,\n} from \"./resolver\";\n\nexport interface SourceMapSegment {\n resolvedStart: number;\n resolvedEnd: number;\n source: \"raw\" | \"template\";\n rawStart: number;\n rawEnd: number;\n templateName?: string;\n}\n\n/**\n * Resolves templates in text while tracking character offset mapping\n * between the raw input and the fully resolved output.\n */\nexport function resolveTemplatesWithMapping(\n text: string,\n templates: Template[] = [],\n templateBindings?: Record<string, string>,\n options?: Pick<ResolveTemplatesOptions, \"maxDepth\">,\n): { text: string; map: SourceMapSegment[] } {\n if (!templates || templates.length === 0 || !text.includes(\"{{\")) {\n return {\n text,\n map: [\n {\n resolvedStart: 0,\n resolvedEnd: text.length,\n source: \"raw\",\n rawStart: 0,\n rawEnd: text.length,\n },\n ],\n };\n }\n\n const templateMap = new Map(templates.map((t) => [t.name, t]));\n const regex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n let match: RegExpExecArray | null;\n let lastIndex = 0;\n let resolvedText = \"\";\n const map: SourceMapSegment[] = [];\n\n while ((match = regex.exec(text)) !== null) {\n const [fullMatch, rawTemplateName] = match;\n const templateName = rawTemplateName.trim();\n const matchIndex = match.index;\n\n // Add raw text preceding this template match\n if (matchIndex > lastIndex) {\n const rawSegment = text.substring(lastIndex, matchIndex);\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + rawSegment.length,\n source: \"raw\",\n rawStart: lastIndex,\n rawEnd: matchIndex,\n });\n resolvedText += rawSegment;\n }\n\n let resolvedBody = fullMatch;\n let isTemplate = false;\n\n const template = templateMap.get(templateName);\n if (template && getTemplateBody(template, templateBindings) !== undefined) {\n // Resolve the tag itself so loop and depth handling match resolveTemplates.\n resolvedBody = resolveTemplates(fullMatch, templates, {\n bindings: templateBindings,\n maxDepth: options?.maxDepth,\n });\n isTemplate = true;\n }\n\n if (isTemplate) {\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + resolvedBody.length,\n source: \"template\",\n rawStart: matchIndex,\n rawEnd: matchIndex + fullMatch.length,\n templateName,\n });\n resolvedText += resolvedBody;\n } else {\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + fullMatch.length,\n source: \"raw\",\n rawStart: matchIndex,\n rawEnd: matchIndex + fullMatch.length,\n });\n resolvedText += fullMatch;\n }\n\n lastIndex = matchIndex + fullMatch.length;\n }\n\n // Add any remaining raw text after the final match\n if (lastIndex < text.length) {\n const rawSegment = text.substring(lastIndex);\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + rawSegment.length,\n source: \"raw\",\n rawStart: lastIndex,\n rawEnd: text.length,\n });\n resolvedText += rawSegment;\n }\n\n return { text: resolvedText, map };\n}\n\n/**\n * Maps an offset in resolved text back to the corresponding offset in raw text.\n */\nexport function mapResolvedOffsetToRaw(\n resolvedOffset: number,\n map: SourceMapSegment[],\n): number {\n for (let i = 0; i < map.length; i++) {\n const seg = map[i];\n const isLast = i === map.length - 1;\n const inRange = isLast\n ? resolvedOffset >= seg.resolvedStart && resolvedOffset <= seg.resolvedEnd\n : resolvedOffset >= seg.resolvedStart && resolvedOffset < seg.resolvedEnd;\n\n if (inRange) {\n if (seg.source === \"raw\") {\n return seg.rawStart + (resolvedOffset - seg.resolvedStart);\n }\n // The end of the text maps to the end of the tag; anywhere inside a\n // resolved template maps to the start of its tag.\n if (resolvedOffset === seg.resolvedEnd) {\n return seg.rawEnd;\n }\n return seg.rawStart;\n }\n }\n return resolvedOffset;\n}\n\n/**\n * Maps an offset in raw text to the corresponding offset in resolved text.\n */\nexport function mapRawOffsetToResolved(\n rawOffset: number,\n map: SourceMapSegment[],\n): number {\n for (let i = 0; i < map.length; i++) {\n const seg = map[i];\n const isLast = i === map.length - 1;\n const inRange = isLast\n ? rawOffset >= seg.rawStart && rawOffset <= seg.rawEnd\n : rawOffset >= seg.rawStart && rawOffset < seg.rawEnd;\n\n if (inRange) {\n if (seg.source === \"raw\") {\n return seg.resolvedStart + (rawOffset - seg.rawStart);\n }\n if (rawOffset === seg.rawEnd) {\n return seg.resolvedEnd;\n }\n return seg.resolvedStart;\n }\n }\n return rawOffset;\n}\n","import { Mark } from \"@tiptap/core\";\nimport { Plugin } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport type { Node as ProsemirrorNode } from \"@tiptap/pm/model\";\nimport type { EditorState } from \"@tiptap/pm/state\";\nimport { TEMPLATE_REGEX, VARIABLE_REGEX, INSTRUCTION_REGEX, ColorGradient } from \"../grammar/tokens\";\n\nexport interface GradientTextOptions {\n templateColorMap: Map<string, ColorGradient>;\n speed?: number;\n jsonVariables?: string[] | Set<string>;\n onTemplateClick?: (templateName: string, event: MouseEvent) => void;\n}\n\nconst createGradientDecorations = (\n doc: ProsemirrorNode,\n options: GradientTextOptions,\n): Decoration[] => {\n const decorations: Decoration[] = [];\n const speed = options.speed ?? 1;\n const jsonVarSet = options.jsonVariables\n ? options.jsonVariables instanceof Set\n ? options.jsonVariables\n : new Set(options.jsonVariables)\n : null;\n\n doc.descendants((node, pos) => {\n if (node.isText) {\n const text = node.text || \"\";\n let match: RegExpExecArray | null;\n\n // 1. Template: {{templateName}}\n const tmplRegex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n while ((match = tmplRegex.exec(text)) !== null) {\n const templateName = match[1].trim();\n const colors = options.templateColorMap?.get(templateName);\n\n if (colors) {\n const start = pos + match.index;\n const end = start + match[0].length;\n const { from: colorFrom, to: colorTo } = colors;\n\n const style = `--bg-size: ${\n speed * 300\n }%; --color-from: ${colorFrom}; --color-to: ${colorTo}; caret-color: #111 !important; background-image: linear-gradient(to right, ${colorFrom}, ${colorTo}, ${colorFrom}); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent;`;\n\n decorations.push(\n Decoration.inline(start, end, {\n class:\n \"inline animate-gradient bg-gradient-to-r from-[var(--color-from)] via-[var(--color-to)] to-[var(--color-from)] bg-[length:var(--bg-size)_100%] bg-clip-text text-transparent border border-(--color-to)/20 px-1 py-0.5 rounded-sm cursor-pointer\",\n style,\n \"data-template\": templateName,\n }),\n );\n }\n }\n\n // 2. Instruction: __text__\n const instRegex = new RegExp(\n INSTRUCTION_REGEX.source,\n INSTRUCTION_REGEX.flags,\n );\n while ((match = instRegex.exec(text)) !== null) {\n const content = match[1].trim();\n const colors = options.templateColorMap?.get(content) || {\n from: \"#ffaa40\",\n to: \"#9c40ff\",\n };\n\n const start = pos + match.index;\n const end = start + match[0].length;\n const { from: colorFrom, to: colorTo } = colors;\n\n const style = `--bg-size: ${\n speed * 300\n }%; --color-from: ${colorFrom}; --color-to: ${colorTo}; caret-color: #111 !important; background-image: linear-gradient(to right, #fb7185, #8b5cf6, #fb7185); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent;`;\n\n decorations.push(\n Decoration.inline(start, end, {\n class:\n \"italic animate-gradient bg-gradient-to-r from-rose-400 from-50% to-violet-500 to-50% bg-size-[200%_100%] bg-clip-text text-transparent inline-flex items-baseline gap-0.5\",\n style,\n }),\n );\n }\n\n // 3. Variable: {variableName}\n const varRegex = new RegExp(\n VARIABLE_REGEX.source,\n VARIABLE_REGEX.flags,\n );\n while ((match = varRegex.exec(text)) !== null) {\n const variableName = match[1].trim();\n const start = pos + match.index;\n const end = start + match[0].length;\n const isJsonVar = jsonVarSet?.has(variableName);\n\n decorations.push(\n Decoration.inline(start, end, {\n class: isJsonVar\n ? \"bg-violet-400/40 border-b-4 border-rose-300 dark:border-rose-800 inline-flex items-baseline px-1 py-0 text-foreground/80 gap-0.5 rounded-xs\"\n : \"bg-rose-400/40 border-b-4 border-violet-300 dark:border-violet-800 inline-flex items-baseline px-1 py-0 text-foreground/80 gap-0.5 rounded-xs\",\n \"data-variable\": variableName,\n }),\n );\n }\n }\n });\n\n return decorations;\n};\n\nexport const GradientText = Mark.create<GradientTextOptions>({\n name: \"gradientText\",\n\n addOptions() {\n return {\n templateColorMap: new Map(),\n speed: 1,\n jsonVariables: undefined,\n onTemplateClick: undefined,\n };\n },\n\n renderHTML({ HTMLAttributes }) {\n const defaultColors = {\n from: \"#ffaa40\",\n to: \"#9c40ff\",\n };\n const speed = this.options.speed ?? 1;\n const style = `--bg-size: ${speed * 300}%; --color-from: ${\n defaultColors.from\n }; --color-to: ${defaultColors.to}; caret-color: #111 !important;`;\n\n return [\n \"span\",\n {\n class:\n \"inline animate-gradient bg-gradient-to-r from-[var(--color-from)] via-[var(--color-to)] to-[var(--color-from)] bg-[length:var(--bg-size)_100%] bg-clip-text text-transparent\",\n style,\n ...HTMLAttributes,\n },\n 0,\n ];\n },\n\n parseHTML() {\n return [\n {\n tag: \"span\",\n getAttrs: (node) =>\n (node as HTMLElement).classList.contains(\"animate-gradient\") &&\n (node as HTMLElement).classList.contains(\"bg-clip-text\") &&\n null,\n },\n ];\n },\n\n addProseMirrorPlugins() {\n const markOptions = this.options;\n\n return [\n new Plugin({\n state: {\n init(_, { doc }) {\n return DecorationSet.create(\n doc,\n createGradientDecorations(doc, markOptions),\n );\n },\n apply(tr, value: DecorationSet) {\n const newDoc = tr.doc;\n if (tr.docChanged) {\n return DecorationSet.create(\n newDoc,\n createGradientDecorations(newDoc, markOptions),\n );\n }\n return value.map(tr.mapping, newDoc);\n },\n },\n props: {\n decorations(state: EditorState) {\n return (this as any).getState(state) as DecorationSet;\n },\n handleClickOn(view, pos, _node, _nodePos, event) {\n const decorationSet = (this as any).getState(\n view.state,\n ) as DecorationSet;\n const decorations = decorationSet.find(pos, pos + 1);\n\n for (const decoration of decorations) {\n const decorationWithAttrs = decoration as any;\n const templateName =\n decorationWithAttrs.type?.attrs?.[\"data-template\"];\n if (templateName) {\n if (markOptions.onTemplateClick) {\n markOptions.onTemplateClick(templateName, event as MouseEvent);\n }\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(\n new CustomEvent(\"show-gradient-popover\", {\n detail: {\n templateName,\n target: event.target,\n },\n }),\n );\n }\n return true;\n }\n }\n return false;\n },\n },\n }),\n ];\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport { Plugin } from \"@tiptap/pm/state\";\n\nexport interface SlashCommandMatchData {\n match: RegExpMatchArray;\n query: string;\n from: number;\n to: number;\n coords: { top: number; left: number; bottom: number; right: number };\n}\n\nexport interface SlashCommandsOptions {\n trigger?: string;\n onMatch?: (data: SlashCommandMatchData) => void;\n onClear?: () => void;\n containerId?: string;\n}\n\nexport const SlashCommands = Extension.create<SlashCommandsOptions>({\n name: \"slashCommands\",\n\n addOptions() {\n return {\n trigger: \"/\",\n onMatch: undefined,\n onClear: undefined,\n containerId: undefined,\n };\n },\n\n addProseMirrorPlugins() {\n const opts = this.options;\n\n return [\n new Plugin({\n view() {\n return {\n update(view) {\n const { state } = view;\n const { selection } = state;\n const { $from } = selection;\n\n if (!$from.parent.isTextblock) {\n opts.onClear?.();\n return;\n }\n\n const textBeforeCursor = $from.parent.textBetween(\n 0,\n $from.parentOffset,\n );\n\n const slashMatch = textBeforeCursor.match(\n /(?:^|\\s)\\/([a-zA-Z0-9_-]*)$/,\n );\n\n if (slashMatch) {\n const matchIndex = slashMatch.index ?? 0;\n const offsetInParent =\n matchIndex + (slashMatch[0].startsWith(\" \") ? 1 : 0);\n const matchFrom = $from.start() + offsetInParent;\n const matchTo = $from.pos;\n const coords = view.coordsAtPos($from.pos);\n\n let relativeCoords = {\n top: coords.top,\n left: coords.left,\n bottom: coords.bottom,\n right: coords.right,\n };\n\n if (opts.containerId && typeof document !== \"undefined\") {\n const container = document.getElementById(opts.containerId);\n if (container) {\n const rect = container.getBoundingClientRect();\n relativeCoords = {\n top: coords.bottom - rect.top + 5,\n left: coords.left - rect.left,\n bottom: coords.bottom - rect.top,\n right: coords.right - rect.left,\n };\n }\n }\n\n opts.onMatch?.({\n match: slashMatch,\n query: slashMatch[1] || \"\",\n from: matchFrom,\n to: matchTo,\n coords: relativeCoords,\n });\n } else {\n opts.onClear?.();\n }\n },\n };\n },\n }),\n ];\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport Suggestion, { SuggestionOptions } from \"@tiptap/suggestion\";\nimport { Template } from \"../grammar/tokens\";\n\nexport interface TemplateSuggestionsOptions {\n templates: Template[];\n char?: string;\n onSuggestion?: (props: {\n query: string;\n range: { from: number; to: number };\n clientRect?: (() => DOMRect | null) | null;\n items: Template[];\n command: (props: { name: string }) => void;\n }) => void;\n}\n\nexport const TemplateSuggestions = Extension.create<TemplateSuggestionsOptions>({\n name: \"templateSuggestions\",\n\n addOptions() {\n return {\n templates: [],\n char: \"{{\",\n onSuggestion: undefined,\n };\n },\n\n addProseMirrorPlugins() {\n const opts = this.options;\n\n const suggestionConfig: Omit<SuggestionOptions<Template>, \"editor\"> = {\n char: opts.char || \"{{\",\n items: ({ query }) => {\n const lower = query.toLowerCase();\n return (opts.templates || []).filter((t) =>\n t.name.toLowerCase().includes(lower),\n );\n },\n command: ({ editor, range, props }) => {\n editor\n .chain()\n .focus()\n .deleteRange(range)\n .insertContent(`{{${props.name}}}`)\n .run();\n },\n render: () => {\n return {\n onStart: (props) => {\n opts.onSuggestion?.(props as any);\n },\n onUpdate: (props) => {\n opts.onSuggestion?.(props as any);\n },\n onExit: () => {\n opts.onSuggestion?.({\n query: \"\",\n range: { from: 0, to: 0 },\n items: [],\n command: () => {},\n });\n },\n };\n },\n };\n\n const SuggestionFn =\n typeof Suggestion === \"function\"\n ? Suggestion\n : (Suggestion as any)?.default || (Suggestion as any)?.Suggestion;\n\n return [\n SuggestionFn({\n editor: this.editor,\n ...suggestionConfig,\n }),\n ];\n },\n});\n","import { Node, mergeAttributes } from \"@tiptap/core\";\n\nexport const LoadingNode = Node.create({\n name: \"loadingNode\",\n group: \"inline\",\n inline: true,\n selectable: true,\n atom: true,\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-id\"),\n renderHTML: (attributes) => {\n if (!attributes.id) return {};\n return { \"data-id\": attributes.id };\n },\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'span[data-type=\"loading\"]',\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-type\": \"loading\",\n class: \"inline-flex items-center px-1.5 py-0.5 text-xs text-muted-foreground animate-pulse\",\n }),\n \"⏳\",\n ];\n },\n});\n","import { Extension, textInputRule } from \"@tiptap/core\";\n\nexport const SmilieReplacer = Extension.create({\n name: \"smilieReplacer\",\n\n addInputRules() {\n return [\n textInputRule({ find: /-___- $/, replace: \"😑 \" }),\n textInputRule({ find: /:'-\\) $/, replace: \"😂 \" }),\n textInputRule({ find: /':-\\) $/, replace: \"😅 \" }),\n textInputRule({ find: /':-D $/, replace: \"😅 \" }),\n textInputRule({ find: />:-\\) $/, replace: \"😆 \" }),\n textInputRule({ find: /-__- $/, replace: \"😑 \" }),\n textInputRule({ find: /':-\\( $/, replace: \"😓 \" }),\n textInputRule({ find: /:'-\\( $/, replace: \"😢 \" }),\n textInputRule({ find: />:-\\( $/, replace: \"😠 \" }),\n textInputRule({ find: /O:-\\) $/, replace: \"😇 \" }),\n textInputRule({ find: /:'\\) $/, replace: \"😂 \" }),\n textInputRule({ find: /:-D $/, replace: \"😃 \" }),\n textInputRule({ find: /':\\) $/, replace: \"😅 \" }),\n textInputRule({ find: /;-\\) $/, replace: \"😉 \" }),\n textInputRule({ find: /B-\\) $/, replace: \"😎 \" }),\n textInputRule({ find: /:-\\* $/, replace: \"😘 \" }),\n textInputRule({ find: /:-\\) $/, replace: \"🙂 \" }),\n textInputRule({ find: /-_- $/, replace: \"😑 \" }),\n textInputRule({ find: /:-O $/, replace: \"😮 \" }),\n textInputRule({ find: /:-P $/, replace: \"😛 \" }),\n textInputRule({ find: /:-p $/, replace: \"😛 \" }),\n textInputRule({ find: /:-\\/ $/, replace: \"😕 \" }),\n textInputRule({ find: /:-\\( $/, replace: \"😞 \" }),\n textInputRule({ find: /:'\\( $/, replace: \"😢 \" }),\n textInputRule({ find: /:D $/, replace: \"😃 \" }),\n textInputRule({ find: /=D $/, replace: \"😃 \" }),\n textInputRule({ find: /;\\) $/, replace: \"😉 \" }),\n textInputRule({ find: /B\\) $/, replace: \"😎 \" }),\n textInputRule({ find: /:\\) $/, replace: \"🙂 \" }),\n textInputRule({ find: /=\\) $/, replace: \"🙂 \" }),\n textInputRule({ find: /:O $/, replace: \"😮 \" }),\n textInputRule({ find: /:P $/, replace: \"😛 \" }),\n textInputRule({ find: /:p $/, replace: \"😛 \" }),\n textInputRule({ find: /:\\/ $/, replace: \"😕 \" }),\n textInputRule({ find: /:\\( $/, replace: \"😞 \" }),\n textInputRule({ find: /<3 $/, replace: \"❤️ \" }),\n textInputRule({ find: /<\\/3 $/, replace: \"💔 \" }),\n textInputRule({ find: /\\/shrug $/, replace: \"¯\\\\_(ツ)_/¯ \" }),\n ];\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport { Plugin } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport type { Node as ProsemirrorNode } from \"@tiptap/pm/model\";\n\nexport function findHexColors(doc: ProsemirrorNode): DecorationSet {\n const hexColorRegex = /(#[0-9a-fA-F]{3,8})\\b/g;\n const decorations: Decoration[] = [];\n\n doc.descendants((node, position) => {\n if (!node.text) return;\n\n let match: RegExpExecArray | null;\n while ((match = hexColorRegex.exec(node.text)) !== null) {\n const color = match[0];\n const from = position + match.index;\n const to = from + color.length;\n\n decorations.push(\n Decoration.inline(from, to, {\n class: \"color-highlight px-1 py-0.5 rounded text-xs font-mono border\",\n style: `--color: ${color}; background-color: ${color}20; border-color: ${color}; color: ${color};`,\n }),\n );\n }\n });\n\n return DecorationSet.create(doc, decorations);\n}\n\nexport const ColorHighlighter = Extension.create({\n name: \"colorHighlighter\",\n\n addProseMirrorPlugins() {\n return [\n new Plugin({\n state: {\n init(_, { doc }) {\n return findHexColors(doc);\n },\n apply(transaction, oldState) {\n return transaction.docChanged ? findHexColors(transaction.doc) : oldState;\n },\n },\n props: {\n decorations(state) {\n return (this as any).getState(state);\n },\n },\n }),\n ];\n },\n});\n","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 {\n types: [\"textStyle\"],\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n fontSize: {\n default: null,\n parseHTML: (element) =>\n element.style.fontSize.replace(/['\"]+/g, \"\"),\n renderHTML: (attributes) => {\n if (!attributes.fontSize) {\n return {};\n }\n return {\n style: `font-size: ${attributes.fontSize}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setFontSize:\n (fontSize: string) =>\n ({ chain }) =>\n chain().setMark(\"textStyle\", { fontSize }).run(),\n unsetFontSize:\n () =>\n ({ chain }) =>\n chain()\n .setMark(\"textStyle\", { fontSize: null })\n .removeEmptyTextStyle()\n .run(),\n };\n },\n});\n\nexport default FontSize;\n","import {\n wrappingInputRule,\n markInputRule,\n type Extensions,\n} from \"@tiptap/core\";\nimport * as _StarterKit from \"@tiptap/starter-kit\";\nimport * as _Color from \"@tiptap/extension-color\";\nimport * as _Highlight from \"@tiptap/extension-highlight\";\nimport * as _Link from \"@tiptap/extension-link\";\nimport * as _TaskList from \"@tiptap/extension-task-list\";\nimport * as _TaskItem from \"@tiptap/extension-task-item\";\nimport * as _TextAlign from \"@tiptap/extension-text-align\";\nimport * as _TextStyle from \"@tiptap/extension-text-style\";\nimport * as _Typography from \"@tiptap/extension-typography\";\nimport * as _Underline from \"@tiptap/extension-underline\";\nimport * as _Placeholder from \"@tiptap/extension-placeholder\";\nimport * as _CharacterCount from \"@tiptap/extension-character-count\";\n\nconst resolveExt = (mod: any, name: string) =>\n mod?.[name] ||\n mod?.default?.[name] ||\n mod?.default?.default ||\n mod?.default ||\n mod;\n\nconst StarterKit = resolveExt(_StarterKit, \"StarterKit\");\nconst Color = resolveExt(_Color, \"Color\");\nconst Highlight = resolveExt(_Highlight, \"Highlight\");\nconst Link = resolveExt(_Link, \"Link\");\nconst TaskList = resolveExt(_TaskList, \"TaskList\");\nconst TaskItem = resolveExt(_TaskItem, \"TaskItem\");\nconst TextAlign = resolveExt(_TextAlign, \"TextAlign\");\nconst TextStyle = resolveExt(_TextStyle, \"TextStyle\");\nconst Typography = resolveExt(_Typography, \"Typography\");\nconst Underline = resolveExt(_Underline, \"Underline\");\nconst Placeholder = resolveExt(_Placeholder, \"Placeholder\");\nconst CharacterCount = resolveExt(_CharacterCount, \"CharacterCount\");\n\nimport { SmilieReplacer } from \"./SmilieReplacer\";\nimport { ColorHighlighter } from \"./ColorHighlighter\";\nimport { FontSize } from \"./FontSize\";\nimport { Mention, type MentionOptions } from \"./mention\";\nimport { Markdown, type MarkdownOptions } from \"./markdown\";\nimport { Image, type ImageOptions } from \"./image\";\n\nexport interface RichTextPresetOptions {\n placeholder?: string | ((props: { node: any }) => string);\n characterLimit?: number;\n openLinksOnClick?: boolean;\n enableSmilies?: boolean;\n enableColorHighlighter?: boolean;\n headingLevels?: (1 | 2 | 3 | 4 | 5 | 6)[];\n mention?: MentionOptions | boolean;\n markdown?: MarkdownOptions | boolean;\n image?: ImageOptions | boolean;\n}\n\n/**\n * Creates a standard rich-text extensions bundle with full formatting support.\n */\nexport function createRichTextPreset(\n options: RichTextPresetOptions = {},\n): Extensions {\n const {\n placeholder = \"Start typing...\",\n characterLimit,\n openLinksOnClick = false,\n enableSmilies = true,\n enableColorHighlighter = true,\n headingLevels = [1, 2, 3, 4],\n } = options;\n\n const extensions: Extensions = [\n StarterKit.configure({\n orderedList: {\n HTMLAttributes: {\n class: \"list-decimal pl-4\",\n },\n },\n bulletList: {\n HTMLAttributes: {\n class: \"list-disc pl-4\",\n },\n },\n heading: {\n levels: headingLevels,\n HTMLAttributes: {\n class: \"font-bold tracking-tight\",\n },\n },\n }),\n TextStyle,\n Color,\n Highlight.configure({ multicolor: true }),\n Underline,\n Typography,\n TextAlign.configure({\n types: [\"heading\", \"paragraph\"],\n }),\n Link.extend({\n addInputRules() {\n return [\n markInputRule({\n find: /(?:^|\\s)\\[([^\\]]+)\\]\\(([^)]+)\\)$/,\n type: this.type,\n getAttributes: (match) => ({\n href: match[2],\n }),\n }),\n ];\n },\n }).configure({\n openOnClick: openLinksOnClick,\n autolink: true,\n defaultProtocol: \"https\",\n protocols: [\"file\", \"vscode\", \"cursor\"],\n HTMLAttributes: {\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n class: \"text-blue-500 underline underline-offset-2\",\n },\n }),\n TaskList,\n TaskItem.extend({\n addInputRules() {\n return [\n wrappingInputRule({\n find: /^\\s*(\\[([ |x])?\\])\\s$/i,\n type: this.type,\n getAttributes: (match) => ({\n checked: match[2]?.toLowerCase() === \"x\",\n }),\n }),\n ];\n },\n }).configure({\n nested: true,\n }),\n FontSize,\n Placeholder.configure({\n emptyEditorClass: \"is-empty\",\n placeholder:\n typeof placeholder === \"function\" ? placeholder : () => placeholder,\n }),\n ];\n\n if (characterLimit) {\n extensions.push(\n CharacterCount.configure({\n limit: characterLimit,\n }),\n );\n }\n\n if (enableSmilies) {\n extensions.push(SmilieReplacer);\n }\n\n if (enableColorHighlighter) {\n extensions.push(ColorHighlighter);\n }\n\n if (options.mention) {\n const mentionConfig =\n typeof options.mention === \"object\" ? options.mention : {};\n extensions.push(\n Mention.configure({\n HTMLAttributes: {\n class: \"pixerate-mention-node\",\n ...(mentionConfig.HTMLAttributes || {}),\n },\n ...mentionConfig,\n }),\n );\n }\n\n if (options.markdown) {\n const markdownConfig =\n typeof options.markdown === \"object\" ? options.markdown : {};\n extensions.push(\n Markdown.configure({\n html: true,\n tightLists: true,\n tightListClass: \"tight\",\n bulletListMarker: \"-\",\n linkify: true,\n breaks: true,\n transformPastedText: true,\n transformCopiedText: true,\n ...markdownConfig,\n }),\n );\n }\n\n if (options.image !== false) {\n const imageConfig =\n typeof options.image === \"object\" ? options.image : {};\n extensions.push(\n Image.configure({\n HTMLAttributes: {\n class: \"rounded-md max-w-full h-auto my-2\",\n ...(imageConfig.HTMLAttributes || {}),\n },\n ...imageConfig,\n }),\n );\n }\n\n return extensions;\n}\n","import {\n Mention as TipTapMention,\n type MentionOptions as TipTapMentionOptions,\n} from \"@tiptap/extension-mention\";\nimport type { SuggestionOptions } from \"@tiptap/suggestion\";\n\nexport interface MentionEntity {\n id: string;\n label: string;\n type?: string;\n avatarUrl?: string;\n color?: string;\n handle?: string;\n name?: string;\n hexColor?: string;\n aliases?: string[];\n [key: string]: any;\n}\n\nexport interface MentionOptions extends Partial<TipTapMentionOptions> {\n HTMLAttributes?: Record<string, any>;\n suggestion?: Partial<SuggestionOptions<MentionEntity>>;\n}\n\nconst BaseMention =\n TipTapMention ||\n (TipTapMention as any)?.default?.default ||\n (TipTapMention as any)?.default ||\n (TipTapMention as any);\n\n/**\n * First-class native Mention extension for @pixerate/editor.\n * Creates atomic inline <span data-type=\"mention\"> nodes with full suggestion support.\n */\nexport const Mention = BaseMention.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n type: {\n default: null,\n parseHTML: (element: HTMLElement) =>\n element.getAttribute(\"data-type-name\") ||\n element.getAttribute(\"data-entity-type\"),\n renderHTML: (attributes: Record<string, any>) => {\n if (!attributes.type) return {};\n return { \"data-type-name\": attributes.type };\n },\n },\n avatarUrl: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute(\"data-avatar-url\"),\n renderHTML: (attributes: Record<string, any>) => {\n if (!attributes.avatarUrl) return {};\n return { \"data-avatar-url\": attributes.avatarUrl };\n },\n },\n color: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute(\"data-color\"),\n renderHTML: (attributes: Record<string, any>) => {\n if (!attributes.color) return {};\n return { \"data-color\": attributes.color };\n },\n },\n };\n },\n});\n\n/**\n * Helper to configure the Mention extension with preset defaults.\n */\nexport function createMentionExtension(options: Partial<MentionOptions> = {}) {\n const { HTMLAttributes = {}, ...rest } = options;\n return Mention.configure({\n HTMLAttributes: {\n class: \"pixerate-mention-node\",\n ...HTMLAttributes,\n },\n ...rest,\n });\n}\n","import { Extension } from \"@tiptap/core\";\n\nexport const MarkdownTightLists = Extension.create({\n name: 'markdownTightLists',\n addOptions: () => ({\n tight: true,\n tightClass: 'tight',\n listTypes: [\n 'bulletList',\n 'orderedList',\n ],\n }),\n addGlobalAttributes() {\n return [\n {\n types: this.options.listTypes,\n attributes: {\n tight: {\n default: this.options.tight,\n parseHTML: element =>\n element.getAttribute('data-tight') === 'true' || !element.querySelector('p'),\n renderHTML: attributes => ({\n class: attributes.tight ? this.options.tightClass : null,\n 'data-tight': attributes.tight ? 'true' : null,\n }),\n },\n },\n },\n ]\n },\n addCommands() {\n return {\n toggleTight: (tight = null) => ({ editor, commands }) => {\n function toggleTight(name) {\n if(!editor.isActive(name)) {\n return false;\n }\n const attrs = editor.getAttributes(name);\n return commands.updateAttributes(name, {\n tight: tight ?? !attrs?.tight,\n });\n }\n return this.options.listTypes\n .some(name => toggleTight(name));\n }\n }\n },\n});\n","import markdownit from 'markdown-it';\n\nconst md = markdownit();\n\nfunction scanDelims(text, pos) {\n md.inline.State.prototype.scanDelims.call({ src: text, posMax: text.length })\n const state = new (md.inline.State)(text, null, null, []);\n return state.scanDelims(pos, true);\n}\n\nexport function shiftDelim(text, delim, start, offset) {\n let res = text.substring(0, start) + text.substring(start + delim.length);\n res = res.substring(0, start + offset) + delim + res.substring(start + offset);\n return res;\n}\n\nfunction trimStart(text, delim, from, to) {\n let pos = from, res = text;\n while(pos < to) {\n if(scanDelims(res, pos).can_open) {\n break;\n }\n res = shiftDelim(res, delim, pos, 1);\n pos++;\n }\n return { text: res, from: pos, to }\n}\n\nfunction trimEnd(text, delim, from, to) {\n let pos = to, res = text;\n while(pos > from) {\n if(scanDelims(res, pos).can_close) {\n break;\n }\n res = shiftDelim(res, delim, pos, -1);\n pos--;\n }\n return { text: res, from, to: pos }\n}\n\nexport function trimInline(text, delim, from, to) {\n let state = {\n text,\n from,\n to,\n }\n\n state = trimStart(state.text, delim, state.from, state.to);\n state = trimEnd(state.text, delim, state.from, state.to);\n\n if(state.to - state.from < delim.length + 1) {\n state.text = state.text.substring(0, state.from) + state.text.substring(state.to + delim.length);\n }\n\n return state.text;\n}\n","import { MarkdownSerializerState as BaseMarkdownSerializerState } from \"prosemirror-markdown\";\nimport { trimInline } from \"../util/markdown\";\n\n\n/**\n * Override default MarkdownSerializerState to:\n * - handle commonmark delimiters (https://spec.commonmark.org/0.29/#left-flanking-delimiter-run)\n */\nexport class MarkdownSerializerState extends BaseMarkdownSerializerState {\n\n inTable = false;\n\n constructor(nodes, marks, options) {\n super(nodes, marks, options ?? {});\n this.inlines = [];\n }\n\n render(node, parent, index) {\n super.render(node, parent, index);\n const top = this.inlines[this.inlines.length - 1];\n if(top?.start && top?.end) {\n const { delimiter, start, end } = this.normalizeInline(top);\n this.out = trimInline(this.out, delimiter, start, end);\n this.inlines.pop();\n }\n }\n\n markString(mark, open, parent, index) {\n const info = this.marks[mark.type.name]\n if(info.expelEnclosingWhitespace) {\n if(open) {\n this.inlines.push({\n start: this.out.length,\n delimiter: info.open,\n });\n } else {\n const top = this.inlines.pop();\n this.inlines.push({\n ...top,\n end: this.out.length,\n });\n }\n }\n return super.markString(mark, open, parent, index);\n }\n\n normalizeInline(inline) {\n let { start, end } = inline;\n while(this.out.charAt(start).match(/\\s/)) {\n start++;\n }\n return {\n ...inline,\n start,\n }\n }\n}\n","import { Fragment } from \"@tiptap/pm/model\";\nimport { getHTMLFromFragment, Mark } from \"@tiptap/core\";\n\n\nexport default Mark.create({\n name: 'markdownHTMLMark',\n /**\n * @return {{markdown: MarkdownMarkSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: {\n open(state, mark) {\n if(!this.editor.storage.markdown.options.html) {\n console.warn(`Tiptap Markdown: \"${mark.type.name}\" mark is only available in html mode`);\n return '';\n }\n return getMarkTags(mark)?.[0] ?? '';\n },\n close(state, mark) {\n if(!this.editor.storage.markdown.options.html) {\n return '';\n }\n return getMarkTags(mark)?.[1] ?? '';\n },\n },\n parse: {\n // handled by markdown-it\n }\n }\n }\n }\n});\n\nfunction getMarkTags(mark) {\n const schema = mark.type.schema;\n const node = schema.text(' ', [mark]);\n const html = getHTMLFromFragment(Fragment.from(node), schema);\n const match = html.match(/^(<.*?>) (<\\/.*?>)$/);\n return match ? [match[1], match[2]] : null;\n}\n","\n\nexport function elementFromString(value) {\n // add a wrapper to preserve leading and trailing whitespace\n const wrappedValue = `<body>${value}</body>`\n\n return new window.DOMParser().parseFromString(wrappedValue, 'text/html').body\n}\n\nexport function escapeHTML(value) {\n return value\n ?.replace(/</g, '<')\n .replace(/>/g, '>');\n}\n\nexport function extractElement(node) {\n const parent = node.parentElement;\n const prepend = parent.cloneNode();\n\n while(parent.firstChild && parent.firstChild !== node) {\n prepend.appendChild(parent.firstChild);\n }\n\n if(prepend.childNodes.length > 0) {\n parent.parentElement.insertBefore(prepend, parent);\n }\n parent.parentElement.insertBefore(node, parent);\n if(parent.childNodes.length === 0) {\n parent.remove();\n }\n}\n\nexport function unwrapElement(node) {\n const parent = node.parentNode;\n\n while (node.firstChild) parent.insertBefore(node.firstChild, node);\n\n parent.removeChild(node);\n}\n","import { Fragment } from \"@tiptap/pm/model\";\nimport { getHTMLFromFragment, Node } from \"@tiptap/core\";\nimport { elementFromString } from \"../../util/dom\";\n\n\nexport default Node.create({\n name: 'markdownHTMLNode',\n addStorage() {\n return {\n markdown: {\n serialize(state, node, parent) {\n if(this.editor.storage.markdown.options.html) {\n state.write(serializeHTML(node, parent));\n } else {\n console.warn(`Tiptap Markdown: \"${node.type.name}\" node is only available in html mode`);\n state.write(`[${node.type.name}]`);\n }\n if(node.isBlock) {\n state.closeBlock(node);\n }\n },\n parse: {\n // handled by markdown-it\n },\n },\n }\n }\n});\n\nfunction serializeHTML(node, parent) {\n const schema = node.type.schema;\n const html = getHTMLFromFragment(Fragment.from(node), schema);\n\n if(node.isBlock && (parent instanceof Fragment || parent.type.name === schema.topNodeType.name)) {\n return formatBlock(html);\n }\n\n return html;\n}\n\n/**\n * format html block as per the commonmark spec\n */\nfunction formatBlock(html) {\n const dom = elementFromString(html);\n const element = dom.firstElementChild;\n\n element.innerHTML = element.innerHTML.trim()\n ? `\\n${element.innerHTML}\\n`\n : `\\n`;\n\n return element.outerHTML;\n}\n","import { Node } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Blockquote = Node.create({\n name: 'blockquote',\n});\n\nexport default Blockquote.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.nodes.blockquote,\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\n\n\nconst BulletList = Node.create({\n name: 'bulletList',\n});\n\nexport default BulletList.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize(state, node) {\n return state.renderList(node, \" \", () => (this.editor.storage.markdown.options.bulletListMarker || \"-\") + \" \");\n },\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\n\n\nconst CodeBlock = Node.create({\n name: 'codeBlock',\n});\n\nexport default CodeBlock.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize(state, node) {\n state.write(\"```\" + (node.attrs.language || \"\") + \"\\n\");\n state.text(node.textContent, false);\n state.ensureNewLine();\n state.write(\"```\");\n state.closeBlock(node);\n },\n parse: {\n setup(markdownit) {\n markdownit.set({\n langPrefix: this.options.languageClassPrefix ?? 'language-',\n });\n },\n updateDOM(element) {\n element.innerHTML = element.innerHTML.replace(/\\n<\\/code><\\/pre>/g, '</code></pre>')\n },\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\nimport HTMLNode from './html';\n\nconst HardBreak = Node.create({\n name: 'hardBreak',\n});\n\nexport default HardBreak.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize(state, node, parent, index) {\n for (let i = index + 1; i < parent.childCount; i++)\n if (parent.child(i).type != node.type) {\n state.write(\n state.inTable\n ? HTMLNode.storage.markdown.serialize.call(this, state, node, parent)\n : \"\\\\\\n\"\n );\n return;\n }\n },\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Heading = Node.create({\n name: 'heading',\n});\n\nexport default Heading.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.nodes.heading,\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst HorizontalRule = Node.create({\n name: 'horizontalRule',\n});\n\nexport default HorizontalRule.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.nodes.horizontal_rule,\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Image = Node.create({\n name: 'image',\n});\n\nexport default Image.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.nodes.image,\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst ListItem = Node.create({\n name: 'listItem',\n});\n\nexport default ListItem.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.nodes.list_item,\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\n\n\nconst OrderedList = Node.create({\n name: 'orderedList',\n});\n\nfunction findIndexOfAdjacentNode(node, parent, index) {\n let i = 0;\n for (; index - i > 0; i++) {\n if (parent.child(index - i - 1).type.name !== node.type.name) {\n break;\n }\n }\n return i;\n}\n\nexport default OrderedList.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize(state, node, parent, index) {\n const start = node.attrs.start || 1\n const maxW = String(start + node.childCount - 1).length\n const space = state.repeat(\" \", maxW + 2)\n const adjacentIndex = findIndexOfAdjacentNode(node, parent, index);\n const separator = adjacentIndex % 2 ? ') ' : '. ';\n state.renderList(node, space, i => {\n const nStr = String(start + i)\n return state.repeat(\" \", maxW - nStr.length) + nStr + separator;\n })\n },\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Paragraph = Node.create({\n name: 'paragraph',\n});\n\nexport default Paragraph.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.nodes.paragraph,\n parse: {\n // handled by markdown-it\n },\n },\n }\n }\n});\n","\n\nexport function childNodes(node) {\n return node?.content?.content ?? [];\n}\n","import { Node } from \"@tiptap/core\";\nimport { childNodes } from \"../../util/prosemirror\";\nimport HTMLNode from './html';\n\nconst Table = Node.create({\n name: 'table',\n});\n\nexport default Table.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize(state, node, parent) {\n if(!isMarkdownSerializable(node)) {\n HTMLNode.storage.markdown.serialize.call(this, state, node, parent);\n return;\n }\n state.inTable = true;\n node.forEach((row, p, i) => {\n state.write('| ');\n row.forEach((col, p, j) => {\n if(j) {\n state.write(' | ');\n }\n const cellContent = col.firstChild;\n if(cellContent.textContent.trim()) {\n state.renderInline(cellContent);\n }\n });\n state.write(' |')\n state.ensureNewLine();\n if(!i) {\n const delimiterRow = Array.from({length: row.childCount}).map(() => '---').join(' | ');\n state.write(`| ${delimiterRow} |`);\n state.ensureNewLine();\n }\n });\n state.closeBlock(node);\n state.inTable = false;\n },\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n})\n\n\nfunction hasSpan(node) {\n return node.attrs.colspan > 1 || node.attrs.rowspan > 1;\n}\n\nfunction isMarkdownSerializable(node) {\n const rows = childNodes(node);\n const firstRow = rows[0];\n const bodyRows = rows.slice(1);\n\n if(childNodes(firstRow).some(cell => cell.type.name !== 'tableHeader' || hasSpan(cell) || cell.childCount > 1)) {\n return false;\n }\n\n if(bodyRows.some(row =>\n childNodes(row).some(cell => cell.type.name === 'tableHeader' || hasSpan(cell) || cell.childCount > 1)\n )) {\n return false;\n }\n\n return true;\n}\n","import { Node } from \"@tiptap/core\";\n\n\nconst TaskItem = Node.create({\n name: 'taskItem',\n});\n\nexport default TaskItem.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize(state, node) {\n const check = node.attrs.checked ? '[x]' : '[ ]';\n state.write(`${check} `);\n state.renderContent(node);\n },\n parse: {\n updateDOM(element) {\n [...element.querySelectorAll('.task-list-item')]\n .forEach(item => {\n const input = item.querySelector('input');\n item.setAttribute('data-type', 'taskItem');\n if(input) {\n item.setAttribute('data-checked', input.checked);\n input.remove();\n }\n });\n },\n }\n }\n }\n }\n});\n","import taskListPlugin from \"markdown-it-task-lists\";\nimport { Node } from \"@tiptap/core\";\nimport BulletList from \"./bullet-list\";\n\n\nconst TaskList = Node.create({\n name: 'taskList',\n});\n\nexport default TaskList.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: BulletList.storage.markdown.serialize,\n parse: {\n setup(markdownit) {\n markdownit.use(taskListPlugin);\n },\n updateDOM(element) {\n [...element.querySelectorAll('.contains-task-list')]\n .forEach(list => {\n list.setAttribute('data-type', 'taskList');\n });\n },\n }\n }\n }\n }\n});\n","import { Node } from \"@tiptap/core\";\nimport { escapeHTML } from \"../../util/dom\";\n\n\nconst Text = Node.create({\n name: 'text',\n});\n\nexport default Text.extend({\n /**\n * @return {{markdown: MarkdownNodeSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize(state, node) {\n state.text(escapeHTML(node.text));\n },\n parse: {\n // handled by markdown-it\n },\n }\n }\n }\n});\n","import { Mark } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Bold = Mark.create({\n name: 'bold',\n});\n\nexport default Bold.extend({\n /**\n * @return {{markdown: MarkdownMarkSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.marks.strong,\n parse: {\n // handled by markdown-it\n }\n },\n }\n }\n});\n","import { Mark } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Code = Mark.create({\n name: 'code',\n});\n\nexport default Code.extend({\n /**\n * @return {{markdown: MarkdownMarkSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.marks.code,\n parse: {\n // handled by markdown-it\n }\n }\n }\n }\n})\n","import { Mark } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Italic = Mark.create({\n name: 'italic',\n});\n\nexport default Italic.extend({\n /**\n * @return {{markdown: MarkdownMarkSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.marks.em,\n parse: {\n // handled by markdown-it\n }\n }\n }\n }\n})\n","import { Mark } from \"@tiptap/core\";\nimport { defaultMarkdownSerializer } from \"prosemirror-markdown\";\n\n\nconst Link = Mark.create({\n name: 'link',\n});\n\nexport default Link.extend({\n /**\n * @return {{markdown: MarkdownMarkSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: defaultMarkdownSerializer.marks.link,\n parse: {\n // handled by markdown-it\n }\n }\n }\n }\n})\n","import { Mark } from \"@tiptap/core\";\n\n\nconst Strike = Mark.create({\n name: 'strike',\n});\n\nexport default Strike.extend({\n /**\n * @return {{markdown: MarkdownMarkSpec}}\n */\n addStorage() {\n return {\n markdown: {\n serialize: {open: '~~', close: '~~', expelEnclosingWhitespace: true},\n parse: {\n // handled by markdown-it\n },\n },\n }\n }\n});\n","import Blockquote from \"./nodes/blockquote\";\nimport BulletList from \"./nodes/bullet-list\";\nimport CodeBlock from \"./nodes/code-block\";\nimport HardBreak from \"./nodes/hard-break\";\nimport Heading from \"./nodes/heading\";\nimport HorizontalRule from \"./nodes/horizontal-rule\";\nimport HTMLNode from \"./nodes/html\";\nimport Image from \"./nodes/image\";\nimport ListItem from \"./nodes/list-item\";\nimport OrderedList from \"./nodes/ordered-list\";\nimport Paragraph from \"./nodes/paragraph\";\nimport Table from \"./nodes/table\";\nimport TaskItem from \"./nodes/task-item\";\nimport TaskList from \"./nodes/task-list\";\nimport Text from \"./nodes/text\";\n\nimport Bold from \"./marks/bold\";\nimport Code from \"./marks/code\";\nimport HTMLMark from \"./marks/html\";\nimport Italic from \"./marks/italic\";\nimport Link from \"./marks/link\";\nimport Strike from \"./marks/strike\";\n\n\nexport default [\n Blockquote,\n BulletList,\n CodeBlock,\n HardBreak,\n Heading,\n HorizontalRule,\n HTMLNode,\n Image,\n ListItem,\n OrderedList,\n Paragraph,\n Table,\n TaskItem,\n TaskList,\n Text,\n\n Bold,\n Code,\n HTMLMark,\n Italic,\n Link,\n Strike,\n]\n","import markdownExtensions from \"../extensions\";\n\n\nexport function getMarkdownSpec(extension) {\n const markdownSpec = extension.storage?.markdown;\n const defaultMarkdownSpec = markdownExtensions.find(e => e.name === extension.name)?.storage.markdown;\n\n if(markdownSpec || defaultMarkdownSpec) {\n return {\n ...defaultMarkdownSpec,\n ...markdownSpec,\n };\n }\n\n return null;\n}\n","import { MarkdownSerializerState } from './state';\nimport HTMLMark from \"../extensions/marks/html\";\nimport HTMLNode from \"../extensions/nodes/html\";\nimport { getMarkdownSpec } from \"../util/extensions\";\nimport HardBreak from \"../extensions/nodes/hard-break\";\n\n\nexport class MarkdownSerializer {\n /**\n * @type {import('@tiptap/core').Editor}\n */\n editor = null;\n\n constructor(editor) {\n this.editor = editor;\n }\n\n serialize(content) {\n const state = new MarkdownSerializerState(this.nodes, this.marks, {\n hardBreakNodeName: HardBreak.name,\n });\n\n state.renderContent(content);\n\n return state.out;\n }\n\n get nodes() {\n return {\n ...Object.fromEntries(\n Object.keys(this.editor.schema.nodes)\n .map(name => [name, this.serializeNode(HTMLNode)])\n ),\n ...Object.fromEntries(\n this.editor.extensionManager.extensions\n .filter(extension => extension.type === 'node' && this.serializeNode(extension))\n .map(extension => [extension.name, this.serializeNode(extension)])\n ?? []\n ),\n };\n }\n\n get marks() {\n return {\n ...Object.fromEntries(\n Object.keys(this.editor.schema.marks)\n .map(name => [name, this.serializeMark(HTMLMark)])\n ),\n ...Object.fromEntries(\n this.editor.extensionManager.extensions\n .filter(extension => extension.type === 'mark' && this.serializeMark(extension))\n .map(extension => [extension.name, this.serializeMark(extension)])\n ?? []\n ),\n };\n }\n\n serializeNode(node) {\n return getMarkdownSpec(node)?.serialize?.bind({ editor: this.editor, options: node.options });\n }\n\n serializeMark(mark) {\n const serialize = getMarkdownSpec(mark)?.serialize;\n return serialize\n ? {\n ...serialize,\n open: typeof serialize.open === 'function' ? serialize.open.bind({ editor: this.editor, options: mark.options }) : serialize.open,\n close: typeof serialize.close === 'function' ? serialize.close.bind({ editor: this.editor, options: mark.options }) : serialize.close,\n }\n : null\n }\n}\n\n","import markdownit from \"markdown-it\";\nimport { elementFromString, extractElement, unwrapElement } from \"../util/dom\";\nimport { getMarkdownSpec } from \"../util/extensions\";\n\nexport class MarkdownParser {\n /**\n * @type {import('@tiptap/core').Editor}\n */\n editor = null;\n /**\n * @type {markdownit}\n */\n md = null;\n\n constructor(editor, { html, linkify, breaks }) {\n this.editor = editor;\n this.md = this.withPatchedRenderer(markdownit({\n html,\n linkify,\n breaks,\n }));\n }\n\n parse(content, { inline } = {}) {\n if(typeof content === 'string') {\n this.editor.extensionManager.extensions.forEach(extension =>\n getMarkdownSpec(extension)?.parse?.setup?.call({ editor:this.editor, options:extension.options }, this.md)\n );\n\n const renderedHTML = this.md.render(content);\n const element = elementFromString(renderedHTML);\n\n this.editor.extensionManager.extensions.forEach(extension =>\n getMarkdownSpec(extension)?.parse?.updateDOM?.call({ editor:this.editor, options:extension.options }, element)\n );\n\n this.normalizeDOM(element, { inline, content });\n\n return element.innerHTML;\n }\n\n return content;\n }\n\n normalizeDOM(node, { inline, content }) {\n this.normalizeBlocks(node);\n\n // remove all \\n appended by markdown-it\n node.querySelectorAll('*').forEach(el => {\n if(el.nextSibling?.nodeType === Node.TEXT_NODE && !el.closest('pre')) {\n el.nextSibling.textContent = el.nextSibling.textContent.replace(/^\\n/, '');\n }\n });\n\n if(inline) {\n this.normalizeInline(node, content);\n }\n\n return node;\n }\n\n normalizeBlocks(node) {\n const blocks = Object.values(this.editor.schema.nodes)\n .filter(node => node.isBlock);\n\n const selector = blocks\n .map(block => block.spec.parseDOM?.map(spec => spec.tag))\n .flat()\n .filter(Boolean)\n .join(',');\n\n if(!selector) {\n return;\n }\n\n [...node.querySelectorAll(selector)].forEach(el => {\n if(el.parentElement.matches('p')) {\n extractElement(el);\n }\n });\n }\n\n normalizeInline(node, content) {\n if(node.firstElementChild?.matches('p')) {\n const firstParagraph = node.firstElementChild;\n const { nextElementSibling } = firstParagraph;\n const startSpaces = content.match(/^\\s+/)?.[0] ?? '';\n const endSpaces = !nextElementSibling\n ? content.match(/\\s+$/)?.[0] ?? ''\n : '';\n\n if(content.match(/^\\n\\n/)) {\n firstParagraph.innerHTML = `${firstParagraph.innerHTML}${endSpaces}`;\n return;\n }\n\n unwrapElement(firstParagraph);\n\n node.innerHTML = `${startSpaces}${node.innerHTML}${endSpaces}`;\n }\n }\n\n /**\n * @param {markdownit} md\n */\n withPatchedRenderer(md) {\n const withoutNewLine = (renderer) => (...args) => {\n const rendered = renderer(...args);\n if(rendered === '\\n') {\n return rendered; // keep soft breaks\n }\n if(rendered[rendered.length - 1] === '\\n') {\n return rendered.slice(0, -1);\n }\n return rendered;\n }\n\n md.renderer.rules.hardbreak = withoutNewLine(md.renderer.rules.hardbreak);\n md.renderer.rules.softbreak = withoutNewLine(md.renderer.rules.softbreak);\n md.renderer.rules.fence = withoutNewLine(md.renderer.rules.fence);\n md.renderer.rules.code_block = withoutNewLine(md.renderer.rules.code_block);\n md.renderer.renderToken = withoutNewLine(md.renderer.renderToken.bind(md.renderer));\n\n return md;\n }\n}\n\n","import { Extension } from \"@tiptap/core\";\nimport { Plugin, PluginKey } from '@tiptap/pm/state';\nimport { DOMParser } from '@tiptap/pm/model';\nimport { elementFromString } from \"../../util/dom\";\n\nexport const MarkdownClipboard = Extension.create({\n name: 'markdownClipboard',\n addOptions() {\n return {\n transformPastedText: false,\n transformCopiedText: false,\n }\n },\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: new PluginKey('markdownClipboard'),\n props: {\n clipboardTextParser: (text, context, plainText) => {\n if(plainText || !this.options.transformPastedText) {\n return null; // pasting with shift key prevents formatting\n }\n const parsed = this.editor.storage.markdown.parser.parse(text, { inline: true });\n return DOMParser.fromSchema(this.editor.schema)\n .parseSlice(elementFromString(parsed), {\n preserveWhitespace: true,\n context,\n });\n },\n /**\n * @param {import('prosemirror-model').Slice} slice\n */\n clipboardTextSerializer: (slice) => {\n if(!this.options.transformCopiedText) {\n return null;\n }\n return this.editor.storage.markdown.serializer.serialize(slice.content);\n },\n },\n })\n ]\n }\n})\n","import { Extension, extensions } from '@tiptap/core';\nimport { MarkdownTightLists } from \"./extensions/tiptap/tight-lists\";\nimport { MarkdownSerializer } from \"./serialize/MarkdownSerializer\";\nimport { MarkdownParser } from \"./parse/MarkdownParser\";\nimport { MarkdownClipboard } from \"./extensions/tiptap/clipboard\";\n\nexport const Markdown = Extension.create({\n name: 'markdown',\n priority: 50,\n addOptions() {\n return {\n html: true,\n tightLists: true,\n tightListClass: 'tight',\n bulletListMarker: '-',\n linkify: false,\n breaks: false,\n transformPastedText: false,\n transformCopiedText: false,\n }\n },\n addCommands() {\n const commands = extensions.Commands.config.addCommands();\n return {\n setContent: (content, emitUpdate, parseOptions) => (props) => {\n return commands.setContent(\n props.editor.storage.markdown.parser.parse(content),\n emitUpdate,\n parseOptions\n )(props);\n },\n insertContentAt: (range, content, options) => (props) => {\n return commands.insertContentAt(\n range,\n props.editor.storage.markdown.parser.parse(content, { inline: true }),\n options\n )(props);\n },\n }\n },\n onBeforeCreate() {\n this.editor.storage.markdown = {\n options: { ...this.options },\n parser: new MarkdownParser(this.editor, this.options),\n serializer: new MarkdownSerializer(this.editor),\n getMarkdown: () => {\n return this.editor.storage.markdown.serializer.serialize(this.editor.state.doc);\n },\n }\n this.editor.options.initialContent = this.editor.options.content;\n this.editor.options.content = this.editor.storage.markdown.parser.parse(this.editor.options.content);\n },\n onCreate() {\n this.editor.options.content = this.editor.options.initialContent;\n delete this.editor.options.initialContent;\n },\n addStorage() {\n return {\n /// storage will be defined in onBeforeCreate() to prevent initial object overriding\n }\n },\n addExtensions() {\n return [\n MarkdownTightLists.configure({\n tight: this.options.tightLists,\n tightClass: this.options.tightListClass,\n }),\n MarkdownClipboard.configure({\n transformPastedText: this.options.transformPastedText,\n transformCopiedText: this.options.transformCopiedText,\n }),\n ]\n },\n});\n","import {\n Markdown as TipTapMarkdown,\n type MarkdownOptions as TipTapMarkdownOptions,\n} from \"tiptap-markdown\";\n\nconst resolveExt = (mod: any, name: string) =>\n mod?.[name] ||\n mod?.default?.[name] ||\n mod?.default?.default ||\n mod?.default ||\n mod;\n\n/**\n * Built-in native Markdown extension for @pixerate/editor based on tiptap-markdown.\n * Enables automatic markdown parsing, serialization, and clipboard handling.\n */\nexport const Markdown = resolveExt(TipTapMarkdown, \"Markdown\");\n\nexport type { TipTapMarkdownOptions as MarkdownOptions };\n","import * as _Image from \"@tiptap/extension-image\";\nimport type { ImageOptions as TipTapImageOptions } from \"@tiptap/extension-image\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\n\nconst resolveExt = (mod: any, name: string) =>\n mod?.[name] ||\n mod?.default?.[name] ||\n mod?.default?.default ||\n mod?.default ||\n mod;\n\nconst BaseImage = resolveExt(_Image, \"Image\");\n\nexport interface ImageOptions extends Partial<TipTapImageOptions> {\n /**\n * Custom upload handler called when an image is pasted or dropped.\n * Resolves to the uploaded image URL string.\n */\n upload?: (file: File) => Promise<string> | string;\n\n /**\n * Callback invoked if the upload handler throws or rejects, or if an image\n * exceeds maxBase64Size when no upload handler is configured.\n */\n onUploadError?: (error: Error, file: File) => void;\n\n /**\n * Maximum allowed file size (in bytes) when embedding images as base64 data URLs\n * without an upload handler. Defaults to 65536 (64 KB).\n * Files larger than this will be rejected to avoid memory bloat and prompt/stream saturation.\n */\n maxBase64Size?: number;\n\n /**\n * Whether to enable automatic image pasting from clipboard. Defaults to true.\n */\n enablePaste?: boolean;\n\n /**\n * Whether to enable automatic image drop. Defaults to true.\n */\n enableDrop?: boolean;\n}\n\nexport const imagePastePluginKey = new PluginKey(\"imagePasteHandler\");\n\n/**\n * Inserts an image node into the editor view at the current selection.\n */\nexport function insertImageNode(view: any, src: string, alt?: string) {\n const { schema } = view.state;\n const imageType = schema.nodes.image;\n if (!imageType) return;\n const node = imageType.create({ src, alt: alt || \"\" });\n const tr = view.state.tr.replaceSelectionWith(node);\n view.dispatch(tr);\n}\n\n/**\n * Updates an existing image node's src attribute across document positions.\n */\nexport function updateImageSrc(view: any, oldSrc: string, newSrc: string) {\n const { doc } = view.state;\n let foundPos: number | null = null;\n let foundAttrs: any = null;\n\n doc.descendants((node: any, pos: number) => {\n if (node.type.name === \"image\" && node.attrs.src === oldSrc) {\n foundPos = pos;\n foundAttrs = node.attrs;\n return false;\n }\n });\n\n if (foundPos !== null && foundAttrs) {\n const tr = view.state.tr.setNodeMarkup(foundPos, undefined, {\n ...foundAttrs,\n src: newSrc,\n });\n view.dispatch(tr);\n }\n}\n\n/**\n * Removes an existing image node matching src attribute across document positions.\n */\nexport function removeImageNode(view: any, src: string) {\n const { doc } = view.state;\n let foundPos: number | null = null;\n let nodeSize = 0;\n\n doc.descendants((node: any, pos: number) => {\n if (node.type.name === \"image\" && node.attrs.src === src) {\n foundPos = pos;\n nodeSize = node.nodeSize;\n return false;\n }\n });\n\n if (foundPos !== null) {\n const tr = view.state.tr.delete(foundPos, foundPos + nodeSize);\n view.dispatch(tr);\n }\n}\n\n/**\n * Handles inserting a pasted or dropped image file, supporting both async upload\n * handlers and direct base64/object-URL fallbacks.\n */\nexport function handleImageInsertion(\n view: any,\n file: File,\n options: ImageOptions,\n) {\n if (typeof options.upload === \"function\") {\n // Generate temporary preview URL if browser supports object URLs\n const hasObjectUrl =\n typeof URL !== \"undefined\" && typeof URL.createObjectURL === \"function\";\n const tempUrl = hasObjectUrl ? URL.createObjectURL(file) : null;\n\n if (tempUrl) {\n insertImageNode(view, tempUrl, file.name);\n }\n\n Promise.resolve(options.upload(file))\n .then((uploadedUrl) => {\n if (!uploadedUrl) {\n throw new Error(\"Upload handler returned empty URL\");\n }\n if (tempUrl) {\n updateImageSrc(view, tempUrl, uploadedUrl);\n if (typeof URL.revokeObjectURL === \"function\") {\n URL.revokeObjectURL(tempUrl);\n }\n } else {\n insertImageNode(view, uploadedUrl, file.name);\n }\n })\n .catch((err) => {\n const error = err instanceof Error ? err : new Error(String(err));\n console.error(\"Failed to upload pasted image:\", error);\n if (tempUrl) {\n removeImageNode(view, tempUrl);\n if (typeof URL.revokeObjectURL === \"function\") {\n URL.revokeObjectURL(tempUrl);\n }\n }\n if (typeof options.onUploadError === \"function\") {\n options.onUploadError(error, file);\n }\n });\n } else if (options.allowBase64 !== false) {\n const maxBase64Size = options.maxBase64Size ?? 65536; // 64KB default\n if (file.size > maxBase64Size) {\n const err = new Error(\n `Image size (${Math.round(file.size / 1024)}KB) exceeds maxBase64Size (${Math.round(\n maxBase64Size / 1024,\n )}KB). Provide an upload handler to support large images.`,\n );\n console.warn(`[Editor] ${err.message}`);\n if (typeof options.onUploadError === \"function\") {\n options.onUploadError(err, file);\n }\n return;\n }\n\n if (typeof FileReader !== \"undefined\") {\n const reader = new FileReader();\n reader.onload = () => {\n const src = reader.result as string;\n if (src) {\n insertImageNode(view, src, file.name);\n }\n };\n reader.readAsDataURL(file);\n }\n }\n}\n\nexport const Image = BaseImage.extend({\n addOptions() {\n return {\n ...this.parent?.(),\n allowBase64: true,\n maxBase64Size: 65536,\n enablePaste: true,\n enableDrop: true,\n upload: undefined,\n onUploadError: undefined,\n HTMLAttributes: {\n class: \"rounded-md max-w-full h-auto my-2\",\n },\n };\n },\n\n addProseMirrorPlugins() {\n const parentPlugins = this.parent?.() || [];\n const options = this.options as ImageOptions;\n\n if (!options.enablePaste && !options.enableDrop) {\n return parentPlugins;\n }\n\n const pastePlugin = new Plugin({\n key: imagePastePluginKey,\n props: {\n handlePaste(view, event) {\n if (!options.enablePaste) return false;\n const items = Array.from(event.clipboardData?.items || []);\n const imageItems = items.filter(\n (item) => item.kind === \"file\" && item.type.startsWith(\"image/\"),\n );\n if (imageItems.length === 0) return false;\n\n event.preventDefault();\n\n for (const item of imageItems) {\n const file = item.getAsFile();\n if (!file) continue;\n handleImageInsertion(view, file, options);\n }\n return true;\n },\n handleDrop(view, event) {\n if (!options.enableDrop) return false;\n const files = Array.from(event.dataTransfer?.files || []);\n const imageFiles = files.filter((f) => f.type.startsWith(\"image/\"));\n if (imageFiles.length === 0) return false;\n\n event.preventDefault();\n\n for (const file of imageFiles) {\n handleImageInsertion(view, file, options);\n }\n return true;\n },\n },\n });\n\n return [...parentPlugins, pastePlugin];\n },\n});\n","import { escapeHtml } from \"./plain-text\";\nimport type { MentionEntity } from \"../extensions/mention\";\n\n/**\n * Canonical regex pattern for matching @mentions in plain text or markdown.\n * Supports:\n * - Standard unquoted handles: @username, @user.name, @team_alpha, @sa-1\n * - Quoted handles: @\"John Doe\", "Jane Doe"\n * Unquoted handles exclude trailing punctuation (e.g. @violet. matches \"violet\" without the dot).\n */\nexport const MENTION_REGEX =\n /(?:^|[\\s>(*_\"';\\\\/[\\]{}~`:]|"|>|<|&)@(?:\"([^\"]+)\"|"([^&]+)"|([a-zA-Z0-9_-]+(?:\\.[a-zA-Z0-9_-]+)*))/g;\n\n/**\n * Split regex identifying markdown code blocks, inline code, URLs, and existing HTML tags.\n * Used by preprocessMarkdownMentions to ensure non-mention regions remain completely untouched.\n */\nexport const MARKDOWN_MENTION_SPLIT_REGEX =\n /(```[\\s\\S]*?```|~~~[\\s\\S]*?~~~|<pre[\\s\\S]*?<\\/pre>|<code[\\s\\S]*?<\\/code>|`[^`\\n]+`|<span\\b[^>]*\\b(?:data-type=[\"']mention[\"']|class=[\"'][^\"']*pixerate-mention-node[^\"']*[\"']|data-mention=[\"'][^\"']*[\"'])[^>]*>[\\s\\S]*?<\\/span>|<[^>]+>|\\]\\([^)]+\\)|(?:https?|file|vscode|cursor|mailto):\\/\\/[^\\s<)]+)/gi;\n\nexport interface MentionSegment {\n type: \"text\" | \"mention\";\n value: string;\n handle?: string;\n}\n\nexport interface PreprocessMarkdownMentionsOptions {\n /**\n * Known pool of mentionable entities (users, agents, teams, etc.).\n */\n mentionables?: MentionEntity[];\n /**\n * Default entity type assigned when a handle does not match any entry in mentionables.\n * Defaults to 'user'.\n */\n defaultType?: string;\n /**\n * Custom resolver callback to derive entity metadata for unmatched handles.\n */\n resolveMention?: (handle: string) => Partial<MentionEntity> | null | undefined;\n}\n\n/**\n * Strips code blocks and inline code from markdown or HTML content:\n * - Fenced code blocks: ```...``` and ~~~...~~~\n * - Inline backtick code: `...`\n * - HTML code/pre tags: <pre>...</pre>, <code>...</code>\n * Used to avoid false-positive mention parsing and keyword analysis within code snippets, terminal logs, or stack traces.\n */\nexport function stripMarkdownCode(content: string): string {\n if (!content || typeof content !== \"string\") return \"\";\n return content\n .replace(/```[\\s\\S]*?```/g, \"\")\n .replace(/~~~[\\s\\S]*?~~~/g, \"\")\n .replace(/<pre[\\s\\S]*?<\\/pre>/gi, \"\")\n .replace(/<code[\\s\\S]*?<\\/code>/gi, \"\")\n .replace(/`[^`\\n]*`/g, \"\");\n}\n\n/**\n * Extracts unique mention handles from a text, markdown, or HTML string,\n * ignoring trailing punctuation, code blocks, URLs, and pre-existing HTML mention attributes.\n */\nexport function extractMentions(content: string): string[] {\n if (!content || typeof content !== \"string\") return [];\n\n // Normalize existing HTML mention nodes (e.g. from TipTap or rich text serializers)\n // so data-mention-suggestion-char=\"@\" does not trigger spurious quoted matches against attributes,\n // and ensure the actual mentioned label or ID is preserved cleanly.\n const normalizedMentionNodes = content.replace(\n /<span\\b[^>]*\\b(?:data-type=[\"']mention[\"']|class=[\"'][^\"']*pixerate-mention-node[^\"']*[\"'])[^>]*>([\\s\\S]*?)<\\/span>/gi,\n (match, inner) => {\n const labelMatch = match.match(/\\bdata-label=[\"']([^\"']+)[\"']/i);\n if (labelMatch) return ` @${labelMatch[1]} `;\n const idMatch = match.match(/\\bdata-id=[\"']([^\"']+)[\"']/i);\n if (idMatch) return ` @${idMatch[1]} `;\n return ` ${inner} `;\n }\n );\n\n const cleanContent = stripMarkdownCode(normalizedMentionNodes);\n // Strip URLs and markdown link destinations so @package or @handles in URLs are not extracted as mentions\n const withoutUrls = cleanContent\n .replace(/(?:https?|ftp|file|vscode|cursor|mailto):\\/\\/[^\\s<>()]+/gi, \"\")\n .replace(/\\]\\([^)]*\\)/g, \"]\");\n // Strip remaining HTML tags so attributes containing '@' or '>' aren't treated as mention triggers\n const textOnly = withoutUrls.replace(/<[^>]+>/g, \" \");\n\n const mentions: string[] = [];\n const seen = new Set<string>();\n\n const regex = new RegExp(MENTION_REGEX.source, \"g\");\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(textOnly)) !== null) {\n const handle = (match[1] ?? match[2] ?? match[3] ?? \"\").trim();\n if (handle && !seen.has(handle)) {\n seen.add(handle);\n mentions.push(handle);\n }\n }\n\n return mentions;\n}\n\n/**\n * Segments a text string into plain text parts and mention tokens.\n * Correctly leaves trailing punctuation (like \".\") as part of the following text segment.\n */\nexport function parseMentionSegments(content: string): MentionSegment[] {\n if (!content) return [];\n\n const segments: MentionSegment[] = [];\n const regex = new RegExp(MENTION_REGEX.source, \"g\");\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n const fullMatch = match[0];\n const atIndex = fullMatch.indexOf(\"@\");\n const prefix = atIndex > 0 ? fullMatch.slice(0, atIndex) : \"\";\n const mentionToken = fullMatch.slice(atIndex);\n const handle = match[1] ?? match[2] ?? match[3];\n const matchStart = match.index + prefix.length;\n\n if (matchStart > lastIndex) {\n segments.push({\n type: \"text\",\n value: content.slice(lastIndex, matchStart),\n });\n }\n\n segments.push({\n type: \"mention\",\n value: mentionToken,\n handle,\n });\n\n lastIndex = matchStart + mentionToken.length;\n }\n\n if (lastIndex < content.length) {\n segments.push({\n type: \"text\",\n value: content.slice(lastIndex),\n });\n }\n\n return segments;\n}\n\n/**\n * Preprocesses markdown text by turning raw @mention handles into TipTap-compatible\n * mention HTML spans (<span class=\"pixerate-mention-node\" data-type=\"mention\" ...>),\n * ensuring code blocks, inline code, existing mention nodes, and URLs remain immune.\n */\nexport function preprocessMarkdownMentions(\n content: string,\n optionsOrMentionables: MentionEntity[] | PreprocessMarkdownMentionsOptions = []\n): string {\n if (!content || typeof content !== \"string\") return \"\";\n\n const options: PreprocessMarkdownMentionsOptions = Array.isArray(optionsOrMentionables)\n ? { mentionables: optionsOrMentionables }\n : optionsOrMentionables;\n\n const allMentionables = options.mentionables || [];\n const defaultType = options.defaultType || \"user\";\n const resolveMention = options.resolveMention;\n\n const parts = content.split(MARKDOWN_MENTION_SPLIT_REGEX);\n\n return parts\n .map((part) => {\n if (!part) return \"\";\n\n // Preserve code fences, code tags, inline backticks, existing mention spans,\n // HTML tags, markdown link targets, and raw URLs untouched.\n if (\n part.startsWith(\"```\") ||\n part.startsWith(\"~~~\") ||\n part.startsWith(\"`\") ||\n part.startsWith(\"](\") ||\n /^(?:https?|file|vscode|cursor|mailto):\\/\\//i.test(part) ||\n /^<pre[\\s>]/i.test(part) ||\n /^<code[\\s>]/i.test(part) ||\n /^<[^>]+>$/i.test(part) ||\n /^<span\\b[^>]*\\b(?:data-type=[\"']mention[\"']|class=[\"'][^\"']*pixerate-mention-node[^\"']*[\"']|data-mention=[\"'][^\"']*[\"'])/i.test(\n part\n )\n ) {\n return part;\n }\n\n const regex = new RegExp(MENTION_REGEX.source, \"g\");\n return part.replace(regex, (match, quotedHandle, escapedQuotedHandle, standardHandle) => {\n const atIndex = match.indexOf(\"@\");\n const prefix = atIndex > 0 ? match.slice(0, atIndex) : \"\";\n const rawHandle = (quotedHandle || escapedQuotedHandle || standardHandle || \"\").trim();\n if (!rawHandle) return match;\n\n const lowerHandle = rawHandle.toLowerCase();\n const entity = allMentionables.find((e) => {\n if (e.label?.toLowerCase() === lowerHandle) return true;\n if (e.handle?.toLowerCase() === lowerHandle) return true;\n if (e.name?.toLowerCase() === lowerHandle) return true;\n if (e.id?.toLowerCase() === lowerHandle) return true;\n if (e.type === \"agent\" && `agent${(e.handle || e.label || \"\").toLowerCase()}` === lowerHandle) return true;\n if (\n e.aliases?.some(\n (a: string) =>\n a.toLowerCase() === lowerHandle ||\n (e.type === \"agent\" && `agent${a.toLowerCase()}` === lowerHandle)\n )\n ) {\n return true;\n }\n return false;\n });\n\n let id = entity?.id;\n let label = entity?.label || entity?.handle || rawHandle;\n let type = entity?.type;\n let avatarUrl = entity?.avatarUrl;\n let color = entity?.color || entity?.hexColor;\n\n if (!entity) {\n const customResolved = resolveMention?.(rawHandle);\n if (customResolved) {\n id = customResolved.id ?? id;\n label = customResolved.label ?? customResolved.handle ?? label;\n type = customResolved.type ?? type;\n avatarUrl = customResolved.avatarUrl ?? avatarUrl;\n color = customResolved.color ?? customResolved.hexColor ?? color;\n } else {\n const stripped = lowerHandle.replace(/^agent[\\s\\-_]*/i, \"\");\n if (\n [\"supervisor\", \"coordinator\", \"planner\", \"validator\", \"executor\"].includes(stripped)\n ) {\n type = \"agent\";\n id = stripped;\n label = stripped;\n } else if (lowerHandle === \"agents\") {\n type = \"team\";\n id = \"agents\";\n label = \"agents\";\n } else {\n type = defaultType;\n id = rawHandle;\n label = rawHandle;\n }\n }\n }\n\n const avatarAttr = avatarUrl ? ` data-avatar-url=\"${escapeHtml(avatarUrl)}\"` : \"\";\n const colorAttr = color ? ` data-color=\"${escapeHtml(color)}\"` : \"\";\n\n return `${prefix}<span class=\"pixerate-mention-node\" data-type=\"mention\" data-id=\"${escapeHtml(\n id || label\n )}\" data-label=\"${escapeHtml(label)}\" data-mention-suggestion-char=\"@\" data-type-name=\"${escapeHtml(\n type || defaultType\n )}\"${avatarAttr}${colorAttr}>@${escapeHtml(label)}</span>`;\n });\n })\n .join(\"\");\n}\n","/**\n * Escapes characters that have syntactic meaning in HTML text.\n */\nexport function escapeHtml(text: string): string {\n if (!text) return \"\";\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\n/**\n * Matches strings that are already TipTap paragraph HTML (start with `<p>` and\n * end with `</p>`), as opposed to plain text that merely mentions a `<p>` tag.\n */\nconst PARAGRAPH_HTML_REGEX = /^\\s*<p[\\s>][\\s\\S]*<\\/p>\\s*$/i;\n\n/**\n * Converts a plain-text string with newlines into HTML paragraphs suitable\n * for TipTap initial content or setContent, preserving line breaks.\n * Input that is already paragraph HTML (`<p>…</p>`) is passed through as-is.\n */\nexport function plainTextToTipTapHtml(text: string): string {\n if (!text) return \"<p></p>\";\n if (PARAGRAPH_HTML_REGEX.test(text)) {\n return text;\n }\n return text\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\r/g, \"\\n\")\n .split(\"\\n\")\n .map((line) => `<p>${escapeHtml(line)}</p>`)\n .join(\"\");\n}\n\n/**\n * Block-level elements that start a new line in plain-text output.\n */\nconst BLOCK_TAGS = new Set([\n \"P\", \"DIV\", \"LI\", \"UL\", \"OL\", \"PRE\", \"BLOCKQUOTE\", \"TABLE\", \"TR\",\n \"H1\", \"H2\", \"H3\", \"H4\", \"H5\", \"H6\", \"HR\",\n]);\n\n/**\n * Matches a TipTap mention span (including its content). The lookahead keeps\n * a single `[^>]*` scan per tag, avoiding catastrophic backtracking on\n * malformed input.\n */\nconst MENTION_SPAN_REGEX =\n /<span\\b(?=[^>]*\\bdata-type=[\"']mention[\"'])([^>]*)>[\\s\\S]*?<\\/span>/gi;\n\nfunction getHtmlAttribute(attrs: string, name: string): string | undefined {\n const match = new RegExp(`\\\\b${name}=(?:\"([^\"]*)\"|'([^']*)')`, \"i\").exec(\n attrs,\n );\n return match ? (match[1] ?? match[2]) : undefined;\n}\n\n/**\n * Parses HTML into an inert fragment. Content of a `<template>` element is not\n * rendered, so `<img onerror>` and similar handlers never run.\n */\nfunction parseHtmlFragment(html: string): DocumentFragment {\n const template = document.createElement(\"template\");\n template.innerHTML = html;\n return template.content;\n}\n\nfunction decodeHtmlEntities(text: string): string {\n return text\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/�*39;/g, \"'\")\n .replace(/ /g, \"\\u00a0\")\n .replace(/&/g, \"&\");\n}\n\n/**\n * Extracts plain text from an HTML string or TipTap HTML, preserving newlines between block tags.\n */\nexport function htmlToPlainText(html: string): string {\n if (!html) return \"\";\n\n // Normalize mentions so data-label is preserved as @label even if textContent is empty\n const mentionNormalized = html.replace(MENTION_SPAN_REGEX, (match, attrs) => {\n const label =\n getHtmlAttribute(attrs, \"data-label\") || getHtmlAttribute(attrs, \"data-id\");\n return label ? `@${label}` : match;\n });\n\n if (typeof document !== \"undefined\") {\n const fragment = parseHtmlFragment(mentionNormalized);\n fragment\n .querySelectorAll(\"br.ProseMirror-trailingBreak\")\n .forEach((br) => br.remove());\n\n // Walk the tree, emitting one line per innermost block so nested blocks\n // (e.g. TipTap's <li><p>…</p></li>) are not repeated.\n const lines: string[] = [];\n let current: string | null = null;\n const flush = () => {\n if (current !== null) {\n lines.push(current);\n current = null;\n }\n };\n const visit = (node: Node) => {\n if (node.nodeType === 3) {\n const value = node.nodeValue ?? \"\";\n // Skip formatting whitespace between blocks.\n if (current === null && value.trim() === \"\") return;\n current = (current ?? \"\") + value;\n return;\n }\n if (node.nodeType !== 1) return;\n const tag = (node as Element).tagName.toUpperCase();\n if (tag === \"BR\") {\n current = (current ?? \"\") + \"\\n\";\n return;\n }\n if (!BLOCK_TAGS.has(tag)) {\n node.childNodes.forEach(visit);\n return;\n }\n flush();\n const linesBefore = lines.length;\n node.childNodes.forEach(visit);\n flush();\n // An empty block (e.g. <p></p>) is an empty line.\n if (lines.length === linesBefore && tag !== \"HR\") {\n lines.push(\"\");\n }\n };\n fragment.childNodes.forEach(visit);\n flush();\n return lines.join(\"\\n\");\n }\n\n // Node.js fallback regex\n const text = mentionNormalized\n .replace(/<br\\s*\\/?>/gi, \"\\n\")\n // A closing block, plus any closing wrappers right after it, ends one line.\n .replace(\n /<\\/(?:p|div|li|pre|blockquote|h[1-6])>(?:\\s*<\\/(?:li|ul|ol|blockquote|div)>)*/gi,\n \"\\n\",\n )\n .replace(/<[^>]+>/g, \"\");\n return decodeHtmlEntities(text).replace(/\\n$/, \"\");\n}\n\n/**\n * Extracts plain text from a TipTap editor instance, preserving newline separators\n * between block nodes and converting mention nodes to @label.\n */\nexport function getEditorText(editor: any): string {\n if (!editor) return \"\";\n const html = typeof editor.getHTML === \"function\" ? editor.getHTML() : \"\";\n if (html) {\n return htmlToPlainText(html);\n }\n if (typeof editor.getText === \"function\") {\n try {\n return editor.getText({ blockSeparator: \"\\n\" });\n } catch {\n return editor.getText();\n }\n }\n return \"\";\n}\n\nexport interface ExtractedMention {\n id: string;\n label: string;\n type?: string;\n avatarUrl?: string;\n color?: string;\n [key: string]: any;\n}\n\nimport { extractMentions } from \"./mentions\";\n\n/**\n * Traverses an editor instance, ProseMirror document, JSONContent, or HTML string\n * and extracts all mention attributes without needing regex.\n */\nexport function extractMentionsFromDoc(docOrEditor: any): ExtractedMention[] {\n if (!docOrEditor) return [];\n const mentions: ExtractedMention[] = [];\n\n // TipTap editor or ProseMirror Node with .descendants()\n const doc =\n docOrEditor?.state?.doc ||\n (typeof docOrEditor?.descendants === \"function\" ? docOrEditor : null);\n\n if (doc && typeof doc.descendants === \"function\") {\n doc.descendants((node: any) => {\n if (node.type?.name === \"mention\" && node.attrs) {\n mentions.push({\n id: node.attrs.id || \"\",\n label: node.attrs.label || \"\",\n type: node.attrs.type,\n avatarUrl: node.attrs.avatarUrl,\n color: node.attrs.color,\n ...node.attrs,\n });\n }\n });\n return mentions;\n }\n\n // JSONContent tree\n if (typeof docOrEditor === \"object\" && docOrEditor.content) {\n const walk = (nodes: any[]) => {\n for (const node of nodes) {\n if (node.type === \"mention\" && node.attrs) {\n mentions.push({\n id: node.attrs.id || \"\",\n label: node.attrs.label || \"\",\n type: node.attrs.type,\n avatarUrl: node.attrs.avatarUrl,\n color: node.attrs.color,\n ...node.attrs,\n });\n }\n if (Array.isArray(node.content)) {\n walk(node.content);\n }\n }\n };\n walk(docOrEditor.content);\n return mentions;\n }\n\n // HTML String\n if (typeof docOrEditor === \"string\") {\n if (typeof document !== \"undefined\") {\n parseHtmlFragment(docOrEditor).querySelectorAll('span[data-type=\"mention\"]').forEach((el) => {\n mentions.push({\n id: el.getAttribute(\"data-id\") || \"\",\n label: el.getAttribute(\"data-label\") || \"\",\n type: el.getAttribute(\"data-type-name\") || undefined,\n avatarUrl: el.getAttribute(\"data-avatar-url\") || undefined,\n color: el.getAttribute(\"data-color\") || undefined,\n });\n });\n } else {\n const spanRegex = /<span([^>]*data-type=[\"']mention[\"'][^>]*)>/gi;\n let match;\n while ((match = spanRegex.exec(docOrEditor)) !== null) {\n const attrStr = match[1];\n const getAttr = (name: string) => {\n const m = new RegExp(`${name}=[\"']([^\"']*)[\"']`, \"i\").exec(attrStr);\n return m ? m[1] : undefined;\n };\n mentions.push({\n id: getAttr(\"data-id\") || \"\",\n label: getAttr(\"data-label\") || \"\",\n type: getAttr(\"data-type-name\") || getAttr(\"data-entity-type\"),\n avatarUrl: getAttr(\"data-avatar-url\"),\n color: getAttr(\"data-color\"),\n });\n }\n }\n\n // Fallback: If no HTML mention tags were found, extract raw @mentions from text or markdown\n if (mentions.length === 0) {\n const rawHandles = extractMentions(docOrEditor);\n for (const handle of rawHandles) {\n mentions.push({\n id: handle,\n label: handle,\n type: \"user\",\n });\n }\n }\n }\n\n return mentions;\n}\n","import MarkdownIt from \"markdown-it\";\nimport taskLists from \"markdown-it-task-lists\";\nimport { escapeHtml, getEditorText } from \"./plain-text\";\n\nconst md = new MarkdownIt({\n html: true,\n linkify: true,\n breaks: true,\n}).use(taskLists);\n\nconst defaultValidateLink = md.validateLink;\nmd.validateLink = (url: string) => {\n if (\n url.startsWith(\"file://\") ||\n url.startsWith(\"vscode://\") ||\n url.startsWith(\"cursor://\")\n ) {\n return true;\n }\n return defaultValidateLink.call(md, url);\n};\n\n/**\n * Tags allowed through from raw HTML embedded in markdown (e.g. mention spans\n * and file links that tiptap-markdown serializes as HTML). Anything else is\n * rendered as escaped text. `input` is limited to checkboxes, which\n * markdown-it-task-lists emits as raw HTML.\n */\nconst ALLOWED_HTML_TAGS = new Set([\n \"a\", \"abbr\", \"b\", \"blockquote\", \"br\", \"code\", \"del\", \"details\", \"div\", \"em\",\n \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"hr\", \"i\", \"img\", \"input\", \"kbd\", \"li\", \"mark\",\n \"ol\", \"p\", \"pre\", \"s\", \"span\", \"strong\", \"sub\", \"summary\", \"sup\", \"table\",\n \"tbody\", \"td\", \"tfoot\", \"th\", \"thead\", \"tr\", \"u\", \"ul\",\n]);\n\nconst ALLOWED_HTML_ATTRS = new Set([\n \"alt\", \"align\", \"checked\", \"class\", \"colspan\", \"disabled\", \"height\", \"href\",\n \"rel\", \"rowspan\", \"src\", \"start\", \"target\", \"title\", \"type\", \"width\",\n]);\n\nconst HTML_TAG_REGEX =\n /<(\\/?)([a-zA-Z][a-zA-Z0-9-]*)((?:\\s+[^\\s\"'>\\/=]+(?:\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s\"'=<>`]+))?)*)\\s*\\/?>/g;\nconst HTML_ATTR_REGEX =\n /([^\\s\"'>\\/=]+)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s\"'=<>`]+)))?/g;\n\nfunction sanitizeTag(\n tagText: string,\n isClosing: string,\n rawTagName: string,\n rawAttrs: string,\n): string {\n const tagName = rawTagName.toLowerCase();\n if (!ALLOWED_HTML_TAGS.has(tagName)) return escapeHtml(tagText);\n if (isClosing) return `</${tagName}>`;\n if (tagName === \"input\" && !/\\stype\\s*=\\s*[\"']?checkbox[\"']?[\\s>/]/i.test(tagText)) {\n return escapeHtml(tagText);\n }\n\n let attrs = \"\";\n let attrMatch: RegExpExecArray | null;\n HTML_ATTR_REGEX.lastIndex = 0;\n while ((attrMatch = HTML_ATTR_REGEX.exec(rawAttrs)) !== null) {\n const name = attrMatch[1].toLowerCase();\n if (!ALLOWED_HTML_ATTRS.has(name) && !/^data-[a-z0-9_.-]+$/.test(name)) {\n continue;\n }\n const rawValue = attrMatch[2] ?? attrMatch[3] ?? attrMatch[4];\n if (rawValue === undefined) {\n attrs += ` ${name}`;\n continue;\n }\n const value = md.utils.unescapeAll(rawValue);\n if (\n (name === \"href\" || name === \"src\") &&\n // Browsers ignore control characters and whitespace inside schemes.\n !md.validateLink(value.replace(/[\\u0000-\\u0020\\u007f]/g, \"\"))\n ) {\n continue;\n }\n attrs += ` ${name}=\"${escapeHtml(value)}\"`;\n }\n return `<${tagName}${attrs}>`;\n}\n\n/**\n * Sanitizes raw HTML with an allowlist of tags and attributes: event handlers,\n * `style`, and unsafe URL schemes are dropped; disallowed tags are escaped.\n */\nfunction sanitizeEmbeddedHtml(html: string): string {\n let result = \"\";\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n HTML_TAG_REGEX.lastIndex = 0;\n while ((match = HTML_TAG_REGEX.exec(html)) !== null) {\n result += html.slice(lastIndex, match.index).replace(/</g, \"<\");\n result += sanitizeTag(match[0], match[1], match[2], match[3]);\n lastIndex = match.index + match[0].length;\n }\n return result + html.slice(lastIndex).replace(/</g, \"<\");\n}\n\nconst defaultHtmlInline = md.renderer.rules.html_inline;\nconst defaultHtmlBlock = md.renderer.rules.html_block;\nmd.renderer.rules.html_inline = (tokens, idx, options, env, self) =>\n env?.allowUnsafeHtml\n ? defaultHtmlInline!(tokens, idx, options, env, self)\n : sanitizeEmbeddedHtml(tokens[idx].content);\nmd.renderer.rules.html_block = (tokens, idx, options, env, self) =>\n env?.allowUnsafeHtml\n ? defaultHtmlBlock!(tokens, idx, options, env, self)\n : sanitizeEmbeddedHtml(tokens[idx].content);\n\nimport {\n preprocessMarkdownMentions,\n type PreprocessMarkdownMentionsOptions,\n} from \"./mentions\";\nimport type { MentionEntity } from \"../extensions/mention\";\n\n/**\n * Preprocesses file-protocol and editor-protocol links in markdown content:\n * converts [label](file://...), vscode://, and cursor:// links into anchor tags\n * annotated with data-file-link=\"true\", preserving code backticks in labels.\n */\nexport function preprocessMarkdownFileLinks(content: string): string {\n if (!content) return \"\";\n return content.replace(\n /\\[([^\\]]+)\\]\\(((?:file|vscode|cursor):\\/\\/[^)]+)\\)/g,\n (_match, rawLabel, href) => {\n const trimmed = rawLabel.trim();\n const codeMatch = trimmed.match(/^`([^`]+)`$/);\n const labelContent = codeMatch\n ? `<code>${escapeHtml(codeMatch[1])}</code>`\n : escapeHtml(trimmed);\n return `<a href=\"${escapeHtml(href)}\" data-file-link=\"true\" title=\"Click to copy file path\">${labelContent}</a>`;\n }\n );\n}\n\nexport interface MarkdownToHtmlOptions {\n /**\n * Preprocess file, vscode, and cursor links into clickable data-file-link tags.\n */\n preprocessFileLinks?: boolean;\n /**\n * Whether to preprocess @mentions into TipTap mention node HTML spans.\n */\n preprocessMentions?: boolean;\n /**\n * Pool of mentionables to pass to preprocessMarkdownMentions.\n */\n mentionables?: MentionEntity[];\n /**\n * Full options for preprocessMarkdownMentions.\n */\n preprocessOptions?: PreprocessMarkdownMentionsOptions;\n /**\n * Render raw HTML embedded in the markdown without sanitizing it. By default,\n * embedded HTML is restricted to an allowlist of tags and attributes (event\n * handlers, `style` and unsafe URL schemes are removed). Only enable this for\n * fully trusted input.\n */\n allowUnsafeHtml?: boolean;\n}\n\n/**\n * Converts a markdown string into HTML suitable for TipTap initial content or setContent.\n * Raw HTML embedded in the markdown is sanitized unless `allowUnsafeHtml` is set.\n */\nexport function markdownToTipTapHtml(\n markdown: string,\n options?: MarkdownToHtmlOptions\n): string {\n if (!markdown) return \"<p></p>\";\n let content = markdown;\n if (options?.preprocessFileLinks) {\n content = preprocessMarkdownFileLinks(content);\n }\n if (\n options?.preprocessMentions ||\n options?.mentionables ||\n options?.preprocessOptions\n ) {\n const mentionOpts = options.preprocessOptions || {\n mentionables: options.mentionables,\n };\n content = preprocessMarkdownMentions(content, mentionOpts);\n }\n return md.render(content, { allowUnsafeHtml: options?.allowUnsafeHtml });\n}\n\n/**\n * Extracts clean markdown from a TipTap editor instance.\n * If the editor has the Markdown extension configured, it uses editor.storage.markdown.getMarkdown().\n * Otherwise, it falls back to getEditorText(editor).\n */\nexport function getEditorMarkdown(editor: any): string {\n if (!editor) return \"\";\n if (typeof editor.storage?.markdown?.getMarkdown === \"function\") {\n return editor.storage.markdown.getMarkdown();\n }\n return getEditorText(editor);\n}\n","import { Editor, EditorOptions, Content, Extensions } from \"@tiptap/core\";\nimport {\n Slice,\n Fragment,\n Node as ProsemirrorNode,\n type Schema,\n} from \"@tiptap/pm/model\";\nimport { Token, tokenizePrompt } from \"./grammar\";\nimport {\n plainTextToTipTapHtml,\n getEditorText,\n markdownToTipTapHtml,\n getEditorMarkdown,\n} from \"./serializers\";\n\nexport interface EditorControllerOptions extends Partial<\n Omit<EditorOptions, \"element\" | \"content\">\n> {\n element?: Element | HTMLElement | null;\n content?: string | Content;\n plainTextMode?: boolean;\n markdownMode?: boolean;\n extensions?: Extensions;\n onPlainTextChange?: (text: string) => void;\n onMarkdownChange?: (markdown: string) => void;\n onTokensChange?: (tokens: Token[]) => void;\n onSelectionChange?: (range: { from: number; to: number } | null) => void;\n}\n\n/**\n * Builds an open slice with one paragraph per line, so inserting it splits the\n * surrounding paragraph like typing Enter would.\n */\nfunction plainTextToSlice(text: string, schema: Schema): Slice {\n const nodes: ProsemirrorNode[] = [];\n text\n .replace(/\\r\\n?/g, \"\\n\")\n .split(\"\\n\")\n .forEach((line) => {\n const nodeJson: any = { type: \"paragraph\" };\n if (line.length > 0) {\n nodeJson.content = [{ type: \"text\", text: line }];\n }\n try {\n nodes.push(ProsemirrorNode.fromJSON(schema, nodeJson));\n } catch {\n // Ignore invalid node\n }\n });\n return Slice.maxOpen(Fragment.fromArray(nodes));\n}\n\n/**\n * UI-agnostic controller managing the lifecycle, commands, and plain-text/token\n * synchronization of a rich text or prompt editor.\n */\nexport class EditorController {\n public readonly editor: Editor;\n private readonly plainTextMode: boolean;\n private readonly markdownMode: boolean;\n private readonly onPlainTextChange?: (text: string) => void;\n private readonly onMarkdownChange?: (markdown: string) => void;\n private readonly onTokensChange?: (tokens: Token[]) => void;\n private readonly onSelectionChange?: (\n range: { from: number; to: number } | null,\n ) => void;\n private baselineContent: string;\n\n constructor(options: EditorControllerOptions = {}) {\n const {\n element,\n content,\n plainTextMode = false,\n markdownMode = false,\n extensions = [],\n onPlainTextChange,\n onMarkdownChange,\n onTokensChange,\n onSelectionChange,\n ...editorOptions\n } = options;\n\n this.plainTextMode = plainTextMode;\n this.markdownMode = markdownMode;\n this.onPlainTextChange = onPlainTextChange;\n this.onMarkdownChange = onMarkdownChange;\n this.onTokensChange = onTokensChange;\n this.onSelectionChange = onSelectionChange;\n\n const initialContent =\n plainTextMode && typeof content === \"string\"\n ? plainTextToTipTapHtml(content)\n : markdownMode && typeof content === \"string\"\n ? markdownToTipTapHtml(content)\n : content;\n\n this.editor = new Editor({\n element: element || undefined,\n content: initialContent,\n extensions,\n ...editorOptions,\n onUpdate: (props) => {\n editorOptions.onUpdate?.(props);\n this.handleUpdate();\n },\n onSelectionUpdate: (props) => {\n editorOptions.onSelectionUpdate?.(props);\n this.handleSelectionUpdate();\n },\n });\n\n if (plainTextMode) {\n this.enforcePlainTextClipboard();\n }\n\n this.baselineContent = this.getCurrentContentString();\n }\n\n private enforcePlainTextClipboard() {\n this.editor.setOptions({\n editorProps: {\n ...this.editor.options.editorProps,\n clipboardTextParser: (\n text: string,\n context: any,\n _plain: boolean,\n view?: any,\n ) => {\n const schema =\n context?.doc?.type?.schema ||\n context?.schema ||\n view?.state?.schema ||\n this.editor.schema;\n\n if (!schema) return Slice.empty;\n\n return plainTextToSlice(text, schema);\n },\n },\n });\n }\n\n private handleUpdate() {\n if (this.plainTextMode || this.onPlainTextChange || this.onTokensChange) {\n const text = this.getPlainText();\n this.onPlainTextChange?.(text);\n\n if (this.onTokensChange) {\n const tokens = tokenizePrompt(text);\n this.onTokensChange(tokens);\n }\n }\n\n if (this.markdownMode || this.onMarkdownChange) {\n const markdown = this.getMarkdown();\n this.onMarkdownChange?.(markdown);\n }\n }\n\n private handleSelectionUpdate() {\n if (this.onSelectionChange) {\n const { from, to } = this.editor.state.selection;\n this.onSelectionChange({ from, to });\n }\n }\n\n public getPlainText(): string {\n return getEditorText(this.editor);\n }\n\n public setPlainText(text: string, emitUpdate = true) {\n const html = plainTextToTipTapHtml(text);\n this.editor.commands.setContent(html, emitUpdate);\n }\n\n public getMarkdown(): string {\n return getEditorMarkdown(this.editor);\n }\n\n public setMarkdown(markdown: string, emitUpdate = true) {\n if (this.editor.storage?.markdown?.parser) {\n this.editor.commands.setContent(markdown, emitUpdate);\n } else {\n const html = markdownToTipTapHtml(markdown);\n this.editor.commands.setContent(html, emitUpdate);\n }\n }\n\n /**\n * Replaces `from`..`to` with literal text: HTML in `text` is not parsed, and\n * newlines split paragraphs.\n */\n private insertPlainText(from: number, to: number, text: string) {\n const { state, view } = this.editor;\n const tr = text.includes(\"\\n\") || text.includes(\"\\r\")\n ? state.tr.replace(from, to, plainTextToSlice(text, state.schema))\n : text\n ? state.tr.insertText(text, from, to)\n : state.tr.delete(from, to);\n view.dispatch(tr.scrollIntoView());\n }\n\n /** Inserts text literally at the selection; HTML in `text` is not parsed. */\n public insertText(text: string) {\n const { from, to } = this.editor.state.selection;\n this.insertPlainText(from, to, text);\n }\n\n /** Inserts text literally at `pos`; HTML in `text` is not parsed. */\n public insertTextAt(pos: number, text: string) {\n this.insertPlainText(pos, pos, text);\n this.editor.commands.focus();\n }\n\n /** Replaces a range with literal text; HTML in `text` is not parsed. */\n public replaceRange(from: number, to: number, text: string) {\n this.insertPlainText(from, to, text);\n this.editor.commands.focus();\n }\n\n public getCurrentContentString(): string {\n if (this.plainTextMode) return this.getPlainText();\n if (this.markdownMode) return this.getMarkdown();\n return this.editor.getHTML();\n }\n\n public isDirty(): boolean {\n return this.getCurrentContentString() !== this.baselineContent;\n }\n\n public setCheckpoint(content?: string): void {\n this.baselineContent =\n content !== undefined ? content : this.getCurrentContentString();\n }\n\n public resetDirty(): void {\n this.setCheckpoint();\n }\n\n public getBaselineContent(): string {\n return this.baselineContent;\n }\n\n public destroy() {\n this.editor.destroy();\n }\n}\n\n/**\n * Creates and initializes an EditorController instance.\n */\nexport function createEditor(\n options: EditorControllerOptions = {},\n): EditorController {\n return new EditorController(options);\n}\n","export type FormulaTokenType =\n | 'NUMBER'\n | 'STRING'\n | 'BOOLEAN'\n | 'CELL_REF'\n | 'RANGE'\n | 'PROPERTY_REF'\n | 'IDENTIFIER'\n | 'OPERATOR'\n | 'LPAREN'\n | 'RPAREN'\n | 'COMMA'\n | 'EOF';\n\nexport interface FormulaToken {\n type: FormulaTokenType;\n value: string;\n position: number;\n}\n\nexport function tokenizeFormula(formula: string): FormulaToken[] {\n const tokens: FormulaToken[] = [];\n // Strip leading '=' if present\n let input = formula.trim();\n let offset = 0;\n if (input.startsWith('=')) {\n input = input.slice(1);\n offset = 1;\n }\n\n let i = 0;\n while (i < input.length) {\n const char = input[i];\n\n // Skip whitespace\n if (/\\s/.test(char)) {\n i++;\n continue;\n }\n\n // Number literal (int or float)\n if (/\\d/.test(char) || (char === '.' && i + 1 < input.length && /\\d/.test(input[i + 1]))) {\n const start = i;\n let hasDot = char === '.';\n i++;\n while (i < input.length && (/\\d/.test(input[i]) || (input[i] === '.' && !hasDot))) {\n if (input[i] === '.') hasDot = true;\n i++;\n }\n tokens.push({\n type: 'NUMBER',\n value: input.slice(start, i),\n position: start + offset\n });\n continue;\n }\n\n // String literal (\"...\" or '...')\n if (char === '\"' || char === \"'\") {\n const quote = char;\n const start = i;\n i++;\n let str = '';\n while (i < input.length && input[i] !== quote) {\n if (input[i] === '\\\\' && i + 1 < input.length) {\n i++;\n }\n str += input[i];\n i++;\n }\n if (i < input.length && input[i] === quote) {\n i++; // skip closing quote\n }\n tokens.push({\n type: 'STRING',\n value: str,\n position: start + offset\n });\n continue;\n }\n\n // Property reference: [property_name] e.g. [status], [title], [effortHours]\n if (char === '[') {\n const start = i;\n i++;\n let prop = '';\n while (i < input.length && input[i] !== ']') {\n prop += input[i];\n i++;\n }\n if (i < input.length && input[i] === ']') {\n i++;\n }\n tokens.push({\n type: 'PROPERTY_REF',\n value: prop.trim(),\n position: start + offset\n });\n continue;\n }\n\n // Single character delimiters\n if (char === '(') {\n tokens.push({ type: 'LPAREN', value: '(', position: i + offset });\n i++;\n continue;\n }\n if (char === ')') {\n tokens.push({ type: 'RPAREN', value: ')', position: i + offset });\n i++;\n continue;\n }\n if (char === ',') {\n tokens.push({ type: 'COMMA', value: ',', position: i + offset });\n i++;\n continue;\n }\n\n // Multi-character comparison operators: <=, >=, <>, !=\n const twoChars = input.slice(i, i + 2);\n if (['<=', '>=', '<>', '!='].includes(twoChars)) {\n tokens.push({\n type: 'OPERATOR',\n value: twoChars === '!=' ? '<>' : twoChars,\n position: i + offset\n });\n i += 2;\n continue;\n }\n\n // Single character operators: +, -, *, /, ^, &, =, <, >\n if (['+', '-', '*', '/', '^', '&', '=', '<', '>'].includes(char)) {\n tokens.push({ type: 'OPERATOR', value: char, position: i + offset });\n i++;\n continue;\n }\n\n // Identifiers, Cell references, and Ranges (e.g. SUM, A1, B2:B10, A:A)\n if (/[a-zA-Z_$]/.test(char)) {\n const start = i;\n while (i < input.length && /[a-zA-Z0-9_$.]/.test(input[i])) {\n i++;\n }\n const rawWord = input.slice(start, i);\n\n // Check if followed by colon indicating a range e.g. A1:B10 or A:A\n if (i < input.length && input[i] === ':') {\n const colonPos = i;\n i++; // skip colon\n const secondStart = i;\n while (i < input.length && /[a-zA-Z0-9_$.]/.test(input[i])) {\n i++;\n }\n const secondWord = input.slice(secondStart, i);\n if (secondWord.length > 0) {\n tokens.push({\n type: 'RANGE',\n value: `${rawWord}:${secondWord}`.toUpperCase(),\n position: start + offset\n });\n continue;\n } else {\n // Revert back\n i = colonPos;\n }\n }\n\n // Check for boolean literal\n const upper = rawWord.toUpperCase();\n if (upper === 'TRUE' || upper === 'FALSE') {\n tokens.push({\n type: 'BOOLEAN',\n value: upper,\n position: start + offset\n });\n continue;\n }\n\n // Check for Cell Reference (e.g. A1, $B$12, AA100)\n if (/^\\$?[A-Za-z]+\\$?[0-9]+$/.test(rawWord)) {\n tokens.push({\n type: 'CELL_REF',\n value: upper.replace(/\\$/g, ''),\n position: start + offset\n });\n continue;\n }\n\n // Function or generic identifier\n tokens.push({\n type: 'IDENTIFIER',\n value: upper,\n position: start + offset\n });\n continue;\n }\n\n // Skip unknown character\n i++;\n }\n\n tokens.push({ type: 'EOF', value: '', position: input.length + offset });\n return tokens;\n}\n","import { FormulaToken, tokenizeFormula, FormulaTokenType } from './lexer';\n\nexport type ASTNode =\n | LiteralNode\n | CellRefNode\n | RangeNode\n | PropertyRefNode\n | BinaryOpNode\n | UnaryOpNode\n | FunctionCallNode;\n\nexport interface LiteralNode {\n type: 'Literal';\n value: number | string | boolean;\n}\n\nexport interface CellRefNode {\n type: 'CellRef';\n ref: string;\n col: string;\n row: number;\n}\n\nexport interface RangeNode {\n type: 'Range';\n raw: string;\n startCol: string;\n startRow: number;\n endCol: string;\n endRow: number;\n}\n\nexport interface PropertyRefNode {\n type: 'PropertyRef';\n property: string;\n}\n\nexport interface BinaryOpNode {\n type: 'BinaryOp';\n op: string;\n left: ASTNode;\n right: ASTNode;\n}\n\nexport interface UnaryOpNode {\n type: 'UnaryOp';\n op: string;\n argument: ASTNode;\n}\n\nexport interface FunctionCallNode {\n type: 'FunctionCall';\n name: string;\n args: ASTNode[];\n}\n\nexport function parseCellReference(ref: string): { col: string; row: number } {\n const match = ref.match(/^([A-Za-z]+)(\\d+)$/);\n if (!match) {\n throw new Error(`Invalid cell reference: ${ref}`);\n }\n return {\n col: match[1].toUpperCase(),\n row: parseInt(match[2], 10)\n };\n}\n\nexport function parseRange(rangeStr: string): RangeNode {\n const [start, end] = rangeStr.split(':');\n const startRef = parseCellReference(start);\n const endRef = parseCellReference(end);\n return {\n type: 'Range',\n raw: rangeStr.toUpperCase(),\n startCol: startRef.col,\n startRow: startRef.row,\n endCol: endRef.col,\n endRow: endRef.row\n };\n}\n\nexport class FormulaParser {\n private tokens: FormulaToken[] = [];\n private current = 0;\n\n constructor(tokens: FormulaToken[]) {\n this.tokens = tokens;\n }\n\n public parse(): ASTNode {\n if (this.peek().type === 'EOF') {\n return { type: 'Literal', value: '' };\n }\n const expr = this.expression();\n if (this.peek().type !== 'EOF') {\n throw new Error(`Unexpected token at position ${this.peek().position}: ${this.peek().value}`);\n }\n return expr;\n }\n\n private expression(): ASTNode {\n return this.comparison();\n }\n\n private comparison(): ASTNode {\n let expr = this.concatenation();\n\n while (\n this.matchOperator('=', '<>', '<', '>', '<=', '>=')\n ) {\n const op = this.previous().value;\n const right = this.concatenation();\n expr = { type: 'BinaryOp', op, left: expr, right };\n }\n\n return expr;\n }\n\n private concatenation(): ASTNode {\n let expr = this.addition();\n\n while (this.matchOperator('&')) {\n const op = this.previous().value;\n const right = this.addition();\n expr = { type: 'BinaryOp', op, left: expr, right };\n }\n\n return expr;\n }\n\n private addition(): ASTNode {\n let expr = this.multiplication();\n\n while (this.matchOperator('+', '-')) {\n const op = this.previous().value;\n const right = this.multiplication();\n expr = { type: 'BinaryOp', op, left: expr, right };\n }\n\n return expr;\n }\n\n private multiplication(): ASTNode {\n let expr = this.exponentiation();\n\n while (this.matchOperator('*', '/')) {\n const op = this.previous().value;\n const right = this.exponentiation();\n expr = { type: 'BinaryOp', op, left: expr, right };\n }\n\n return expr;\n }\n\n private exponentiation(): ASTNode {\n let expr = this.unary();\n\n while (this.matchOperator('^')) {\n const op = this.previous().value;\n const right = this.unary();\n expr = { type: 'BinaryOp', op, left: expr, right };\n }\n\n return expr;\n }\n\n private unary(): ASTNode {\n if (this.matchOperator('-', '+')) {\n const op = this.previous().value;\n const argument = this.unary();\n return { type: 'UnaryOp', op, argument };\n }\n return this.primary();\n }\n\n private primary(): ASTNode {\n const token = this.peek();\n\n if (token.type === 'NUMBER') {\n this.advance();\n return { type: 'Literal', value: parseFloat(token.value) };\n }\n\n if (token.type === 'STRING') {\n this.advance();\n return { type: 'Literal', value: token.value };\n }\n\n if (token.type === 'BOOLEAN') {\n this.advance();\n return { type: 'Literal', value: token.value === 'TRUE' };\n }\n\n if (token.type === 'CELL_REF') {\n this.advance();\n const parsed = parseCellReference(token.value);\n return {\n type: 'CellRef',\n ref: token.value,\n col: parsed.col,\n row: parsed.row\n };\n }\n\n if (token.type === 'RANGE') {\n this.advance();\n return parseRange(token.value);\n }\n\n if (token.type === 'PROPERTY_REF') {\n this.advance();\n return {\n type: 'PropertyRef',\n property: token.value\n };\n }\n\n // Function call e.g. SUM(...)\n if (token.type === 'IDENTIFIER') {\n const name = token.value;\n this.advance();\n\n if (this.check('LPAREN')) {\n this.consume('LPAREN', `Expected '(' after function ${name}`);\n const args: ASTNode[] = [];\n if (!this.check('RPAREN')) {\n do {\n args.push(this.expression());\n } while (this.match('COMMA'));\n }\n this.consume('RPAREN', `Expected ')' after function arguments`);\n return {\n type: 'FunctionCall',\n name,\n args\n };\n }\n\n // Standalone identifier treated as string literal or reference\n return { type: 'Literal', value: name };\n }\n\n if (this.match('LPAREN')) {\n const expr = this.expression();\n this.consume('RPAREN', `Expected ')' after expression`);\n return expr;\n }\n\n throw new Error(`Unexpected token at position ${token.position}: ${token.value || token.type}`);\n }\n\n private match(...types: string[]): boolean {\n for (const type of types) {\n if (this.check(type)) {\n this.advance();\n return true;\n }\n }\n return false;\n }\n\n private matchOperator(...ops: string[]): boolean {\n if (this.check('OPERATOR') && ops.includes(this.peek().value)) {\n this.advance();\n return true;\n }\n return false;\n }\n\n private check(type: string): boolean {\n if (this.isAtEnd()) return false;\n return this.peek().type === type;\n }\n\n private advance(): FormulaToken {\n if (!this.isAtEnd()) this.current++;\n return this.previous();\n }\n\n private isAtEnd(): boolean {\n return this.peek().type === 'EOF';\n }\n\n private peek(): FormulaToken {\n return this.tokens[this.current];\n }\n\n private previous(): FormulaToken {\n return this.tokens[this.current - 1];\n }\n\n private consume(type: string, message: string): FormulaToken {\n if (this.check(type)) return this.advance();\n throw new Error(message);\n }\n}\n\nexport function parseFormula(formula: string): ASTNode {\n const tokens = tokenizeFormula(formula);\n const parser = new FormulaParser(tokens);\n return parser.parse();\n}\n","import { ASTNode, parseFormula } from './parser';\n\nexport interface EvaluationContext {\n resolveCell?: (col: string, row: number) => any;\n resolveRange?: (startCol: string, startRow: number, endCol: string, endRow: number) => any[];\n resolveProperty?: (property: string) => any;\n}\n\nexport function colNameToIndex(col: string): number {\n let index = 0;\n const upper = col.toUpperCase();\n for (let i = 0; i < upper.length; i++) {\n index = index * 26 + (upper.charCodeAt(i) - 65 + 1);\n }\n return index - 1;\n}\n\nexport function indexToColName(index: number): string {\n let num = index + 1;\n let name = '';\n while (num > 0) {\n const mod = (num - 1) % 26;\n name = String.fromCharCode(65 + mod) + name;\n num = Math.floor((num - mod) / 26);\n }\n return name;\n}\n\nexport class FormulaEvaluator {\n private context: EvaluationContext;\n\n constructor(context: EvaluationContext = {}) {\n this.context = context;\n }\n\n public evaluate(astOrFormula: ASTNode | string): any {\n const ast = typeof astOrFormula === 'string' ? parseFormula(astOrFormula) : astOrFormula;\n return this.evaluateNode(ast);\n }\n\n private evaluateNode(node: ASTNode): any {\n switch (node.type) {\n case 'Literal':\n return node.value;\n\n case 'CellRef': {\n if (!this.context.resolveCell) {\n throw new Error(`Cannot resolve cell reference ${node.ref}: no cell resolver provided`);\n }\n return this.context.resolveCell(node.col, node.row);\n }\n\n case 'Range': {\n if (!this.context.resolveRange) {\n throw new Error(`Cannot resolve range ${node.raw}: no range resolver provided`);\n }\n return this.context.resolveRange(node.startCol, node.startRow, node.endCol, node.endRow);\n }\n\n case 'PropertyRef': {\n if (!this.context.resolveProperty) {\n throw new Error(`Cannot resolve property [${node.property}]: no property resolver provided`);\n }\n return this.context.resolveProperty(node.property);\n }\n\n case 'UnaryOp': {\n const val = this.evaluateNode(node.argument);\n if (node.op === '-') return -Number(val);\n if (node.op === '+') return +Number(val);\n throw new Error(`Unsupported unary operator: ${node.op}`);\n }\n\n case 'BinaryOp': {\n const left = this.evaluateNode(node.left);\n const right = this.evaluateNode(node.right);\n\n switch (node.op) {\n case '+':\n return Number(left) + Number(right);\n case '-':\n return Number(left) - Number(right);\n case '*':\n return Number(left) * Number(right);\n case '/': {\n const denom = Number(right);\n if (denom === 0) return '#DIV/0!';\n return Number(left) / denom;\n }\n case '^':\n return Math.pow(Number(left), Number(right));\n case '&':\n return `${left ?? ''}${right ?? ''}`;\n case '=':\n // Relaxed equality\n return String(left).toLowerCase() === String(right).toLowerCase();\n case '<>':\n return String(left).toLowerCase() !== String(right).toLowerCase();\n case '<':\n return Number(left) < Number(right);\n case '<=':\n return Number(left) <= Number(right);\n case '>':\n return Number(left) > Number(right);\n case '>=':\n return Number(left) >= Number(right);\n default:\n throw new Error(`Unsupported binary operator: ${node.op}`);\n }\n }\n\n case 'FunctionCall': {\n return this.callFunction(node.name, node.args);\n }\n\n default:\n throw new Error(`Unknown AST node: ${(node as any).type}`);\n }\n }\n\n private callFunction(name: string, args: ASTNode[]): any {\n const fnName = name.toUpperCase();\n\n // Flatten helper for range/array args\n const evaluateAndFlatten = (): any[] => {\n const items: any[] = [];\n for (const arg of args) {\n const val = this.evaluateNode(arg);\n if (Array.isArray(val)) {\n items.push(...val);\n } else {\n items.push(val);\n }\n }\n return items;\n };\n\n switch (fnName) {\n case 'SUM': {\n const items = evaluateAndFlatten();\n let total = 0;\n for (const item of items) {\n const num = Number(item);\n if (!isNaN(num)) total += num;\n }\n return total;\n }\n\n case 'AVERAGE': {\n const items = evaluateAndFlatten();\n let total = 0;\n let count = 0;\n for (const item of items) {\n const num = Number(item);\n if (!isNaN(num) && item !== '' && item !== null && item !== undefined) {\n total += num;\n count++;\n }\n }\n return count === 0 ? 0 : total / count;\n }\n\n case 'COUNT': {\n const items = evaluateAndFlatten();\n let count = 0;\n for (const item of items) {\n const num = Number(item);\n if (!isNaN(num) && item !== '' && item !== null && item !== undefined) {\n count++;\n }\n }\n return count;\n }\n\n case 'COUNTA': {\n const items = evaluateAndFlatten();\n let count = 0;\n for (const item of items) {\n if (item !== '' && item !== null && item !== undefined) {\n count++;\n }\n }\n return count;\n }\n\n case 'MIN': {\n const items = evaluateAndFlatten().map(Number).filter((n) => !isNaN(n));\n return items.length === 0 ? 0 : Math.min(...items);\n }\n\n case 'MAX': {\n const items = evaluateAndFlatten().map(Number).filter((n) => !isNaN(n));\n return items.length === 0 ? 0 : Math.max(...items);\n }\n\n case 'IF': {\n if (args.length < 2) throw new Error('IF requires at least 2 arguments');\n const condition = Boolean(this.evaluateNode(args[0]));\n if (condition) {\n return this.evaluateNode(args[1]);\n } else {\n return args.length > 2 ? this.evaluateNode(args[2]) : false;\n }\n }\n\n case 'CONCAT': {\n const items = evaluateAndFlatten();\n return items.map((i) => (i === null || i === undefined ? '' : String(i))).join('');\n }\n\n case 'UPPER': {\n if (args.length !== 1) throw new Error('UPPER requires 1 argument');\n const val = this.evaluateNode(args[0]);\n return String(val ?? '').toUpperCase();\n }\n\n case 'LOWER': {\n if (args.length !== 1) throw new Error('LOWER requires 1 argument');\n const val = this.evaluateNode(args[0]);\n return String(val ?? '').toLowerCase();\n }\n\n case 'TRIM': {\n if (args.length !== 1) throw new Error('TRIM requires 1 argument');\n const val = this.evaluateNode(args[0]);\n return String(val ?? '').trim();\n }\n\n case 'LEN': {\n if (args.length !== 1) throw new Error('LEN requires 1 argument');\n const val = this.evaluateNode(args[0]);\n return String(val ?? '').length;\n }\n\n case 'ROUND': {\n if (args.length < 1) throw new Error('ROUND requires at least 1 argument');\n const num = Number(this.evaluateNode(args[0]));\n const decimals = args.length > 1 ? Number(this.evaluateNode(args[1])) : 0;\n const factor = Math.pow(10, decimals);\n return Math.round(num * factor) / factor;\n }\n\n case 'ABS': {\n if (args.length !== 1) throw new Error('ABS requires 1 argument');\n return Math.abs(Number(this.evaluateNode(args[0])));\n }\n\n case 'TODAY': {\n return new Date().toISOString().split('T')[0];\n }\n\n case 'DAYS': {\n if (args.length !== 2) throw new Error('DAYS requires 2 arguments (end_date, start_date)');\n const d1 = new Date(this.evaluateNode(args[0]));\n const d2 = new Date(this.evaluateNode(args[1]));\n const diffTime = d1.getTime() - d2.getTime();\n return Math.round(diffTime / (1000 * 60 * 60 * 24));\n }\n\n default:\n throw new Error(`Unknown function: ${fnName}`);\n }\n }\n}\n","import { ASTNode, parseFormula } from './parser';\nimport { colNameToIndex, indexToColName } from './evaluator';\n\nexport interface CellDep {\n col: string;\n row: number;\n}\n\nexport function extractCellDependencies(node: ASTNode): CellDep[] {\n const deps: CellDep[] = [];\n\n const visit = (curr: ASTNode) => {\n if (curr.type === 'CellRef') {\n deps.push({ col: curr.col, row: curr.row });\n } else if (curr.type === 'Range') {\n const startC = colNameToIndex(curr.startCol);\n const endC = colNameToIndex(curr.endCol);\n const minC = Math.min(startC, endC);\n const maxC = Math.max(startC, endC);\n const minR = Math.min(curr.startRow, curr.endRow);\n const maxR = Math.max(curr.startRow, curr.endRow);\n\n for (let c = minC; c <= maxC; c++) {\n for (let r = minR; r <= maxR; r++) {\n deps.push({ col: indexToColName(c), row: r });\n }\n }\n } else if (curr.type === 'BinaryOp') {\n visit(curr.left);\n visit(curr.right);\n } else if (curr.type === 'UnaryOp') {\n visit(curr.argument);\n } else if (curr.type === 'FunctionCall') {\n curr.args.forEach(visit);\n }\n };\n\n visit(node);\n return deps;\n}\n\nexport class DependencyGraph {\n // Map of cellKey (e.g. \"B2\") -> Set of cellKeys that this cell depends ON\n private dependencies = new Map<string, Set<string>>();\n // Map of cellKey (e.g. \"A1\") -> Set of cellKeys that depend ON this cell (dependents)\n private dependents = new Map<string, Set<string>>();\n\n public setCellFormula(cellKey: string, formulaStr: string | null): void {\n const key = cellKey.toUpperCase();\n\n // Clear existing dependencies\n const oldDeps = this.dependencies.get(key) || new Set();\n for (const dep of oldDeps) {\n this.dependents.get(dep)?.delete(key);\n }\n this.dependencies.delete(key);\n\n if (!formulaStr || !formulaStr.startsWith('=')) {\n return;\n }\n\n try {\n const ast = parseFormula(formulaStr);\n const deps = extractCellDependencies(ast);\n const newDeps = new Set<string>();\n\n for (const d of deps) {\n const depKey = `${d.col}${d.row}`.toUpperCase();\n newDeps.add(depKey);\n\n if (!this.dependents.has(depKey)) {\n this.dependents.set(depKey, new Set());\n }\n this.dependents.get(depKey)!.add(key);\n }\n\n this.dependencies.set(key, newDeps);\n } catch {\n // Syntax errors in formula have no valid dependencies\n }\n }\n\n public getDependencies(cellKey: string): string[] {\n return Array.from(this.dependencies.get(cellKey.toUpperCase()) || []);\n }\n\n public getDependents(cellKey: string): string[] {\n return Array.from(this.dependents.get(cellKey.toUpperCase()) || []);\n }\n\n /**\n * Detects if there is a cycle containing cellKey.\n */\n public hasCycle(cellKey: string): boolean {\n const key = cellKey.toUpperCase();\n const visited = new Set<string>();\n const recStack = new Set<string>();\n\n const dfs = (node: string): boolean => {\n visited.add(node);\n recStack.add(node);\n\n const deps = this.dependencies.get(node) || new Set();\n for (const neighbor of deps) {\n if (!visited.has(neighbor)) {\n if (dfs(neighbor)) return true;\n } else if (recStack.has(neighbor)) {\n return true;\n }\n }\n\n recStack.delete(node);\n return false;\n };\n\n return dfs(key);\n }\n\n /**\n * Returns cells affected by updating cellKey in topological order.\n */\n public getEvaluationOrder(startCellKey: string): { order: string[]; hasCycle: boolean } {\n const start = startCellKey.toUpperCase();\n const visited = new Set<string>();\n const recStack = new Set<string>();\n const order: string[] = [];\n let cycleDetected = false;\n\n // Collect all downstream affected cells (reachability via dependents)\n const affected = new Set<string>();\n const collectAffected = (node: string) => {\n affected.add(node);\n const directDependents = this.dependents.get(node) || new Set();\n for (const dep of directDependents) {\n if (!affected.has(dep)) {\n collectAffected(dep);\n }\n }\n };\n collectAffected(start);\n\n // Topological sort among affected cells\n const visit = (node: string) => {\n if (recStack.has(node)) {\n cycleDetected = true;\n return;\n }\n if (visited.has(node)) return;\n\n recStack.add(node);\n visited.add(node);\n\n // Visit nodes that this node depends on, IF they are in the affected set\n const deps = this.dependencies.get(node) || new Set();\n for (const neighbor of deps) {\n if (affected.has(neighbor)) {\n visit(neighbor);\n }\n }\n\n recStack.delete(node);\n order.push(node);\n };\n\n for (const node of affected) {\n if (!visited.has(node)) {\n visit(node);\n }\n }\n\n return { order, hasCycle: cycleDetected };\n }\n}\n","import { SpreadsheetDataSource, SpreadsheetRow, SpreadsheetColumn } from '../types';\n\nexport class DataSourceBinder {\n private dataSources = new Map<string, SpreadsheetDataSource>();\n\n public register(dataSource: SpreadsheetDataSource): void {\n this.dataSources.set(dataSource.id, dataSource);\n }\n\n public unregister(dataSourceId: string): void {\n this.dataSources.delete(dataSourceId);\n }\n\n public getDataSource(id: string): SpreadsheetDataSource | undefined {\n return this.dataSources.get(id);\n }\n\n /**\n * Generates or reconciles spreadsheet rows from a primary data source.\n */\n public syncRows(\n currentRows: SpreadsheetRow[],\n dataSourceId: string\n ): SpreadsheetRow[] {\n const ds = this.dataSources.get(dataSourceId);\n if (!ds) return currentRows;\n\n const records = ds.getRecords();\n const existingRecordRowMap = new Map<string, SpreadsheetRow>();\n const freeformRows: SpreadsheetRow[] = [];\n\n for (const row of currentRows) {\n if (row.type === 'record' && row.recordId) {\n existingRecordRowMap.set(row.recordId, row);\n } else {\n freeformRows.push(row);\n }\n }\n\n const nextRows: SpreadsheetRow[] = [];\n let rowIndex = 0;\n\n for (const record of records) {\n const existing = existingRecordRowMap.get(record.id);\n nextRows.push({\n id: existing?.id || `row_${record.id}`,\n index: rowIndex++,\n height: existing?.height || 32,\n recordId: record.id,\n type: 'record'\n });\n existingRecordRowMap.delete(record.id);\n }\n\n // Append preserved freeform rows\n for (const freeform of freeformRows) {\n nextRows.push({\n ...freeform,\n index: rowIndex++\n });\n }\n\n return nextRows;\n }\n\n /**\n * Resolves a record's bound field value.\n */\n public resolveBoundValue(\n dataSourceId: string,\n recordId: string,\n field: string\n ): any {\n const ds = this.dataSources.get(dataSourceId);\n if (!ds) return undefined;\n\n const records = ds.getRecords();\n const record = records.find((r) => r.id === recordId);\n return record ? record[field] : undefined;\n }\n\n /**\n * Dispatches an update to the underlying data source.\n */\n public async commitBoundValue(\n dataSourceId: string,\n recordId: string,\n field: string,\n value: any\n ): Promise<void> {\n const ds = this.dataSources.get(dataSourceId);\n if (!ds) return;\n await ds.updateRecord(recordId, field, value);\n }\n}\n","import {\n SpreadsheetDocument,\n SpreadsheetColumn,\n SpreadsheetRow,\n CellCoordinate,\n CellRange,\n CellData,\n SpreadsheetDataSource\n} from './types';\nimport {\n FormulaEvaluator,\n colNameToIndex,\n indexToColName,\n DependencyGraph\n} from './formula';\nimport { DataSourceBinder } from './datasource';\n\nexport interface SpreadsheetControllerOptions {\n document?: Partial<SpreadsheetDocument>;\n dataSources?: SpreadsheetDataSource[];\n primaryDataSourceId?: string;\n onDocumentChange?: (doc: SpreadsheetDocument) => void;\n onSelectionChange?: (activeCell: CellCoordinate | null, range: CellRange | null) => void;\n onCellCommit?: (rowId: string, colId: string, raw: string, value: any) => void;\n}\n\nexport class SpreadsheetController {\n public document: SpreadsheetDocument;\n public activeCell: CellCoordinate | null = null;\n public selectedRange: CellRange | null = null;\n public editingCell: CellCoordinate | null = null;\n public draftValue = '';\n\n public readonly binder = new DataSourceBinder();\n public readonly depGraph = new DependencyGraph();\n public readonly evaluator: FormulaEvaluator;\n\n private primaryDataSourceId?: string;\n private onDocumentChange?: (doc: SpreadsheetDocument) => void;\n private onSelectionChange?: (activeCell: CellCoordinate | null, range: CellRange | null) => void;\n private onCellCommit?: (rowId: string, colId: string, raw: string, value: any) => void;\n\n // History stack for undo/redo\n private undoStack: string[] = [];\n private redoStack: string[] = [];\n private isApplyingHistory = false;\n\n constructor(options: SpreadsheetControllerOptions = {}) {\n const defaultCols: SpreadsheetColumn[] = [\n { id: 'col_a', key: 'A', title: 'A', width: 120, type: 'freeform' },\n { id: 'col_b', key: 'B', title: 'B', width: 120, type: 'freeform' },\n { id: 'col_c', key: 'C', title: 'C', width: 120, type: 'freeform' },\n { id: 'col_d', key: 'D', title: 'D', width: 120, type: 'freeform' }\n ];\n\n const defaultRows: SpreadsheetRow[] = options.primaryDataSourceId ? [] : Array.from({ length: 10 }, (_, i) => ({\n id: `row_${i + 1}`,\n index: i,\n height: 32,\n type: 'freeform'\n }));\n\n this.document = {\n id: options.document?.id || `sheet_${Date.now()}`,\n name: options.document?.name || 'Sheet 1',\n columns: options.document?.columns || defaultCols,\n rows: options.document?.rows || defaultRows,\n cells: options.document?.cells || {},\n createdAt: options.document?.createdAt || Date.now(),\n updatedAt: options.document?.updatedAt || Date.now()\n };\n\n this.primaryDataSourceId = options.primaryDataSourceId;\n this.onDocumentChange = options.onDocumentChange;\n this.onSelectionChange = options.onSelectionChange;\n this.onCellCommit = options.onCellCommit;\n\n if (options.dataSources) {\n options.dataSources.forEach((ds) => this.binder.register(ds));\n }\n\n this.evaluator = new FormulaEvaluator({\n resolveCell: (colStr, rowNum) => this.resolveCellByCoord(colStr, rowNum),\n resolveRange: (sCol, sRow, eCol, eRow) => this.resolveRangeByCoords(sCol, sRow, eCol, eRow),\n resolveProperty: (prop) => this.resolveCurrentRowProperty(prop)\n });\n\n this.syncWithDataSource();\n this.recalculateAll();\n }\n\n public loadDocument(document: SpreadsheetDocument): void {\n this.document = JSON.parse(JSON.stringify(document));\n this.activeCell = null;\n this.selectedRange = null;\n this.editingCell = null;\n this.draftValue = '';\n this.undoStack = [];\n this.redoStack = [];\n this.syncWithDataSource();\n this.recalculateAll();\n this.notifyChange();\n }\n\n public registerDataSource(ds: SpreadsheetDataSource): void {\n this.binder.register(ds);\n this.syncWithDataSource();\n this.recalculateAll();\n }\n\n public setPrimaryDataSource(dataSourceId: string | undefined): void {\n this.primaryDataSourceId = dataSourceId;\n this.syncWithDataSource();\n this.recalculateAll();\n }\n\n public syncWithDataSource(): void {\n if (!this.primaryDataSourceId) return;\n this.document.rows = this.binder.syncRows(this.document.rows, this.primaryDataSourceId);\n this.recomputeRowIndices();\n }\n\n private recomputeRowIndices(): void {\n this.document.rows.forEach((r, idx) => {\n r.index = idx;\n });\n this.document.columns.forEach((c, idx) => {\n c.key = indexToColName(idx);\n });\n }\n\n public getColumn(colIdOrKey: string): SpreadsheetColumn | undefined {\n return this.document.columns.find(\n (c) => c.id === colIdOrKey || c.key.toUpperCase() === colIdOrKey.toUpperCase()\n );\n }\n\n public getRow(rowIdOrIndex: string | number): SpreadsheetRow | undefined {\n if (typeof rowIdOrIndex === 'number') {\n return this.document.rows[rowIdOrIndex];\n }\n return this.document.rows.find((r) => r.id === rowIdOrIndex);\n }\n\n public getCell(rowId: string, colId: string): CellData {\n const existing = this.document.cells[rowId]?.[colId];\n if (existing) return existing;\n\n // Check if column is bound to record\n const col = this.document.columns.find((c) => c.id === colId);\n const row = this.document.rows.find((r) => r.id === rowId);\n\n if (col && row && col.type === 'bound' && col.binding && row.recordId) {\n const boundVal = this.binder.resolveBoundValue(\n col.binding.dataSource,\n row.recordId,\n col.binding.field\n );\n return {\n raw: boundVal !== undefined ? String(boundVal) : '',\n value: boundVal ?? '',\n format: col.format\n };\n }\n\n // Check if column has a column-level formula\n if (col && col.type === 'formula' && col.formula) {\n return {\n raw: col.formula,\n value: '',\n format: col.format\n };\n }\n\n return { raw: '', value: '', format: col?.format };\n }\n\n public setCellValue(rowId: string, colId: string, raw: string): void {\n this.recordSnapshot();\n\n if (!this.document.cells[rowId]) {\n this.document.cells[rowId] = {};\n }\n\n const col = this.document.columns.find((c) => c.id === colId);\n const row = this.document.rows.find((r) => r.id === rowId);\n\n // If this is a bound column and row is bound to record, dispatch back to data source\n if (col?.type === 'bound' && col.binding && row?.recordId) {\n this.binder.commitBoundValue(\n col.binding.dataSource,\n row.recordId,\n col.binding.field,\n raw\n );\n }\n\n const cellKey = this.getCellKey(rowId, colId);\n this.depGraph.setCellFormula(cellKey, raw.startsWith('=') ? raw : null);\n\n this.document.cells[rowId][colId] = {\n raw,\n value: raw,\n format: col?.format\n };\n\n this.document.updatedAt = Date.now();\n this.recalculateCell(rowId, colId);\n this.notifyChange();\n\n const evaluatedVal = this.document.cells[rowId][colId]?.value;\n this.onCellCommit?.(rowId, colId, raw, evaluatedVal);\n }\n\n private getCellKey(rowId: string, colId: string): string {\n const row = this.document.rows.find((r) => r.id === rowId);\n const col = this.document.columns.find((c) => c.id === colId);\n if (!row || !col) return `${colId}_${rowId}`;\n return `${col.key}${row.index + 1}`.toUpperCase();\n }\n\n public recalculateCell(rowId: string, colId: string): void {\n const cellKey = this.getCellKey(rowId, colId);\n const { order, hasCycle } = this.depGraph.getEvaluationOrder(cellKey);\n\n if (hasCycle) {\n if (this.document.cells[rowId]?.[colId]) {\n this.document.cells[rowId][colId].error = '#CYCLE!';\n this.document.cells[rowId][colId].value = '#CYCLE!';\n }\n return;\n }\n\n for (const key of order) {\n this.evalSingleCellByKey(key);\n }\n }\n\n public recalculateAll(): void {\n for (const row of this.document.rows) {\n for (const col of this.document.columns) {\n const cell = this.getCell(row.id, col.id);\n const cellKey = `${col.key}${row.index + 1}`.toUpperCase();\n if (cell.raw.startsWith('=')) {\n this.depGraph.setCellFormula(cellKey, cell.raw);\n }\n }\n }\n\n for (const row of this.document.rows) {\n for (const col of this.document.columns) {\n const cellKey = `${col.key}${row.index + 1}`.toUpperCase();\n this.evalSingleCellByKey(cellKey);\n }\n }\n }\n\n private evalSingleCellByKey(cellKey: string): void {\n const match = cellKey.match(/^([A-Za-z]+)(\\d+)$/);\n if (!match) return;\n const colName = match[1].toUpperCase();\n const rowNum = parseInt(match[2], 10);\n\n const col = this.document.columns.find((c) => c.key.toUpperCase() === colName);\n const row = this.document.rows[rowNum - 1];\n if (!col || !row) return;\n\n const cell = this.getCell(row.id, col.id);\n if (!cell.raw.startsWith('=')) {\n if (cell.error === '#CYCLE!') {\n cell.error = undefined;\n }\n return;\n }\n\n try {\n const computed = this.evaluator.evaluate(cell.raw);\n if (!this.document.cells[row.id]) {\n this.document.cells[row.id] = {};\n }\n this.document.cells[row.id][col.id] = {\n ...cell,\n value: computed,\n error: undefined\n };\n } catch (err: any) {\n if (!this.document.cells[row.id]) {\n this.document.cells[row.id] = {};\n }\n this.document.cells[row.id][col.id] = {\n ...cell,\n value: '#ERROR!',\n error: err?.message || 'Formula error'\n };\n }\n }\n\n private resolveCellByCoord(colStr: string, rowNum: number): any {\n const col = this.document.columns.find((c) => c.key.toUpperCase() === colStr.toUpperCase());\n const row = this.document.rows[rowNum - 1];\n if (!col || !row) return 0;\n\n const cell = this.getCell(row.id, col.id);\n return cell.value !== undefined && cell.value !== '' ? cell.value : 0;\n }\n\n private resolveRangeByCoords(sCol: string, sRow: number, eCol: string, eRow: number): any[] {\n const startC = colNameToIndex(sCol);\n const endC = colNameToIndex(eCol);\n const minC = Math.min(startC, endC);\n const maxC = Math.max(startC, endC);\n const minR = Math.min(sRow, eRow);\n const maxR = Math.max(sRow, eRow);\n\n const results: any[] = [];\n for (let c = minC; c <= maxC; c++) {\n const colName = indexToColName(c);\n const col = this.document.columns.find((colDef) => colDef.key.toUpperCase() === colName);\n if (!col) continue;\n\n for (let r = minR; r <= maxR; r++) {\n const row = this.document.rows[r - 1];\n if (!row) continue;\n const cell = this.getCell(row.id, col.id);\n results.push(cell.value !== undefined && cell.value !== '' ? cell.value : 0);\n }\n }\n return results;\n }\n\n private resolveCurrentRowProperty(prop: string): any {\n if (!this.activeCell) return 0;\n const row = this.document.rows[this.activeCell.row];\n if (!row || !row.recordId || !this.primaryDataSourceId) return 0;\n return this.binder.resolveBoundValue(this.primaryDataSourceId, row.recordId, prop) ?? 0;\n }\n\n // --- Selection and Navigation ---\n\n public selectCell(row: number, col: number, extendSelection = false): void {\n const clampedRow = Math.max(0, Math.min(row, this.document.rows.length - 1));\n const clampedCol = Math.max(0, Math.min(col, this.document.columns.length - 1));\n\n const rowObj = this.document.rows[clampedRow];\n const colObj = this.document.columns[clampedCol];\n\n this.activeCell = {\n row: clampedRow,\n col: clampedCol,\n rowId: rowObj?.id,\n colId: colObj?.id\n };\n\n if (extendSelection && this.selectedRange) {\n this.selectedRange = {\n startRow: this.selectedRange.startRow,\n startCol: this.selectedRange.startCol,\n endRow: clampedRow,\n endCol: clampedCol\n };\n } else {\n this.selectedRange = {\n startRow: clampedRow,\n startCol: clampedCol,\n endRow: clampedRow,\n endCol: clampedCol\n };\n }\n\n this.onSelectionChange?.(this.activeCell, this.selectedRange);\n }\n\n public selectRange(range: CellRange): void {\n this.selectedRange = range;\n this.onSelectionChange?.(this.activeCell, this.selectedRange);\n }\n\n public startEditing(row?: number, col?: number, initialValue?: string): void {\n const targetRow = row ?? this.activeCell?.row ?? 0;\n const targetCol = col ?? this.activeCell?.col ?? 0;\n this.selectCell(targetRow, targetCol);\n\n const rowObj = this.document.rows[targetRow];\n const colObj = this.document.columns[targetCol];\n if (!rowObj || !colObj) return;\n\n this.editingCell = {\n row: targetRow,\n col: targetCol,\n rowId: rowObj.id,\n colId: colObj.id\n };\n\n const cell = this.getCell(rowObj.id, colObj.id);\n this.draftValue = initialValue !== undefined ? initialValue : cell.raw;\n }\n\n public commitEditing(valueToCommit?: string): void {\n if (!this.editingCell) return;\n const val = valueToCommit !== undefined ? valueToCommit : this.draftValue;\n if (this.editingCell.rowId && this.editingCell.colId) {\n this.setCellValue(this.editingCell.rowId, this.editingCell.colId, val);\n }\n this.editingCell = null;\n this.draftValue = '';\n }\n\n public cancelEditing(): void {\n this.editingCell = null;\n this.draftValue = '';\n }\n\n public moveCursor(\n direction: 'up' | 'down' | 'left' | 'right',\n extendSelection = false\n ): void {\n if (!this.activeCell) {\n this.selectCell(0, 0);\n return;\n }\n\n let nextRow = this.activeCell.row;\n let nextCol = this.activeCell.col;\n\n switch (direction) {\n case 'up':\n nextRow = Math.max(0, nextRow - 1);\n break;\n case 'down':\n nextRow = Math.min(this.document.rows.length - 1, nextRow + 1);\n break;\n case 'left':\n nextCol = Math.max(0, nextCol - 1);\n break;\n case 'right':\n nextCol = Math.min(this.document.columns.length - 1, nextCol + 1);\n break;\n }\n\n this.selectCell(nextRow, nextCol, extendSelection);\n }\n\n // --- Grid Structure Mutations ---\n\n public insertColumn(index: number, config?: Partial<SpreadsheetColumn>): void {\n this.recordSnapshot();\n const newId = config?.id || `col_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;\n const newCol: SpreadsheetColumn = {\n id: newId,\n key: indexToColName(index),\n title: config?.title || indexToColName(index),\n width: config?.width || 130,\n type: config?.type || 'freeform',\n binding: config?.binding,\n formula: config?.formula,\n format: config?.format || 'text',\n readOnly: config?.readOnly\n };\n\n this.document.columns.splice(index, 0, newCol);\n this.recomputeRowIndices();\n this.recalculateAll();\n this.notifyChange();\n }\n\n public deleteColumn(colId: string): void {\n this.recordSnapshot();\n this.document.columns = this.document.columns.filter((c) => c.id !== colId);\n for (const rowId of Object.keys(this.document.cells)) {\n delete this.document.cells[rowId][colId];\n }\n this.recomputeRowIndices();\n this.recalculateAll();\n this.notifyChange();\n }\n\n public insertRow(index: number, config?: Partial<SpreadsheetRow>): void {\n this.recordSnapshot();\n const newId = config?.id || `row_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;\n const newRow: SpreadsheetRow = {\n id: newId,\n index,\n height: config?.height || 32,\n recordId: config?.recordId,\n type: config?.type || 'freeform'\n };\n\n this.document.rows.splice(index, 0, newRow);\n this.recomputeRowIndices();\n this.recalculateAll();\n this.notifyChange();\n }\n\n public deleteRow(rowId: string): void {\n this.recordSnapshot();\n this.document.rows = this.document.rows.filter((r) => r.id !== rowId);\n delete this.document.cells[rowId];\n this.recomputeRowIndices();\n this.recalculateAll();\n this.notifyChange();\n }\n\n public setColumnWidth(colId: string, width: number): void {\n const col = this.document.columns.find((c) => c.id === colId);\n if (col) {\n col.width = Math.max(30, width);\n this.notifyChange();\n }\n }\n\n public autoFitColumnWidth(colId: string, customWidth?: number): void {\n if (customWidth !== undefined) {\n this.setColumnWidth(colId, customWidth);\n return;\n }\n const col = this.document.columns.find((c) => c.id === colId);\n if (!col) return;\n\n let maxLen = (col.title || '').length + (col.key ? col.key.length + 3 : 0);\n for (const row of this.document.rows) {\n const cell = this.getCell(row.id, col.id);\n const valStr = cell.value != null ? String(cell.value) : '';\n if (valStr.length > maxLen) {\n maxLen = valStr.length;\n }\n }\n const estimatedWidth = Math.min(600, Math.max(50, Math.ceil(maxLen * 8.5 + 32)));\n this.setColumnWidth(colId, estimatedWidth);\n }\n\n // --- Clipboard TSV/CSV ---\n\n public exportToTsv(): string {\n return this.document.rows\n .map((row) =>\n this.document.columns\n .map((col) => {\n const cell = this.getCell(row.id, col.id);\n return String(cell.value ?? '').replace(/\\t/g, ' ');\n })\n .join('\\t')\n )\n .join('\\n');\n }\n\n public importFromTsv(tsvData: string, startRow = 0, startCol = 0): void {\n this.recordSnapshot();\n const lines = tsvData.trim().split('\\n');\n\n lines.forEach((line, rIdx) => {\n const cells = line.split('\\t');\n const targetR = startRow + rIdx;\n\n while (targetR >= this.document.rows.length) {\n this.insertRow(this.document.rows.length);\n }\n const row = this.document.rows[targetR];\n\n cells.forEach((val, cIdx) => {\n const targetC = startCol + cIdx;\n while (targetC >= this.document.columns.length) {\n this.insertColumn(this.document.columns.length);\n }\n const col = this.document.columns[targetC];\n this.setCellValue(row.id, col.id, val);\n });\n });\n\n this.recalculateAll();\n this.notifyChange();\n }\n\n // --- Undo/Redo Snapshots ---\n\n private recordSnapshot(): void {\n if (this.isApplyingHistory) return;\n this.undoStack.push(JSON.stringify(this.document));\n if (this.undoStack.length > 50) this.undoStack.shift();\n this.redoStack = [];\n }\n\n public undo(): void {\n if (this.undoStack.length === 0) return;\n this.isApplyingHistory = true;\n this.redoStack.push(JSON.stringify(this.document));\n const previous = JSON.parse(this.undoStack.pop()!);\n this.document = previous;\n this.recalculateAll();\n this.notifyChange();\n this.isApplyingHistory = false;\n }\n\n public redo(): void {\n if (this.redoStack.length === 0) return;\n this.isApplyingHistory = true;\n this.undoStack.push(JSON.stringify(this.document));\n const next = JSON.parse(this.redoStack.pop()!);\n this.document = next;\n this.recalculateAll();\n this.notifyChange();\n this.isApplyingHistory = false;\n }\n\n private notifyChange(): void {\n this.onDocumentChange?.(this.document);\n }\n}\n","/**\n * Compares two values for structural equality.\n * Handles primitives, objects, arrays, and null/undefined.\n */\nexport function defaultIsEqual<T>(a: T, b: T): boolean {\n if (Object.is(a, b)) return true;\n if (\n typeof a !== \"object\" ||\n a === null ||\n typeof b !== \"object\" ||\n b === null\n ) {\n return false;\n }\n\n // Fast path for arrays\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!defaultIsEqual(a[i], b[i])) return false;\n }\n return true;\n }\n if (Array.isArray(a) !== Array.isArray(b)) {\n return false;\n }\n\n const keysA = Object.keys(a) as (keyof T)[];\n const keysB = Object.keys(b) as (keyof T)[];\n\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (!Object.prototype.hasOwnProperty.call(b, key)) return false;\n if (!defaultIsEqual(a[key], b[key])) return false;\n }\n\n return true;\n}\n\nexport interface DirtyTrackerOptions<T> {\n isEqual?: (a: T, b: T) => boolean;\n}\n\n/**\n * Tracks a baseline value and determines if the current state is dirty (modified).\n */\nexport class DirtyTracker<T = unknown> {\n private baseline: T;\n private readonly isEqual: (a: T, b: T) => boolean;\n\n constructor(\n initialBaseline: T,\n options?: DirtyTrackerOptions<T> | ((a: T, b: T) => boolean),\n ) {\n this.baseline = initialBaseline;\n if (typeof options === \"function\") {\n this.isEqual = options;\n } else {\n this.isEqual = options?.isEqual ?? defaultIsEqual;\n }\n }\n\n /**\n * Returns current baseline value.\n */\n public getBaseline(): T {\n return this.baseline;\n }\n\n /**\n * Sets a new baseline value without triggering any dirty state.\n */\n public setBaseline(value: T): void {\n this.baseline = value;\n }\n\n /**\n * Checks whether the given value differs from the baseline.\n */\n public isDirty(current: T): boolean {\n return !this.isEqual(this.baseline, current);\n }\n\n /**\n * Resets the baseline to the provided current value (or clears dirty status).\n */\n public reset(current: T): void {\n this.baseline = current;\n }\n}\n\n/**\n * Creates a DirtyTracker instance.\n */\nexport function createDirtyTracker<T>(\n initialBaseline: T,\n options?: DirtyTrackerOptions<T> | ((a: T, b: T) => boolean),\n): DirtyTracker<T> {\n return new DirtyTracker(initialBaseline, options);\n}\n","import {\n Command,\n HistoryManagerOptions,\n HistoryState,\n MergedExecutionOptions,\n SnapshotCommandOptions,\n} from \"./types\";\n\n/**\n * UI-agnostic History and Undo/Redo manager supporting command closures,\n * snapshot diffs, transaction batching, and high-frequency event coalescing.\n */\nexport class HistoryManager {\n private undoStack: Command[] = [];\n private redoStack: Command[] = [];\n private readonly maxDepth: number;\n private isApplying = false;\n private batchDepth = 0;\n private currentBatch: Command[] | null = null;\n private listeners: Set<(state: HistoryState) => void> = new Set();\n private onStateChange?: (state: HistoryState) => void;\n private cachedState: HistoryState;\n\n constructor(options: HistoryManagerOptions = {}) {\n this.maxDepth = options.maxDepth ?? 50;\n this.onStateChange = options.onStateChange;\n this.cachedState = this.computeState();\n }\n\n private computeState(): HistoryState {\n const canUndo = this.undoStack.length > 0;\n const canRedo = this.redoStack.length > 0;\n return {\n canUndo,\n canRedo,\n undoName: canUndo ? this.undoStack[this.undoStack.length - 1].name : \"\",\n redoName: canRedo ? this.redoStack[this.redoStack.length - 1].name : \"\",\n undoCount: this.undoStack.length,\n redoCount: this.redoStack.length,\n };\n }\n\n /**\n * Returns a snapshot of the current history state.\n * Cached to maintain referential equality across renders for useSyncExternalStore.\n */\n public getState(): HistoryState {\n return this.cachedState;\n }\n\n private notify(): void {\n this.cachedState = this.computeState();\n const state = this.cachedState;\n this.onStateChange?.(state);\n this.listeners.forEach((listener) => {\n try {\n listener(state);\n } catch (err) {\n console.error(\"[HistoryManager] Error in state listener:\", err);\n }\n });\n }\n\n /**\n * Executes a command and pushes it onto the undo stack.\n * Clears the redo stack.\n */\n public execute(command: Command): void {\n if (this.isApplying) {\n command.execute();\n return;\n }\n\n if (this.batchDepth > 0 && this.currentBatch) {\n command.execute();\n this.currentBatch.push({\n ...command,\n timestamp: command.timestamp ?? Date.now(),\n });\n return;\n }\n\n command.execute();\n\n this.undoStack.push({\n ...command,\n timestamp: command.timestamp ?? Date.now(),\n });\n\n if (this.undoStack.length > this.maxDepth) {\n this.undoStack.shift();\n }\n\n this.redoStack = [];\n this.notify();\n }\n\n /**\n * Executes a command, coalescing it with the previous command if they share\n * the same `tag` and occurred within `windowMs` (default: 300ms).\n * Useful for high-frequency interactions like slider scrubs or node drags.\n */\n public executeMerged(\n command: Command,\n options: MergedExecutionOptions = {},\n ): void {\n const windowMs = options.windowMs ?? 300;\n const now = Date.now();\n\n if (\n command.tag &&\n this.undoStack.length > 0 &&\n this.batchDepth === 0 &&\n !this.isApplying\n ) {\n const top = this.undoStack[this.undoStack.length - 1];\n const elapsed = top.timestamp ? now - top.timestamp : Infinity;\n\n if (top.tag === command.tag && elapsed <= windowMs) {\n command.execute();\n // Replace top with merged command keeping the original initial undo\n const initialUndo = top.undo;\n this.undoStack[this.undoStack.length - 1] = {\n name: command.name,\n tag: command.tag,\n timestamp: now,\n execute: command.execute,\n undo: initialUndo,\n redo: command.redo ?? command.execute,\n };\n this.redoStack = [];\n this.notify();\n return;\n }\n }\n\n this.execute({ ...command, timestamp: now });\n }\n\n /**\n * Batches multiple commands executed within `fn` into a single atomic undo entry.\n */\n public batch(name: string, fn: () => void): void {\n if (this.isApplying) {\n fn();\n return;\n }\n\n if (this.batchDepth > 0) {\n // Already inside a batch; execute directly\n fn();\n return;\n }\n\n this.batchDepth++;\n this.currentBatch = [];\n\n try {\n fn();\n } finally {\n this.batchDepth--;\n const batchCommands = this.currentBatch;\n this.currentBatch = null;\n\n if (batchCommands && batchCommands.length > 0) {\n const compoundCommand: Command = {\n name,\n timestamp: Date.now(),\n execute: () => {\n for (let i = 0; i < batchCommands.length; i++) {\n (batchCommands[i].redo ?? batchCommands[i].execute)();\n }\n },\n undo: () => {\n for (let i = batchCommands.length - 1; i >= 0; i--) {\n batchCommands[i].undo();\n }\n },\n redo: () => {\n for (let i = 0; i < batchCommands.length; i++) {\n (batchCommands[i].redo ?? batchCommands[i].execute)();\n }\n },\n };\n\n this.undoStack.push(compoundCommand);\n if (this.undoStack.length > this.maxDepth) {\n this.undoStack.shift();\n }\n this.redoStack = [];\n this.notify();\n }\n }\n }\n\n /**\n * Reverts the most recent command on the undo stack.\n * Returns true if a command was undone, false otherwise.\n */\n public undo(): boolean {\n if (this.undoStack.length === 0 || this.isApplying || this.batchDepth > 0) {\n return false;\n }\n\n this.isApplying = true;\n try {\n const command = this.undoStack.pop()!;\n command.undo();\n this.redoStack.push(command);\n return true;\n } finally {\n this.isApplying = false;\n this.notify();\n }\n }\n\n /**\n * Re-applies the most recent undone command on the redo stack.\n * Returns true if a command was redone, false otherwise.\n */\n public redo(): boolean {\n if (this.redoStack.length === 0 || this.isApplying || this.batchDepth > 0) {\n return false;\n }\n\n this.isApplying = true;\n try {\n const command = this.redoStack.pop()!;\n (command.redo ?? command.execute)();\n this.undoStack.push(command);\n return true;\n } finally {\n this.isApplying = false;\n this.notify();\n }\n }\n\n /**\n * Clears both undo and redo stacks.\n */\n public clear(): void {\n this.undoStack = [];\n this.redoStack = [];\n this.notify();\n }\n\n /**\n * Subscribes to history state changes.\n * The listener is immediately invoked with the current state.\n * Returns an unsubscribe function.\n */\n public subscribe(listener: (state: HistoryState) => void): () => void {\n this.listeners.add(listener);\n listener(this.getState());\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n /**\n * Utility helper to create a Command from before/after state snapshots.\n */\n public static createSnapshotCommand<T>(\n options: SnapshotCommandOptions<T>,\n ): Command {\n return {\n name: options.name,\n tag: options.tag,\n execute: () => options.apply(options.after),\n undo: () => options.apply(options.before),\n redo: () => options.apply(options.after),\n };\n }\n}\n\n/**\n * Creates and initializes a new HistoryManager instance.\n */\nexport function createHistoryManager(\n options: HistoryManagerOptions = {},\n): HistoryManager {\n return new HistoryManager(options);\n}\n","import dagre from '@dagrejs/dagre';\nimport type {\n\tCanvasEdge,\n\tCanvasLayoutOptions,\n\tCanvasNode,\n\tIncrementalLayoutOptions,\n\tPlaceBesideOptions,\n\tRect,\n\tSide,\n\tXYPosition\n} from './types.js';\n\nexport const DEFAULT_NODE_WIDTH = 200;\nexport const DEFAULT_NODE_HEIGHT = 60;\nexport const DEFAULT_PLACEMENT_GAP = 48;\n\n/**\n * Calculates upper-left flow coordinate for an element to be centered in the viewport.\n */\nexport function getCenteredNodePosition(\n\twidth = 0,\n\theight = 0,\n\tscreenToFlowPosition: (position: XYPosition) => XYPosition,\n\tscreenDimensions?: { width: number; height: number }\n): XYPosition {\n\tconst rect =\n\t\tscreenDimensions ??\n\t\t(typeof document !== 'undefined'\n\t\t\t? { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight }\n\t\t\t: { width: 1920, height: 1080 });\n\n\tconst flowPos = screenToFlowPosition({ x: rect.width / 2, y: rect.height / 2 });\n\treturn {\n\t\tx: flowPos.x - width / 2,\n\t\ty: flowPos.y - height / 2\n\t};\n}\n\n/**\n * Updates positions of nodes so their collective bounding box is centered in the current viewport.\n */\nexport function centerNodes<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[],\n\tscreenToFlowPosition: (position: XYPosition) => XYPosition,\n\tgetNodesBounds: (nodes: TNode[]) => Rect,\n\tscreenDimensions?: { width: number; height: number }\n): TNode[] {\n\tif (nodes.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst bounds = getNodesBounds(nodes);\n\tconst boundingBoxOrigin = { x: bounds.x, y: bounds.y };\n\n\tconst centeredPosition = getCenteredNodePosition(\n\t\tbounds.width,\n\t\tbounds.height,\n\t\tscreenToFlowPosition,\n\t\tscreenDimensions\n\t);\n\n\tconst deltaX = centeredPosition.x - boundingBoxOrigin.x;\n\tconst deltaY = centeredPosition.y - boundingBoxOrigin.y;\n\n\treturn nodes.map((node) => ({\n\t\t...node,\n\t\tposition: {\n\t\t\tx: node.position.x + deltaX,\n\t\t\ty: node.position.y + deltaY\n\t\t}\n\t}));\n}\n\n/**\n * Automatically calculates directed hierarchical layout of nodes and edges using Dagre.\n */\nexport function getLayoutedNodes<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[],\n\tgetNodesBounds?: (nodes: TNode[]) => Rect,\n\toptions: CanvasLayoutOptions = {}\n): TNode[] {\n\tif (nodes.length === 0) return [];\n\n\tconst {\n\t\tdirection = 'LR',\n\t\tranksep = 100,\n\t\tnodesep = 25,\n\t\tdefaultNodeWidth = DEFAULT_NODE_WIDTH,\n\t\tdefaultNodeHeight = DEFAULT_NODE_HEIGHT\n\t} = options;\n\n\tconst dagreGraph = new dagre.graphlib.Graph();\n\tdagreGraph.setDefaultEdgeLabel(() => ({}));\n\tdagreGraph.setGraph({ rankdir: direction, ranksep, nodesep });\n\n\tconst nodeIds = new Set(nodes.map((node) => node.id));\n\n\tnodes.forEach((node) => {\n\t\tconst nodeWidth = node.measured?.width ?? (node as any).width ?? defaultNodeWidth;\n\t\tconst nodeHeight = node.measured?.height ?? (node as any).height ?? defaultNodeHeight;\n\t\tdagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight });\n\t});\n\n\tedges.forEach((edge) => {\n\t\tif (nodeIds.has(edge.source) && nodeIds.has(edge.target)) {\n\t\t\tdagreGraph.setEdge(edge.source, edge.target);\n\t\t}\n\t});\n\n\tdagre.layout(dagreGraph);\n\n\treturn nodes.map((node) => {\n\t\tconst nodeWithPosition = dagreGraph.node(node.id);\n\t\tconst nodeWidth = node.measured?.width ?? (node as any).width ?? defaultNodeWidth;\n\t\tconst nodeHeight = node.measured?.height ?? (node as any).height ?? defaultNodeHeight;\n\n\t\treturn {\n\t\t\t...node,\n\t\t\tposition: {\n\t\t\t\tx: nodeWithPosition.x - nodeWidth / 2,\n\t\t\t\ty: nodeWithPosition.y - nodeHeight / 2\n\t\t\t}\n\t\t};\n\t});\n}\n\n/**\n * Heuristic text-based node size estimator when DOM measurement is not available.\n */\nexport function estimateNodeSize(\n\tnode: CanvasNode,\n\tdefaultWidth = DEFAULT_NODE_WIDTH,\n\tdefaultHeight = DEFAULT_NODE_HEIGHT\n): { width: number; height: number } {\n\tconst label = String(node.data?.label ?? node.data?.title ?? node.id ?? '');\n\tconst lines = label.split(/\\n|<br\\s*\\/?>/);\n\tconst longest = Math.max(...lines.map((l) => l.replace(/<[^>]+>/g, '').length), 1);\n\tconst width = Math.min(480, Math.max(defaultWidth, longest * 8 + 48));\n\tconst height = Math.max(defaultHeight, lines.length * 20 + 24);\n\treturn { width, height };\n}\n\n/**\n * Computes bounding rectangle of an array of rectangles.\n */\nexport function boundsOf(rects: Rect[]): Rect | null {\n\tif (!rects.length) return null;\n\tconst minX = Math.min(...rects.map((r) => r.x));\n\tconst minY = Math.min(...rects.map((r) => r.y));\n\tconst maxX = Math.max(...rects.map((r) => r.x + r.width));\n\tconst maxY = Math.max(...rects.map((r) => r.y + r.height));\n\treturn { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\n/**\n * Center coordinate of a rectangle.\n */\nexport function centre(r: Rect): XYPosition {\n\treturn { x: r.x + r.width / 2, y: r.y + r.height / 2 };\n}\n\n/**\n * Determines whether two rectangles overlap, including an optional padding distance.\n */\nexport function overlaps(a: Rect, b: Rect, pad = 16): boolean {\n\treturn (\n\t\ta.x < b.x + b.width + pad &&\n\t\ta.x + a.width + pad > b.x &&\n\t\ta.y < b.y + b.height + pad &&\n\t\ta.y + a.height + pad > b.y\n\t);\n}\n\n/**\n * Maps directed layout flow to its natural forward growth side.\n */\nexport function flowSide(direction: 'LR' | 'TB' | 'RL' | 'BT' = 'LR'): Side {\n\tswitch (direction) {\n\t\tcase 'LR':\n\t\t\treturn 'right';\n\t\tcase 'RL':\n\t\t\treturn 'left';\n\t\tcase 'BT':\n\t\t\treturn 'above';\n\t\tcase 'TB':\n\t\tdefault:\n\t\t\treturn 'below';\n\t}\n}\n\n/**\n * Incremental layout blending:\n * Keeps established/manual node positions intact. Runs Dagre on the entire graph,\n * computes the centroid translation offset between auto and stored positions of existing nodes,\n * and places unpositioned/new nodes at (auto + offset).\n */\nexport function ensureLayout<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[],\n\toptions: IncrementalLayoutOptions = {}\n): TNode[] {\n\tif (nodes.length === 0) return [];\n\n\tconst stored = options.storedPositions ?? {};\n\tconst missing = nodes.filter((n) => !stored[n.id]);\n\n\t// Case 1: Every node has an established coordinate -> preserve verbatim\n\tif (missing.length === 0) {\n\t\treturn nodes.map((n) => ({\n\t\t\t...n,\n\t\t\tposition: { ...stored[n.id]! }\n\t\t}));\n\t}\n\n\t// Calculate full dagre auto-layout\n\tconst autoLayouted = getLayoutedNodes(nodes, edges, undefined, options);\n\tconst autoMap = new Map<string, XYPosition>(\n\t\tautoLayouted.map((n) => [n.id, n.position])\n\t);\n\n\t// Case 2: No nodes have stored coordinates -> return auto layout directly\n\tconst both = nodes.filter((n) => stored[n.id] && autoMap.has(n.id));\n\tif (both.length === 0) {\n\t\treturn autoLayouted;\n\t}\n\n\t// Case 3: Blend! Align on centroid translation offset of overlapping nodes\n\tlet dx = 0;\n\tlet dy = 0;\n\tfor (const n of both) {\n\t\tconst s = stored[n.id]!;\n\t\tconst a = autoMap.get(n.id)!;\n\t\tdx += s.x - a.x;\n\t\tdy += s.y - a.y;\n\t}\n\tdx /= both.length;\n\tdy /= both.length;\n\n\treturn nodes.map((node) => {\n\t\tif (stored[node.id]) {\n\t\t\treturn {\n\t\t\t\t...node,\n\t\t\t\tposition: { ...stored[node.id]! }\n\t\t\t};\n\t\t}\n\t\tconst autoPos = autoMap.get(node.id) ?? { x: 0, y: 0 };\n\t\treturn {\n\t\t\t...node,\n\t\t\tposition: {\n\t\t\t\tx: Math.round(autoPos.x + dx),\n\t\t\t\ty: Math.round(autoPos.y + dy)\n\t\t\t}\n\t\t};\n\t});\n}\n\n/**\n * Finds a free top-left coordinate for a node of `size` adjacent to `nearNodeId` (or the cluster),\n * sliding along the perpendicular axis past any intersecting bounding boxes to guarantee non-overlapping placement.\n */\nexport function placeBeside(\n\trects: Record<string, Rect>,\n\tsize: { width: number; height: number },\n\tside: Side,\n\tnearNodeId?: string,\n\toptions: PlaceBesideOptions = {}\n): XYPosition {\n\tconst {\n\t\tgap = DEFAULT_PLACEMENT_GAP,\n\t\tignore = [],\n\t\tmaxAttempts = 32\n\t} = options;\n\n\tconst skip = new Set([nearNodeId, ...ignore].filter(Boolean));\n\tconst obstacles = Object.entries(rects)\n\t\t.filter(([id]) => !skip.has(id))\n\t\t.map(([, r]) => r);\n\n\tconst anchor =\n\t\t(nearNodeId && rects[nearNodeId]) ||\n\t\tboundsOf(Object.values(rects)) ||\n\t\t{ x: 0, y: 0, width: 0, height: 0 };\n\n\tconst anchorCenter = centre(anchor);\n\n\tlet baseX: number;\n\tlet baseY: number;\n\n\tswitch (side) {\n\t\tcase 'right':\n\t\t\tbaseX = anchor.x + anchor.width + gap;\n\t\t\tbaseY = anchorCenter.y - size.height / 2;\n\t\t\tbreak;\n\t\tcase 'left':\n\t\t\tbaseX = anchor.x - gap - size.width;\n\t\t\tbaseY = anchorCenter.y - size.height / 2;\n\t\t\tbreak;\n\t\tcase 'above':\n\t\t\tbaseX = anchorCenter.x - size.width / 2;\n\t\t\tbaseY = anchor.y - gap - size.height;\n\t\t\tbreak;\n\t\tcase 'below':\n\t\tdefault:\n\t\t\tbaseX = anchorCenter.x - size.width / 2;\n\t\t\tbaseY = anchor.y + anchor.height + gap;\n\t\t\tbreak;\n\t}\n\n\t// Slide perpendicular to growth direction, alternating positive and negative steps (+1, -1, +2, -2...)\n\tconst isHorizontal = side === 'right' || side === 'left';\n\tconst step = (isHorizontal ? size.height : size.width) + 20;\n\n\tfor (let i = 0; i < maxAttempts; i++) {\n\t\tconst offset = i === 0 ? 0 : Math.ceil(i / 2) * step * (i % 2 === 1 ? 1 : -1);\n\t\tconst candidateBox: Rect = {\n\t\t\tx: isHorizontal ? baseX : baseX + offset,\n\t\t\ty: isHorizontal ? baseY + offset : baseY,\n\t\t\twidth: size.width,\n\t\t\theight: size.height\n\t\t};\n\n\t\tif (!obstacles.some((obstacle) => overlaps(candidateBox, obstacle, 8))) {\n\t\t\treturn {\n\t\t\t\tx: Math.round(candidateBox.x),\n\t\t\t\ty: Math.round(candidateBox.y)\n\t\t\t};\n\t\t}\n\t}\n\n\treturn {\n\t\tx: Math.round(baseX),\n\t\ty: Math.round(baseY)\n\t};\n}\n","/**\n * The time source that canvas animations and agent performances play on.\n *\n * Defaults to `realClock` (requestAnimationFrame and setTimeout).\n * A `ManualClock` moves only when told to via `advance(ms)` or `tick(fps)`,\n * enabling deterministic frame-by-frame stepping for testing, video generation,\n * or headless server environments.\n */\n\nexport interface Clock {\n\t/** Current time in milliseconds. */\n\tnow(): number;\n\t/** Resolves on the next animation frame. */\n\tframe(): Promise<void>;\n\t/** Resolves after `ms` milliseconds of this clock's time. */\n\tsleep(ms: number): Promise<void>;\n\t/**\n\t * Whether the clock follows wall time. Live clocks stop or degrade when the\n\t * tab is in the background (browsers pause animation frames), so transitions\n\t * can commit immediately rather than leaving operations hanging.\n\t */\n\treadonly live: boolean;\n}\n\n/** Whether the browser tab is hidden (where RAF pauses). */\nexport const pageHidden = (): boolean =>\n\ttypeof document !== 'undefined' && document.hidden;\n\n/** Real-time clock using requestAnimationFrame and setTimeout. */\nexport const realClock: Clock = {\n\tlive: true,\n\tnow: () => (typeof performance !== 'undefined' ? performance.now() : Date.now()),\n\tframe: () =>\n\t\tnew Promise<void>((resolve) => {\n\t\t\tif (typeof requestAnimationFrame === 'function' && !pageHidden()) {\n\t\t\t\trequestAnimationFrame(() => resolve());\n\t\t\t} else {\n\t\t\t\tsetTimeout(resolve, 16);\n\t\t\t}\n\t\t}),\n\tsleep: (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, Math.max(0, ms)))\n};\n\nconst settle = () => new Promise<void>((resolve) => setTimeout(resolve, 0));\n\n/**\n * A deterministic clock that only moves forward when `advance` or `tick` is called.\n * Allows step-by-step frame testing and video rendering without waiting for real time.\n */\nexport class ManualClock implements Clock {\n\treadonly live = false;\n\tprivate time: number;\n\tprivate frames: (() => void)[] = [];\n\tprivate sleepers: { at: number; seq: number; resolve: () => void }[] = [];\n\tprivate seq = 0;\n\n\tconstructor(start = 0) {\n\t\tthis.time = start;\n\t}\n\n\tpublic now(): number {\n\t\treturn this.time;\n\t}\n\n\tpublic frame(): Promise<void> {\n\t\treturn new Promise<void>((resolve) => this.frames.push(resolve));\n\t}\n\n\tpublic sleep(ms: number): Promise<void> {\n\t\treturn new Promise<void>((resolve) =>\n\t\t\tthis.sleepers.push({\n\t\t\t\tat: this.time + Math.max(0, ms),\n\t\t\t\tseq: this.seq++,\n\t\t\t\tresolve\n\t\t\t})\n\t\t);\n\t}\n\n\t/** Whether any frames or sleep timers are currently pending. */\n\tpublic get pending(): boolean {\n\t\treturn this.frames.length > 0 || this.sleepers.length > 0;\n\t}\n\n\t/** Advances time by `ms`, resolving due sleep timers in order, followed by queued frames. */\n\tpublic async advance(ms: number): Promise<void> {\n\t\tconst end = this.time + Math.max(0, ms);\n\t\tawait settle();\n\n\t\twhile (true) {\n\t\t\tlet next: (typeof this.sleepers)[number] | undefined;\n\t\t\tfor (const s of this.sleepers) {\n\t\t\t\tif (s.at <= end && (!next || s.at < next.at || (s.at === next.at && s.seq < next.seq))) {\n\t\t\t\t\tnext = s;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!next) break;\n\n\t\t\tthis.sleepers.splice(this.sleepers.indexOf(next), 1);\n\t\t\tthis.time = Math.max(this.time, next.at);\n\t\t\tnext.resolve();\n\t\t\tawait settle();\n\t\t}\n\n\t\tthis.time = end;\n\t\tconst dueFrames = this.frames.splice(0, this.frames.length);\n\t\tfor (const resolveFrame of dueFrames) {\n\t\t\tresolveFrame();\n\t\t}\n\t\tawait settle();\n\t}\n\n\t/** Convenience method to advance by 1 frame at a given fps (default: 60fps = 16.67ms). */\n\tpublic async tick(fps = 60): Promise<void> {\n\t\tawait this.advance(Math.round(1000 / fps));\n\t}\n}\n","import type {\n\tCanvasNode,\n\tFanOutTrajectoryOptions,\n\tNodeTransition,\n\tTrajectoryFunction,\n\tTrajectoryPoint,\n\tXYPosition\n} from './types.js';\n\n/**\n * Standard cubic ease-out function (pure math, framework-agnostic).\n */\nexport const defaultEasing = (t: number): number => --t * t * t + 1;\n\n/**\n * Standard linear trajectory: straight line interpolation with linear scale & opacity progression.\n */\nexport const linearTrajectory: TrajectoryFunction = (\n\torigin: XYPosition,\n\ttarget: XYPosition,\n\tprogress: number\n): TrajectoryPoint => {\n\treturn {\n\t\tposition: {\n\t\t\tx: origin.x + (target.x - origin.x) * progress,\n\t\t\ty: origin.y + (target.y - origin.y) * progress\n\t\t},\n\t\tscale: progress,\n\t\topacity: Math.min(1, progress * 1.5)\n\t};\n};\n\n/**\n * Linear position trajectory: pure position interpolation without altering scale or opacity.\n */\nexport const linearPositionTrajectory: TrajectoryFunction = (\n\torigin: XYPosition,\n\ttarget: XYPosition,\n\tprogress: number\n): TrajectoryPoint => {\n\treturn {\n\t\tposition: {\n\t\t\tx: origin.x + (target.x - origin.x) * progress,\n\t\t\ty: origin.y + (target.y - origin.y) * progress\n\t\t}\n\t};\n};\n\n/**\n * Creates a fan-out trajectory where nodes arc outward from origin to target.\n */\nexport function createFanOutTrajectory(options: FanOutTrajectoryOptions = {}): TrajectoryFunction {\n\tconst {\n\t\tcurvature = 0.4,\n\t\tstartScale = 0,\n\t\tendScale = 1,\n\t\tstartOpacity = 0,\n\t\tendOpacity = 1\n\t} = options;\n\n\treturn (\n\t\torigin: XYPosition,\n\t\ttarget: XYPosition,\n\t\tprogress: number,\n\t\tindex: number,\n\t\ttotal: number\n\t): TrajectoryPoint => {\n\t\tconst dx = target.x - origin.x;\n\t\tconst dy = target.y - origin.y;\n\n\t\t// Normalized index from -1 (top) to +1 (bottom)\n\t\tconst normIndex = total > 1 ? (index - (total - 1) / 2) / ((total - 1) / 2) : 0;\n\n\t\t// Perpendicular control point offset to create smooth fan arc\n\t\tconst midX = origin.x + dx * 0.4;\n\t\tconst midY = origin.y + dy * 0.1 - normIndex * Math.abs(dx) * 0.15 * curvature;\n\n\t\t// Quadratic Bezier interpolation: B(t) = (1-t)^2 * P0 + 2(1-t)t * P1 + t^2 * P2\n\t\tconst t = progress;\n\t\tconst oneMinusT = 1 - t;\n\n\t\tconst x = oneMinusT * oneMinusT * origin.x + 2 * oneMinusT * t * midX + t * t * target.x;\n\t\tconst y = oneMinusT * oneMinusT * origin.y + 2 * oneMinusT * t * midY + t * t * target.y;\n\n\t\tconst scale = startScale + (endScale - startScale) * progress;\n\t\tconst opacity = startOpacity + (endOpacity - startOpacity) * progress;\n\n\t\treturn {\n\t\t\tposition: { x, y },\n\t\t\tscale,\n\t\t\topacity\n\t\t};\n\t};\n}\n\n/**\n * Creates a custom quadratic Bezier trajectory with a specified control point resolver.\n */\nexport function createBezierTrajectory(\n\tgetControlPoint: (origin: XYPosition, target: XYPosition) => XYPosition\n): TrajectoryFunction {\n\treturn (origin: XYPosition, target: XYPosition, progress: number): TrajectoryPoint => {\n\t\tconst cp = getControlPoint(origin, target);\n\t\tconst t = progress;\n\t\tconst oneMinusT = 1 - t;\n\n\t\tconst x = oneMinusT * oneMinusT * origin.x + 2 * oneMinusT * t * cp.x + t * t * target.x;\n\t\tconst y = oneMinusT * oneMinusT * origin.y + 2 * oneMinusT * t * cp.y + t * t * target.y;\n\n\t\treturn {\n\t\t\tposition: { x, y },\n\t\t\tscale: progress,\n\t\t\topacity: progress\n\t\t};\n\t};\n}\n\nimport { realClock, type Clock } from './clock.js';\n\n/**\n * Coordinates and animates multiple node transitions simultaneously with zero per-frame array allocations.\n */\nexport function runMultiNodeTransition<TNode extends CanvasNode = CanvasNode>(\n\ttransitions: NodeTransition<TNode>[],\n\toptions: {\n\t\tdefaultDuration?: number;\n\t\tdefaultEasing?: (t: number) => number;\n\t\tclock?: Clock;\n\t\tonUpdate?: () => void;\n\t\tonComplete?: () => void;\n\t} = {}\n): () => void {\n\tif (transitions.length === 0) {\n\t\toptions.onComplete?.();\n\t\treturn () => {};\n\t}\n\n\tconst {\n\t\tdefaultDuration = 400,\n\t\tdefaultEasing: easingFunc = defaultEasing,\n\t\tclock = realClock,\n\t\tonUpdate,\n\t\tonComplete\n\t} = options;\n\n\tlet isCancelled = false;\n\tconst startTime = clock.now();\n\n\tconst items = transitions.map((tr, i) => ({\n\t\t...tr,\n\t\tindex: tr.index ?? i,\n\t\ttotal: tr.total ?? transitions.length,\n\t\tduration: tr.duration ?? defaultDuration,\n\t\teasing: tr.easing ?? easingFunc,\n\t\tdelay: tr.delay ?? 0,\n\t\ttrajectory: tr.trajectory ?? linearTrajectory\n\t}));\n\n\tfunction frame() {\n\t\tif (isCancelled) return;\n\n\t\tconst now = clock.now();\n\t\tlet allCompleted = true;\n\n\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\tconst item = items[i];\n\t\t\tconst elapsed = now - (startTime + item.delay);\n\n\t\t\tif (elapsed < 0) {\n\t\t\t\tallCompleted = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Guard zero duration and division by zero (referenced in GOTCHAS.md)\n\t\t\tconst rawProgress = item.duration <= 0 ? 1 : Math.min(elapsed / item.duration, 1);\n\t\t\tconst progress = item.duration <= 0 ? 1 : item.easing(rawProgress);\n\n\t\t\tconst point = item.trajectory(item.from, item.to, progress, item.index, item.total);\n\n\t\t\titem.node.position = { ...point.position };\n\n\t\t\tif (point.scale !== undefined || point.opacity !== undefined) {\n\t\t\t\tif (!item.node.data) {\n\t\t\t\t\titem.node.data = {} as any;\n\t\t\t\t}\n\t\t\t\tif (point.scale !== undefined) {\n\t\t\t\t\t(item.node.data as any).scale = point.scale;\n\t\t\t\t}\n\t\t\t\tif (point.opacity !== undefined) {\n\t\t\t\t\t(item.node.data as any).opacity = point.opacity;\n\t\t\t\t\tconst currentStyle = (item.node.style || '').replace(/opacity:\\s*[^;]+;?/g, '').trim();\n\t\t\t\t\titem.node.style = `${currentStyle ? currentStyle + '; ' : ''}opacity: ${point.opacity};`;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rawProgress < 1) {\n\t\t\t\tallCompleted = false;\n\t\t\t}\n\t\t}\n\n\t\tonUpdate?.();\n\n\t\tif (!allCompleted) {\n\t\t\tclock.frame().then(frame);\n\t\t} else {\n\t\t\tonComplete?.();\n\t\t}\n\t}\n\n\tframe();\n\n\treturn () => {\n\t\tisCancelled = true;\n\t};\n}\n","import dagre from '@dagrejs/dagre';\nimport type {\n\tCanvasEdge,\n\tCanvasNode,\n\tDirectionalDisplacementOptions,\n\tRect,\n\tReflowDisplacementOptions,\n\tXYPosition\n} from './types.js';\n\n/**\n * Calculates a bounding rectangle for a set of nodes if not provided by getNodesBounds.\n */\nexport function computeNodesBoundingBox<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[],\n\tdefaultWidth = 200,\n\tdefaultHeight = 60\n): Rect {\n\tif (nodes.length === 0) {\n\t\treturn { x: 0, y: 0, width: 0, height: 0 };\n\t}\n\n\tlet minX = Infinity;\n\tlet minY = Infinity;\n\tlet maxX = -Infinity;\n\tlet maxY = -Infinity;\n\n\tfor (const node of nodes) {\n\t\tconst width = node.measured?.width ?? (node as any).width ?? defaultWidth;\n\t\tconst height = node.measured?.height ?? (node as any).height ?? defaultHeight;\n\n\t\tminX = Math.min(minX, node.position.x);\n\t\tminY = Math.min(minY, node.position.y);\n\t\tmaxX = Math.max(maxX, node.position.x + width);\n\t\tmaxY = Math.max(maxY, node.position.y + height);\n\t}\n\n\treturn {\n\t\tx: minX,\n\t\ty: minY,\n\t\twidth: maxX - minX,\n\t\theight: maxY - minY\n\t};\n}\n\n/**\n * Pure directional displacement calculation.\n * Shifts downstream or surrounding nodes along an axis to clear space for newly inserted child nodes.\n */\nexport function calculateDirectionalDisplacement<TNode extends CanvasNode = CanvasNode>(params: {\n\texistingNodes: TNode[];\n\toriginNode: TNode;\n\tchildNodes: TNode[];\n\tgetNodesBounds?: (nodes: TNode[]) => Rect;\n\toptions?: DirectionalDisplacementOptions;\n}): Map<string, XYPosition> {\n\tconst {\n\t\texistingNodes,\n\t\toriginNode,\n\t\tchildNodes,\n\t\tgetNodesBounds,\n\t\toptions = {}\n\t} = params;\n\n\tconst {\n\t\tdirection = 'right',\n\t\tgap = 40,\n\t\tspreadSiblingLanes = false,\n\t\tsiblingTolerance = 50,\n\t\tminY\n\t} = options;\n\n\tconst displacedMap = new Map<string, XYPosition>();\n\tif (childNodes.length === 0 || existingNodes.length === 0) {\n\t\treturn displacedMap;\n\t}\n\n\tconst childBounds = getNodesBounds\n\t\t? getNodesBounds(childNodes)\n\t\t: computeNodesBoundingBox(childNodes);\n\n\tconst originWidth = originNode.measured?.width ?? (originNode as any).width ?? 200;\n\tconst originHeight = originNode.measured?.height ?? (originNode as any).height ?? 60;\n\n\t// The delta space required along primary axis\n\tconst deltaPrimary =\n\t\tdirection === 'right' || direction === 'left'\n\t\t\t? childBounds.width + gap\n\t\t\t: childBounds.height + gap;\n\n\t// Vertical displacement parameters: upward and downward row clearance\n\tconst deltaUp = Math.max(0, originNode.position.y - childBounds.y + gap);\n\tconst deltaDown = Math.max(\n\t\t0,\n\t\tchildBounds.y + childBounds.height - (originNode.position.y + originHeight) + gap\n\t);\n\n\t// Both above and below displace equally so the row expands symmetrically\n\tconst equalDelta = Math.max(deltaUp, deltaDown);\n\n\tfor (const node of existingNodes) {\n\t\tif (node.id === originNode.id) continue;\n\n\t\tconst isSiblingRow =\n\t\t\tMath.abs(node.position.y - originNode.position.y) < siblingTolerance;\n\n\t\tswitch (direction) {\n\t\t\tcase 'right': {\n\t\t\t\tif (node.position.x > originNode.position.x) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x + deltaPrimary,\n\t\t\t\t\t\ty: node.position.y\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'left': {\n\t\t\t\tif (node.position.x < originNode.position.x) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x - deltaPrimary,\n\t\t\t\t\t\ty: node.position.y\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'down': {\n\t\t\t\tif (node.position.y > originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y + deltaPrimary\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'up': {\n\t\t\t\tif (node.position.y < originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y - deltaPrimary\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'vertical': {\n\t\t\t\tif (isSiblingRow) break;\n\n\t\t\t\tif (node.position.y < originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y - equalDelta\n\t\t\t\t\t});\n\t\t\t\t} else if (node.position.y > originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y + equalDelta\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Sibling lane spreading to avoid overlap among child nodes\n\tif (spreadSiblingLanes && (direction === 'right' || direction === 'left')) {\n\t\tfor (const [nodeId, pos] of displacedMap.entries()) {\n\t\t\tconst node = existingNodes.find((n) => n.id === nodeId);\n\t\t\tif (node && Math.abs(node.position.y - originNode.position.y) < siblingTolerance) {\n\t\t\t\tconst isAbove = node.position.y < originNode.position.y;\n\t\t\t\tdisplacedMap.set(nodeId, {\n\t\t\t\t\tx: pos.x,\n\t\t\t\t\ty: pos.y + (isAbove ? -deltaUp : deltaDown)\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// Floor constraint\n\tif (minY !== undefined) {\n\t\tfor (const [nodeId, pos] of displacedMap.entries()) {\n\t\t\tif (pos.y < minY) {\n\t\t\t\tdisplacedMap.set(nodeId, { x: pos.x, y: minY });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn displacedMap;\n}\n\n/**\n * Calculates Dagre reflow displacement preserving the position of an anchor node.\n */\nexport function calculateDagreReflowDisplacement<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(params: {\n\tcurrentNodes: TNode[];\n\tcurrentEdges: TEdge[];\n\tfutureNodes: TNode[];\n\tfutureEdges: TEdge[];\n\toptions: ReflowDisplacementOptions;\n\tgetNodesBounds?: (nodes: TNode[]) => Rect;\n}): Map<string, XYPosition> {\n\tconst {\n\t\tcurrentNodes,\n\t\tfutureNodes,\n\t\tfutureEdges,\n\t\toptions\n\t} = params;\n\n\tconst {\n\t\tanchorNodeId,\n\t\tdirection = 'LR',\n\t\tranksep = 100,\n\t\tnodesep = 25,\n\t\tdefaultNodeWidth = 200,\n\t\tdefaultNodeHeight = 60\n\t} = options;\n\n\tconst anchorNode = currentNodes.find((n) => n.id === anchorNodeId);\n\tif (!anchorNode) return new Map();\n\n\tconst g = new dagre.graphlib.Graph();\n\tg.setDefaultEdgeLabel(() => ({}));\n\tg.setGraph({ rankdir: direction, ranksep, nodesep });\n\n\tconst nodeIds = new Set(futureNodes.map((n) => n.id));\n\n\tfutureNodes.forEach((node) => {\n\t\tconst nodeWidth = node.measured?.width ?? (node as any).width ?? defaultNodeWidth;\n\t\tconst nodeHeight = node.measured?.height ?? (node as any).height ?? defaultNodeHeight;\n\t\tg.setNode(node.id, { width: nodeWidth, height: nodeHeight });\n\t});\n\n\tfutureEdges.forEach((edge) => {\n\t\tif (nodeIds.has(edge.source) && nodeIds.has(edge.target)) {\n\t\t\tg.setEdge(edge.source, edge.target);\n\t\t}\n\t});\n\n\tdagre.layout(g);\n\n\tconst anchorLayoutPos = g.node(anchorNodeId);\n\tif (!anchorLayoutPos) return new Map();\n\n\tconst anchorWidth = anchorNode.measured?.width ?? (anchorNode as any).width ?? defaultNodeWidth;\n\tconst anchorHeight = anchorNode.measured?.height ?? (anchorNode as any).height ?? defaultNodeHeight;\n\n\tconst anchorLayoutUpperLeft = {\n\t\tx: anchorLayoutPos.x - anchorWidth / 2,\n\t\ty: anchorLayoutPos.y - anchorHeight / 2\n\t};\n\n\tconst deltaX = anchorNode.position.x - anchorLayoutUpperLeft.x;\n\tconst deltaY = anchorNode.position.y - anchorLayoutUpperLeft.y;\n\n\tconst displacementMap = new Map<string, XYPosition>();\n\n\tcurrentNodes.forEach((node) => {\n\t\tif (node.id === anchorNodeId) return;\n\n\t\tconst layoutNode = g.node(node.id);\n\t\tif (!layoutNode) return;\n\n\t\tconst nodeWidth = node.measured?.width ?? (node as any).width ?? defaultNodeWidth;\n\t\tconst nodeHeight = node.measured?.height ?? (node as any).height ?? defaultNodeHeight;\n\n\t\tconst upperLeftX = layoutNode.x - nodeWidth / 2 + deltaX;\n\t\tconst upperLeftY = layoutNode.y - nodeHeight / 2 + deltaY;\n\n\t\tif (\n\t\t\tMath.abs(upperLeftX - node.position.x) > 1 ||\n\t\t\tMath.abs(upperLeftY - node.position.y) > 1\n\t\t) {\n\t\t\tdisplacementMap.set(node.id, { x: upperLeftX, y: upperLeftY });\n\t\t}\n\t});\n\n\treturn displacementMap;\n}\n","import type {\n\tCanvasClipboardPayload,\n\tCanvasEdge,\n\tCanvasNode,\n\tXYPosition\n} from './types.js';\n\n/**\n * Checks if an event originated from a text input, textarea, contenteditable element, or rich editor.\n */\nexport function isEventFromTextInput(event: Event | { target: EventTarget | null }): boolean {\n\tconst target = (event as any).target as HTMLElement | null;\n\tif (!target) return false;\n\tif (\n\t\ttarget.tagName === 'INPUT' ||\n\t\ttarget.tagName === 'TEXTAREA' ||\n\t\ttarget.tagName === 'SELECT' ||\n\t\ttarget.isContentEditable ||\n\t\ttarget.closest?.('[contenteditable=\"true\"]') ||\n\t\ttarget.closest?.('.ProseMirror')\n\t) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/**\n * Validates that an object conforms to minimal CanvasNode shape.\n */\nexport function isValidCanvasNode(obj: unknown): obj is CanvasNode {\n\treturn (\n\t\ttypeof obj === 'object' &&\n\t\tobj !== null &&\n\t\t'id' in obj &&\n\t\ttypeof (obj as any).id === 'string' &&\n\t\t'position' in obj &&\n\t\ttypeof (obj as any).position === 'object' &&\n\t\t(obj as any).position !== null &&\n\t\t'x' in (obj as any).position &&\n\t\t'y' in (obj as any).position\n\t);\n}\n\n/**\n * Checks if a string is a valid HTTP/HTTPS URL.\n */\nexport function isValidUrl(url: string): boolean {\n\ttry {\n\t\tconst parsed = new URL(url);\n\t\treturn parsed.protocol === 'http:' || parsed.protocol === 'https:';\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Serializes nodes and optional edges into clipboard JSON payload.\n */\nexport function serializeCanvasNodes<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(nodes: TNode[], edges?: TEdge[]): string {\n\tconst payload: CanvasClipboardPayload<TNode, TEdge> = {\n\t\tversion: 1,\n\t\tnodes,\n\t\tedges\n\t};\n\treturn JSON.stringify(payload);\n}\n\n/**\n * Parses raw JSON string into a CanvasClipboardPayload if valid.\n */\nexport function parseCanvasClipboardData<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(raw: string): CanvasClipboardPayload<TNode, TEdge> | null {\n\ttry {\n\t\tconst parsed = JSON.parse(raw);\n\t\tif (\n\t\t\ttypeof parsed === 'object' &&\n\t\t\tparsed !== null &&\n\t\t\tArray.isArray(parsed.nodes) &&\n\t\t\tparsed.nodes.length > 0 &&\n\t\t\tparsed.nodes.every(isValidCanvasNode)\n\t\t) {\n\t\t\treturn parsed as CanvasClipboardPayload<TNode, TEdge>;\n\t\t}\n\t} catch {\n\t\t// Not JSON or invalid payload\n\t}\n\treturn null;\n}\n\n/**\n * Generates unique new IDs for pasted nodes and updates edge references accordingly.\n */\nexport function remapPastedNodes<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[] = [],\n\toffset: XYPosition = { x: 30, y: 30 },\n\tidGenerator: () => string = () => `node-${Math.random().toString(36).substring(2, 9)}`\n): { nodes: TNode[]; edges: TEdge[] } {\n\tconst idMap = new Map<string, string>();\n\n\tconst newNodes = nodes.map((node) => {\n\t\tconst newId = idGenerator();\n\t\tidMap.set(node.id, newId);\n\t\treturn {\n\t\t\t...node,\n\t\t\tid: newId,\n\t\t\tposition: {\n\t\t\t\tx: node.position.x + offset.x,\n\t\t\t\ty: node.position.y + offset.y\n\t\t\t},\n\t\t\tselected: true\n\t\t};\n\t});\n\n\tconst newEdges = edges\n\t\t.filter((e) => idMap.has(e.source) && idMap.has(e.target))\n\t\t.map((edge) => ({\n\t\t\t...edge,\n\t\t\tid: `edge-${Math.random().toString(36).substring(2, 9)}`,\n\t\t\tsource: idMap.get(edge.source)!,\n\t\t\ttarget: idMap.get(edge.target)!,\n\t\t\tselected: false\n\t\t}));\n\n\treturn { nodes: newNodes, edges: newEdges };\n}\n\n/**\n * Repositions nodes so their bounding box origin matches the given target position.\n */\nexport function repositionNodesTo<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[],\n\ttargetOrigin: XYPosition\n): TNode[] {\n\tif (nodes.length === 0) return [];\n\tconst minX = Math.min(...nodes.map((n) => n.position.x));\n\tconst minY = Math.min(...nodes.map((n) => n.position.y));\n\tconst deltaX = targetOrigin.x - minX;\n\tconst deltaY = targetOrigin.y - minY;\n\n\treturn nodes.map((n) => ({\n\t\t...n,\n\t\tposition: {\n\t\t\tx: n.position.x + deltaX,\n\t\t\ty: n.position.y + deltaY\n\t\t}\n\t}));\n}\n","import type { CanvasEdge, CanvasNode, Rect } from './types.js';\n\nexport interface CanvasHeightOptions {\n\t/** Smallest height returned (default 320). */\n\tmin?: number;\n\t/** Largest height returned; taller content is scaled/zoomed (default 560). */\n\tmax?: number;\n\t/** Extra padding around the content (default 48). */\n\tpadding?: number;\n}\n\nfunction clampHeight(contentHeight: number, options: CanvasHeightOptions = {}): number {\n\tconst { min = 320, max = 560, padding = 48 } = options;\n\treturn Math.round(Math.min(max, Math.max(min, contentHeight + padding)));\n}\n\n/**\n * Calculates the bounding box extent of all positioned nodes, or `null` for an empty graph.\n */\nexport function layoutBounds<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[]\n): Rect | null {\n\tif (nodes.length === 0) return null;\n\n\tlet minX = Infinity;\n\tlet minY = Infinity;\n\tlet maxX = -Infinity;\n\tlet maxY = -Infinity;\n\n\tfor (const node of nodes) {\n\t\tconst x = node.position.x;\n\t\tconst y = node.position.y;\n\t\tconst width = node.width ?? 180;\n\t\tconst height = node.height ?? 80;\n\n\t\tminX = Math.min(minX, x);\n\t\tminY = Math.min(minY, y);\n\t\tmaxX = Math.max(maxX, x + width);\n\t\tmaxY = Math.max(maxY, y + height);\n\t}\n\n\tif (minX === Infinity) return null;\n\treturn { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\n/**\n * Returns a clamped container height that fits the layout at 1:1 scale without overflow.\n */\nexport function canvasHeight<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[],\n\toptions?: CanvasHeightOptions\n): number {\n\treturn clampHeight(layoutBounds(nodes)?.height ?? 0, options);\n}\n\nconst DEFAULT_RANK_HEIGHT = 80 + 72; // Average node height + default rank separation\nconst NODES_PER_RANK = 2;\n\n/**\n * Estimates the container height to reserve before layout calculation finishes,\n * based on node and edge counts alone. Prevents layout shift (CLS).\n */\nexport function estimateCanvasHeight<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[],\n\toptions?: CanvasHeightOptions\n): number {\n\tconst ranks = Math.max(1, Math.ceil(nodes.length / NODES_PER_RANK));\n\treturn clampHeight(ranks * DEFAULT_RANK_HEIGHT, options);\n}\n\nfunction mix(a: number, b: number, t: number): number {\n\treturn a + (b - a) * t;\n}\n\n/**\n * Interpolates node positions and sizes between two layouts partway at progress `t` (0 = from, 1 = to).\n * Nodes present in both interpolate smoothly; nodes newly added in `to` snap to target.\n */\nexport function blendLayout<TNode extends CanvasNode = CanvasNode>(\n\tfrom: TNode[],\n\tto: TNode[],\n\tt: number\n): TNode[] {\n\tif (t >= 1) return to;\n\n\tconst fromMap = new Map<string, TNode>(from.map((n) => [n.id, n]));\n\n\treturn to.map((target) => {\n\t\tconst origin = fromMap.get(target.id);\n\t\tif (!origin) return target;\n\n\t\treturn {\n\t\t\t...target,\n\t\t\tposition: {\n\t\t\t\tx: mix(origin.position.x, target.position.x, t),\n\t\t\t\ty: mix(origin.position.y, target.position.y, t)\n\t\t\t},\n\t\t\twidth:\n\t\t\t\torigin.width !== undefined && target.width !== undefined\n\t\t\t\t\t? mix(origin.width, target.width, t)\n\t\t\t\t\t: target.width,\n\t\t\theight:\n\t\t\t\torigin.height !== undefined && target.height !== undefined\n\t\t\t\t\t? mix(origin.height, target.height, t)\n\t\t\t\t\t: target.height\n\t\t};\n\t});\n}\n\n/**\n * Filters out nodes that are not touched by any edge.\n *\n * During LLM streaming, nodes often arrive a chunk or token before the edge\n * that connects them. Displaying them immediately causes them to be placed as root\n * nodes only to jump into their correct position once the edge arrives.\n * Hiding orphan nodes during active streaming keeps the layout calm and jitter-free.\n */\nexport function connectedOnly<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[]\n): TNode[] {\n\tif (edges.length === 0) return nodes;\n\n\tconst linkedNodeIds = new Set<string>();\n\tfor (const edge of edges) {\n\t\tlinkedNodeIds.add(edge.source);\n\t\tlinkedNodeIds.add(edge.target);\n\t}\n\n\tconst filtered = nodes.filter((node) => linkedNodeIds.has(node.id));\n\t// If filtering would remove everything, return the original nodes\n\treturn filtered.length > 0 ? filtered : nodes;\n}\n","import { realClock, type Clock } from './clock.js';\nimport { ensureLayout } from './layout.js';\nimport { linearPositionTrajectory, runMultiNodeTransition } from './trajectory.js';\nimport type { CanvasEdge, CanvasNode, IncrementalLayoutOptions, NodeTransition, XYPosition } from './types.js';\nimport { connectedOnly } from './view.js';\n\nexport interface StreamingLayoutManagerOptions {\n\tthrottleMs?: number;\n\tglideDurationMs?: number;\n\tconnectedOnly?: boolean;\n\tclock?: Clock;\n\tlayoutOptions?: IncrementalLayoutOptions;\n\tonLayoutUpdated?: (positions: Map<string, XYPosition>) => void;\n}\n\n/**\n * Manages throttled incremental layout recalculation and smooth tweened node gliding\n * during active streaming (e.g. LLM streaming or graph generation).\n */\nexport class StreamingLayoutManager<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n> {\n\tprivate throttleMs: number;\n\tprivate glideDurationMs: number;\n\tprivate connectedOnly: boolean;\n\tprivate clock: Clock;\n\tprivate layoutOptions: IncrementalLayoutOptions;\n\tprivate onLayoutUpdated?: (positions: Map<string, XYPosition>) => void;\n\n\tprivate pendingTimer: any = null;\n\tprivate activeTransitionCancel: (() => void) | null = null;\n\tprivate targetPositions = new Map<string, XYPosition>();\n\n\tconstructor(options: StreamingLayoutManagerOptions = {}) {\n\t\tthis.throttleMs = options.throttleMs ?? 200;\n\t\tthis.glideDurationMs = options.glideDurationMs ?? 300;\n\t\tthis.connectedOnly = options.connectedOnly ?? false;\n\t\tthis.clock = options.clock ?? realClock;\n\t\tthis.layoutOptions = options.layoutOptions ?? { direction: 'LR' };\n\t\tthis.onLayoutUpdated = options.onLayoutUpdated;\n\t}\n\n\t/**\n\t * Feed incoming nodes and edges into the streaming manager.\n\t * Coalesces rapid streaming bursts and triggers smooth layout gliding.\n\t */\n\tpublic pushStreamUpdate(\n\t\tnodes: TNode[],\n\t\tedges: TEdge[],\n\t\tcurrentPositions: Map<string, XYPosition>\n\t): void {\n\t\tif (this.pendingTimer) {\n\t\t\tclearTimeout(this.pendingTimer);\n\t\t}\n\n\t\tthis.pendingTimer = setTimeout(() => {\n\t\t\tthis.pendingTimer = null;\n\t\t\tthis.recalculateAndGlide(nodes, edges, currentPositions);\n\t\t}, this.throttleMs);\n\t}\n\n\t/**\n\t * Forces immediate calculation and cancels pending throttled timers.\n\t */\n\tpublic flush(\n\t\tnodes: TNode[],\n\t\tedges: TEdge[],\n\t\tcurrentPositions: Map<string, XYPosition>\n\t): void {\n\t\tif (this.pendingTimer) {\n\t\t\tclearTimeout(this.pendingTimer);\n\t\t\tthis.pendingTimer = null;\n\t\t}\n\t\tthis.recalculateAndGlide(nodes, edges, currentPositions);\n\t}\n\n\tprivate recalculateAndGlide(\n\t\tnodes: TNode[],\n\t\tedges: TEdge[],\n\t\tcurrentPositions: Map<string, XYPosition>\n\t): void {\n\t\tconst targetNodes = this.connectedOnly ? connectedOnly(nodes, edges) : nodes;\n\t\tif (targetNodes.length === 0) return;\n\n\t\t// Cancel any currently running RAF glide\n\t\tif (this.activeTransitionCancel) {\n\t\t\tthis.activeTransitionCancel();\n\t\t\tthis.activeTransitionCancel = null;\n\t\t}\n\n\t\t// Incremental layout preserves existing nodes and aligns new nodes\n\t\tconst stored: Record<string, XYPosition> = {};\n\t\tfor (const [id, pos] of currentPositions.entries()) {\n\t\t\tstored[id] = pos;\n\t\t}\n\n\t\tconst layouted = ensureLayout(targetNodes, edges, {\n\t\t\t...this.layoutOptions,\n\t\t\tstoredPositions: stored\n\t\t});\n\n\t\tconst nextPositions = new Map<string, XYPosition>();\n\t\tconst transitions: NodeTransition<TNode>[] = [];\n\n\t\tfor (const node of layouted) {\n\t\t\tconst target = node.position;\n\t\t\tnextPositions.set(node.id, target);\n\n\t\t\tconst current = currentPositions.get(node.id) ?? target;\n\t\t\tconst distance = Math.hypot(target.x - current.x, target.y - current.y);\n\n\t\t\tif (distance > 2) {\n\t\t\t\ttransitions.push({\n\t\t\t\t\tnode,\n\t\t\t\t\tfrom: current,\n\t\t\t\t\tto: target,\n\t\t\t\t\ttrajectory: linearPositionTrajectory,\n\t\t\t\t\tduration: this.glideDurationMs\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis.targetPositions = nextPositions;\n\n\t\tif (transitions.length > 0) {\n\t\t\tthis.activeTransitionCancel = runMultiNodeTransition(transitions, {\n\t\t\t\tclock: this.clock,\n\t\t\t\tonUpdate: () => {\n\t\t\t\t\t// Broadcast updated positions during RAF\n\t\t\t\t\tconst liveMap = new Map<string, XYPosition>(currentPositions);\n\t\t\t\t\tfor (const trans of transitions) {\n\t\t\t\t\t\tliveMap.set(trans.node.id, { ...trans.node.position });\n\t\t\t\t\t}\n\t\t\t\t\tthis.onLayoutUpdated?.(liveMap);\n\t\t\t\t},\n\t\t\t\tonComplete: () => {\n\t\t\t\t\tthis.activeTransitionCancel = null;\n\t\t\t\t\tthis.onLayoutUpdated?.(nextPositions);\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tthis.onLayoutUpdated?.(nextPositions);\n\t\t}\n\t}\n\n\tpublic destroy(): void {\n\t\tif (this.pendingTimer) {\n\t\t\tclearTimeout(this.pendingTimer);\n\t\t\tthis.pendingTimer = null;\n\t\t}\n\t\tif (this.activeTransitionCancel) {\n\t\t\tthis.activeTransitionCancel();\n\t\t\tthis.activeTransitionCancel = null;\n\t\t}\n\t}\n}\n","import { ensureLayout, getLayoutedNodes, placeBeside } from '../canvas/layout.js';\nimport type { CanvasEdge, CanvasNode, Rect } from '../canvas/types.js';\nimport type { AgentCommand, AgentStep, EditorSnapshot } from './types.js';\n\n/**\n * Plans a sequence of atomic execution steps from a high-level agent command.\n */\nexport function planAgentCommand<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tcommand: AgentCommand<TNode, TEdge>,\n\tsnapshot: EditorSnapshot<TNode, TEdge>,\n\toptions: {\n\t\tdefaultNodeSize?: { width: number; height: number };\n\t\tidGenerator?: () => string;\n\t} = {}\n): AgentStep<TNode, TEdge>[] {\n\tconst defaultNodeSize = options.defaultNodeSize ?? { width: 200, height: 60 };\n\tconst idGen = options.idGenerator ?? (() => `node-${Math.random().toString(36).substring(2, 9)}`);\n\tconst edgeIdGen = () => `edge-${Math.random().toString(36).substring(2, 9)}`;\n\n\tconst nodes = snapshot.canvas?.nodes ?? [];\n\tconst edges = snapshot.canvas?.edges ?? [];\n\n\tswitch (command.type) {\n\t\tcase 'canvas:add_node': {\n\t\t\tlet pos = command.node.position;\n\n\t\t\tif (!pos) {\n\t\t\t\tif (command.nearNodeId) {\n\t\t\t\t\t// Use collision-aware directional placement\n\t\t\t\t\tconst rects: Record<string, Rect> = {};\n\t\t\t\t\tfor (const n of nodes) {\n\t\t\t\t\t\trects[n.id] = {\n\t\t\t\t\t\t\tx: n.position.x,\n\t\t\t\t\t\t\ty: n.position.y,\n\t\t\t\t\t\t\twidth: n.measured?.width ?? (n as any).width ?? defaultNodeSize.width,\n\t\t\t\t\t\t\theight: n.measured?.height ?? (n as any).height ?? defaultNodeSize.height\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tpos = placeBeside(\n\t\t\t\t\t\trects,\n\t\t\t\t\t\tdefaultNodeSize,\n\t\t\t\t\t\tcommand.side ?? 'right',\n\t\t\t\t\t\tcommand.nearNodeId\n\t\t\t\t\t);\n\t\t\t\t} else if (nodes.length > 0) {\n\t\t\t\t\t// Default beside the last node\n\t\t\t\t\tconst lastNode = nodes[nodes.length - 1];\n\t\t\t\t\tconst rects: Record<string, Rect> = {};\n\t\t\t\t\tfor (const n of nodes) {\n\t\t\t\t\t\trects[n.id] = {\n\t\t\t\t\t\t\tx: n.position.x,\n\t\t\t\t\t\t\ty: n.position.y,\n\t\t\t\t\t\t\twidth: n.measured?.width ?? (n as any).width ?? defaultNodeSize.width,\n\t\t\t\t\t\t\theight: n.measured?.height ?? (n as any).height ?? defaultNodeSize.height\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tpos = placeBeside(rects, defaultNodeSize, 'right', lastNode.id);\n\t\t\t\t} else {\n\t\t\t\t\tpos = { x: 100, y: 100 };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst fullNode: TNode = {\n\t\t\t\t...command.node,\n\t\t\t\tid: command.node.id || idGen(),\n\t\t\t\tposition: pos\n\t\t\t} as TNode;\n\n\t\t\tconst steps: AgentStep<TNode, TEdge>[] = [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:canvas_add_node',\n\t\t\t\t\tnode: fullNode\n\t\t\t\t}\n\t\t\t];\n\n\t\t\t// If attached to nearNode, optionally automatically connect\n\t\t\tif (command.nearNodeId) {\n\t\t\t\tsteps.push({\n\t\t\t\t\ttype: 'step:canvas_add_edge',\n\t\t\t\t\tedge: {\n\t\t\t\t\t\tid: edgeIdGen(),\n\t\t\t\t\t\tsource: command.nearNodeId,\n\t\t\t\t\t\ttarget: fullNode.id\n\t\t\t\t\t} as TEdge\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn steps;\n\t\t}\n\n\t\tcase 'canvas:remove_nodes': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:canvas_remove_nodes',\n\t\t\t\t\tnodeIds: command.nodeIds\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'canvas:connect': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:canvas_add_edge',\n\t\t\t\t\tedge: {\n\t\t\t\t\t\tid: edgeIdGen(),\n\t\t\t\t\t\tsource: command.source,\n\t\t\t\t\t\ttarget: command.target,\n\t\t\t\t\t\tlabel: command.label\n\t\t\t\t\t} as TEdge\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'canvas:update_node': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:canvas_update_node',\n\t\t\t\t\tid: command.id,\n\t\t\t\t\tdata: command.data\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'canvas:layout': {\n\t\t\tconst dir = command.direction ?? 'LR';\n\t\t\tlet layouted: TNode[];\n\n\t\t\tif (command.incremental) {\n\t\t\t\tconst stored: Record<string, { x: number; y: number }> = {};\n\t\t\t\tfor (const n of nodes) {\n\t\t\t\t\tif (n.position && (n.position.x !== 0 || n.position.y !== 0)) {\n\t\t\t\t\t\tstored[n.id] = { ...n.position };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlayouted = ensureLayout(nodes, edges, {\n\t\t\t\t\tdirection: dir,\n\t\t\t\t\tstoredPositions: stored\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tlayouted = getLayoutedNodes(nodes, edges, undefined, { direction: dir });\n\t\t\t}\n\n\t\t\tconst positions: Record<string, { x: number; y: number }> = {};\n\t\t\tfor (const node of layouted) {\n\t\t\t\tpositions[node.id] = { ...node.position };\n\t\t\t}\n\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:canvas_move_nodes',\n\t\t\t\t\tpositions\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'canvas:select': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:canvas_select',\n\t\t\t\t\tnodeIds: command.nodeIds\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'canvas:highlight': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:canvas_highlight',\n\t\t\t\t\tnodeIds: command.nodeIds,\n\t\t\t\t\tcolor: command.color ?? '#3b82f6',\n\t\t\t\t\tdurationMs: command.durationMs ?? 2000\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'prompt:insert_text': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:prompt_insert',\n\t\t\t\t\ttext: command.text,\n\t\t\t\t\tat: command.at\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'prompt:replace_range': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:prompt_replace',\n\t\t\t\t\tfrom: command.from,\n\t\t\t\t\tto: command.to,\n\t\t\t\t\ttext: command.text\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'prompt:set_variable': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:prompt_set_variable',\n\t\t\t\t\tname: command.name,\n\t\t\t\t\tvalue: command.value\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'prompt:select': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:prompt_select',\n\t\t\t\t\tfrom: command.from,\n\t\t\t\t\tto: command.to\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'choreography:say': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:say',\n\t\t\t\t\ttext: command.text,\n\t\t\t\t\tatNodeId: command.atNodeId,\n\t\t\t\t\tposition: command.position\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tcase 'choreography:wait': {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\ttype: 'step:wait',\n\t\t\t\t\tms: command.ms\n\t\t\t\t}\n\t\t\t];\n\t\t}\n\n\t\tdefault: {\n\t\t\treturn [];\n\t\t}\n\t}\n}\n","/**\n * Standard MCP Tool Definitions for @pixerate/editor.\n * Compatible with the Model Context Protocol (MCP) tool specification schema.\n */\n\nexport const MCP_TOOL_GET_EDITOR_STATE = {\n\tname: 'get_editor_state',\n\tdescription:\n\t\t'Retrieves the current state of the document, variables, selection, and canvas graph (nodes and edges).',\n\tinputSchema: {\n\t\ttype: 'object',\n\t\tproperties: {\n\t\t\tincludeDocument: {\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdescription: 'Whether to include the prompt document text and variables (default: true).'\n\t\t\t},\n\t\t\tincludeCanvas: {\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdescription: 'Whether to include the canvas nodes and edges (default: true).'\n\t\t\t}\n\t\t}\n\t}\n} as const;\n\nexport const MCP_TOOL_EDIT_CANVAS = {\n\tname: 'edit_canvas',\n\tdescription:\n\t\t'Applies high-level structural operations to the visual canvas (adding nodes, connecting edges, organizing layout, or moving elements).',\n\tinputSchema: {\n\t\ttype: 'object',\n\t\tproperties: {\n\t\t\toperation: {\n\t\t\t\ttype: 'string',\n\t\t\t\tenum: [\n\t\t\t\t\t'add_node',\n\t\t\t\t\t'remove_nodes',\n\t\t\t\t\t'connect',\n\t\t\t\t\t'update_node',\n\t\t\t\t\t'layout',\n\t\t\t\t\t'select',\n\t\t\t\t\t'highlight'\n\t\t\t\t],\n\t\t\t\tdescription: 'The canvas operation to execute.'\n\t\t\t},\n\t\t\tnode: {\n\t\t\t\ttype: 'object',\n\t\t\t\tdescription: 'Node definition when operation is add_node. Can omit position to auto-place.'\n\t\t\t},\n\t\t\tnearNodeId: {\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Anchor node ID to position beside using collision-aware placement.'\n\t\t\t},\n\t\t\tside: {\n\t\t\t\ttype: 'string',\n\t\t\t\tenum: ['top', 'right', 'bottom', 'left'],\n\t\t\t\tdescription: 'Side of the anchor node to place the new node beside.'\n\t\t\t},\n\t\t\tnodeIds: {\n\t\t\t\ttype: 'array',\n\t\t\t\titems: { type: 'string' },\n\t\t\t\tdescription: 'Array of node IDs for remove_nodes, select, or highlight.'\n\t\t\t},\n\t\t\tsource: {\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Source node ID for connect operation.'\n\t\t\t},\n\t\t\ttarget: {\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Target node ID for connect operation.'\n\t\t\t},\n\t\t\tlabel: {\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Optional edge label for connect operation.'\n\t\t\t},\n\t\t\tdirection: {\n\t\t\t\ttype: 'string',\n\t\t\t\tenum: ['LR', 'TB', 'RL', 'BT'],\n\t\t\t\tdescription: 'Layout direction (default LR).'\n\t\t\t},\n\t\t\tincremental: {\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdescription: 'Preserve existing node coordinates and blend layout (default true).'\n\t\t\t}\n\t\t},\n\t\trequired: ['operation']\n\t}\n} as const;\n\nexport const MCP_TOOL_EDIT_PROMPT = {\n\tname: 'edit_prompt',\n\tdescription:\n\t\t'Applies edits to the prompt template document, including inserting text, replacing ranges, and setting variables.',\n\tinputSchema: {\n\t\ttype: 'object',\n\t\tproperties: {\n\t\t\toperation: {\n\t\t\t\ttype: 'string',\n\t\t\t\tenum: ['insert_text', 'replace_range', 'set_variable', 'select'],\n\t\t\t\tdescription: 'The prompt operation to execute.'\n\t\t\t},\n\t\t\ttext: {\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Text to insert or replace.'\n\t\t\t},\n\t\t\tat: {\n\t\t\t\ttype: 'number',\n\t\t\t\tdescription: 'Position to insert text at.'\n\t\t\t},\n\t\t\tfrom: {\n\t\t\t\ttype: 'number',\n\t\t\t\tdescription: 'Start offset for replace_range or select.'\n\t\t\t},\n\t\t\tto: {\n\t\t\t\ttype: 'number',\n\t\t\t\tdescription: 'End offset for replace_range or select.'\n\t\t\t},\n\t\t\tname: {\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Variable name for set_variable.'\n\t\t\t},\n\t\t\tvalue: {\n\t\t\t\tdescription: 'Variable value for set_variable.'\n\t\t\t}\n\t\t},\n\t\trequired: ['operation']\n\t}\n} as const;\n\nexport const MCP_TOOL_VIEW_EDITOR = {\n\tname: 'view_editor',\n\tdescription:\n\t\t'Captures a visual image snapshot (JPEG or PNG) of the editor canvas or viewport for multimodal evaluation. Active agent cursor indicators are automatically excluded from the snapshot.',\n\tinputSchema: {\n\t\ttype: 'object',\n\t\tproperties: {\n\t\t\tscope: {\n\t\t\t\ttype: 'string',\n\t\t\t\tenum: ['viewport', 'canvas'],\n\t\t\t\tdescription: 'Whether to capture only the visible viewport or the full canvas bounding box (default: viewport).'\n\t\t\t},\n\t\t\tformat: {\n\t\t\t\ttype: 'string',\n\t\t\t\tenum: ['jpeg', 'png'],\n\t\t\t\tdescription: 'Image format of the base64 snapshot (default: jpeg).'\n\t\t\t},\n\t\t\tmaxEdge: {\n\t\t\t\ttype: 'integer',\n\t\t\t\tdescription: 'Maximum width or height dimension in pixels (default: 1024).'\n\t\t\t}\n\t\t}\n\t}\n} as const;\n\n/**\n * CSS selectors for ephemeral UI overlays (such as agent cursors, presence tags, and transient bubbles)\n * that should be excluded during canvas image export and visual snapshot generation.\n */\nexport const EXPORT_EXCLUDED_SELECTORS = [\n\t'.pixerate-presence',\n\t'.agent-presence',\n\t'.ursula-presence'\n] as const;\n\nexport const EDITOR_MCP_TOOLS = [\n\tMCP_TOOL_GET_EDITOR_STATE,\n\tMCP_TOOL_EDIT_CANVAS,\n\tMCP_TOOL_EDIT_PROMPT,\n\tMCP_TOOL_VIEW_EDITOR\n] as const;\n\n","import type { DepthMaskOptions, ImageAdjustments } from './types';\n\nfunction clamp(value: number, min = 0, max = 255): number {\n return Math.max(min, Math.min(max, value));\n}\n\n/**\n * Applies color and tone adjustments (brightness, contrast, saturation, exposure, temperature, opacity, blur)\n * directly to the pixel data of an ImageData buffer.\n */\nexport function applyAdjustments(imageData: ImageData, adjustments: ImageAdjustments): void {\n const { brightness, contrast, saturation, exposure, temperature, opacity, blur } = adjustments;\n const data = imageData.data;\n const len = data.length;\n\n const hasBrightness = brightness !== 0;\n const hasContrast = contrast !== 0;\n const hasSaturation = saturation !== 0;\n const hasExposure = exposure !== 0;\n const hasTemperature = temperature !== 0;\n const hasOpacity = opacity < 1;\n\n // Pre-calculate contrast factor\n const contrastFactor = hasContrast\n ? (259 * (contrast + 255)) / (255 * (259 - contrast))\n : 1;\n\n // Pre-calculate exposure multiplier\n const exposureMultiplier = hasExposure ? Math.pow(2, exposure / 50) : 1;\n\n // Pre-calculate saturation multiplier\n const satMultiplier = hasSaturation ? 1 + saturation / 100 : 1;\n\n // Pre-calculate temperature offsets\n const tempOffset = hasTemperature ? temperature * 0.8 : 0;\n\n if (hasBrightness || hasContrast || hasSaturation || hasExposure || hasTemperature || hasOpacity) {\n for (let i = 0; i < len; i += 4) {\n let r = data[i];\n let g = data[i + 1];\n let b = data[i + 2];\n let a = data[i + 3];\n\n // Exposure\n if (hasExposure) {\n r = clamp(r * exposureMultiplier);\n g = clamp(g * exposureMultiplier);\n b = clamp(b * exposureMultiplier);\n }\n\n // Brightness\n if (hasBrightness) {\n const bOffset = brightness * 2.55;\n r = clamp(r + bOffset);\n g = clamp(g + bOffset);\n b = clamp(b + bOffset);\n }\n\n // Contrast\n if (hasContrast) {\n r = clamp(contrastFactor * (r - 128) + 128);\n g = clamp(contrastFactor * (g - 128) + 128);\n b = clamp(contrastFactor * (b - 128) + 128);\n }\n\n // Saturation\n if (hasSaturation) {\n const luminance = 0.2989 * r + 0.587 * g + 0.114 * b;\n r = clamp(luminance + (r - luminance) * satMultiplier);\n g = clamp(luminance + (g - luminance) * satMultiplier);\n b = clamp(luminance + (b - luminance) * satMultiplier);\n }\n\n // Temperature / Warmth\n if (hasTemperature) {\n r = clamp(r + tempOffset);\n b = clamp(b - tempOffset);\n }\n\n // Opacity\n if (hasOpacity) {\n a = clamp(a * opacity);\n }\n\n data[i] = r;\n data[i + 1] = g;\n data[i + 2] = b;\n data[i + 3] = a;\n }\n }\n\n // Apply blur if requested\n if (blur > 0) {\n applyFastBoxBlur(imageData, Math.min(Math.round(blur), 40));\n }\n}\n\n/**\n * Fast separable box blur running horizontally and vertically.\n */\nfunction applyFastBoxBlur(imageData: ImageData, radius: number): void {\n if (radius < 1) return;\n const w = imageData.width;\n const h = imageData.height;\n const src = imageData.data;\n const temp = new Uint8ClampedArray(src.length);\n\n // Horizontal blur pass\n for (let y = 0; y < h; y++) {\n for (let x = 0; x < w; x++) {\n let r = 0, g = 0, b = 0, a = 0;\n let count = 0;\n for (let k = -radius; k <= radius; k++) {\n const px = Math.min(w - 1, Math.max(0, x + k));\n const idx = (y * w + px) * 4;\n r += src[idx];\n g += src[idx + 1];\n b += src[idx + 2];\n a += src[idx + 3];\n count++;\n }\n const dstIdx = (y * w + x) * 4;\n temp[dstIdx] = Math.round(r / count);\n temp[dstIdx + 1] = Math.round(g / count);\n temp[dstIdx + 2] = Math.round(b / count);\n temp[dstIdx + 3] = Math.round(a / count);\n }\n }\n\n // Vertical blur pass back into src\n for (let x = 0; x < w; x++) {\n for (let y = 0; y < h; y++) {\n let r = 0, g = 0, b = 0, a = 0;\n let count = 0;\n for (let k = -radius; k <= radius; k++) {\n const py = Math.min(h - 1, Math.max(0, y + k));\n const idx = (py * w + x) * 4;\n r += temp[idx];\n g += temp[idx + 1];\n b += temp[idx + 2];\n a += temp[idx + 3];\n count++;\n }\n const dstIdx = (y * w + x) * 4;\n src[dstIdx] = Math.round(r / count);\n src[dstIdx + 1] = Math.round(g / count);\n src[dstIdx + 2] = Math.round(b / count);\n src[dstIdx + 3] = Math.round(a / count);\n }\n }\n}\n\n/**\n * Blends a depth/alpha mask into the main image data based on Gleamforge depth masking.\n * Supports threshold range with softness gradation, brightness mode, and optional inversion.\n */\nexport function applyDepthMask(\n mainImageData: ImageData,\n maskImageData: ImageData,\n options: DepthMaskOptions\n): void {\n const { mode, depthRange, softness, invert } = options;\n const mainData = mainImageData.data;\n const maskData = maskImageData.data;\n const len = Math.min(mainData.length, maskData.length);\n const effectiveSoftness = Math.max(1, softness || 10);\n const minDepth = depthRange[0];\n const maxDepth = depthRange[1];\n\n for (let i = 0; i < len; i += 4) {\n let maskValue = maskData[i]; // Use red channel of mask (or grayscale)\n if (invert) {\n maskValue = 255 - maskValue;\n }\n\n let alphaValue: number;\n\n if (mode === 'threshold') {\n if (maskValue >= maxDepth + effectiveSoftness) {\n alphaValue = 0;\n } else if (maskValue > maxDepth) {\n alphaValue = Math.round(((maxDepth + effectiveSoftness - maskValue) / effectiveSoftness) * 255);\n } else if (maskValue >= minDepth) {\n alphaValue = 255;\n } else if (maskValue < minDepth - effectiveSoftness) {\n alphaValue = 0;\n } else {\n alphaValue = Math.round(((maskValue - (minDepth - effectiveSoftness)) / effectiveSoftness) * 255);\n }\n } else {\n // Brightness mode\n alphaValue = clamp(maskValue + minDepth);\n }\n\n // Multiply existing alpha with mask alpha\n mainData[i + 3] = clamp((mainData[i + 3] * alphaValue) / 255);\n }\n}\n\n/**\n * Removes alpha channel by setting all alpha bytes to 255 (completely opaque).\n * From Gleamforge image-filters.ts.\n */\nexport function removeAlpha(imageData: ImageData): void {\n const data = imageData.data;\n const len = data.length;\n for (let i = 3; i < len; i += 4) {\n data[i] = 255;\n }\n}\n","import type {\n Annotation,\n CropBox,\n ExportOptions,\n ImageEditorState,\n ImageTransform,\n PenAnnotation,\n RectAnnotation,\n CircleAnnotation,\n ArrowAnnotation,\n LineAnnotation,\n TextAnnotation,\n ImageAnnotation,\n} from './types';\nimport { applyAdjustments, applyDepthMask } from './filters';\n\nexport interface RenderOptions {\n viewportWidth?: number;\n viewportHeight?: number;\n showCropOverlay?: boolean;\n showSelectionOverlay?: boolean;\n interactive?: boolean;\n draftAnnotation?: Annotation | null;\n draftCrop?: CropBox | null;\n}\n\n/**\n * Image Cache to avoid refetching HTMLImageElement objects repeatedly during re-renders.\n */\nclass ImageCache {\n private cache = new Map<string, HTMLImageElement>();\n\n public async get(src: string): Promise<HTMLImageElement> {\n const existing = this.cache.get(src);\n if (existing && existing.complete) {\n return existing;\n }\n\n return new Promise((resolve, reject) => {\n if (typeof window === 'undefined' || typeof Image === 'undefined') {\n reject(new Error('Image loading is only supported in browser/DOM environments'));\n return;\n }\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.onload = () => {\n this.cache.set(src, img);\n resolve(img);\n };\n img.onerror = (e) => reject(new Error(`Failed to load image from: ${src}`));\n img.src = src;\n\n // In JSDOM or test environments where Image resource loading is inactive, resolve promptly\n if (typeof navigator !== 'undefined' && /jsdom/i.test(navigator.userAgent)) {\n setTimeout(() => {\n try {\n Object.defineProperty(img, 'naturalWidth', { value: 800, configurable: true });\n Object.defineProperty(img, 'naturalHeight', { value: 600, configurable: true });\n Object.defineProperty(img, 'complete', { value: true, configurable: true });\n } catch {\n // Ignore definition errors in restrictive environments\n }\n this.cache.set(src, img);\n resolve(img);\n }, 10);\n }\n });\n }\n\n public set(src: string, img: HTMLImageElement): void {\n this.cache.set(src, img);\n }\n\n public clear(): void {\n this.cache.clear();\n }\n}\n\nexport const globalImageCache = new ImageCache();\n\n/**\n * Renders an image with all its transformations, filters, depth masks, and annotations\n * to a target HTMLCanvasElement.\n */\nexport class ImageEditorRenderer {\n public imageCache = globalImageCache;\n private cachedBaseCanvas: HTMLCanvasElement | null = null;\n private cachedBaseKey = '';\n\n /**\n * Helper to create a canvas element safely in browser/JSDOM.\n */\n public createCanvas(width: number, height: number): HTMLCanvasElement {\n if (typeof document !== 'undefined' && document.createElement) {\n const c = document.createElement('canvas');\n c.width = Math.max(1, Math.round(width));\n c.height = Math.max(1, Math.round(height));\n return c;\n }\n // Fallback for non-DOM / headless\n return {\n width: Math.max(1, Math.round(width)),\n height: Math.max(1, Math.round(height)),\n getContext: () => null,\n toDataURL: () => '',\n toBlob: () => {},\n } as unknown as HTMLCanvasElement;\n }\n\n /**\n * Renders the editor state onto a canvas (viewport or preview).\n */\n public async renderToCanvas(\n targetCanvas: HTMLCanvasElement,\n imageSource: CanvasImageSource | string,\n state: ImageEditorState,\n options: RenderOptions = {}\n ): Promise<void> {\n const ctx = targetCanvas.getContext('2d');\n if (!ctx) return;\n\n let img: CanvasImageSource;\n if (typeof imageSource === 'string') {\n img = await this.imageCache.get(imageSource);\n } else {\n img = imageSource;\n }\n\n const naturalWidth = (img as any).naturalWidth || (img as any).videoWidth || (img as any).width || 800;\n const naturalHeight = (img as any).naturalHeight || (img as any).videoHeight || (img as any).height || 600;\n\n const { crop, transform, adjustments, depthMask, annotations, selectedAnnotationId, zoom, pan, isOriginalCompared } = state;\n\n // Viewport dimensions\n const vpWidth = options.viewportWidth || targetCanvas.width;\n const vpHeight = options.viewportHeight || targetCanvas.height;\n\n targetCanvas.width = vpWidth;\n targetCanvas.height = vpHeight;\n\n ctx.clearRect(0, 0, vpWidth, vpHeight);\n\n // If in compare mode, render original image directly and exit\n if (isOriginalCompared) {\n this.drawFittedImage(ctx, img, naturalWidth, naturalHeight, vpWidth, vpHeight, zoom, pan);\n return;\n }\n\n // Determine working base dimensions based on crop or natural\n // When actively in crop tool or overlay requested, show full image so user can adjust the crop box\n const isActivelyCropping = Boolean(options.showCropOverlay || state.activeTool === 'crop');\n const cropX = (!isActivelyCropping && crop) ? Math.max(0, crop.x) : 0;\n const cropY = (!isActivelyCropping && crop) ? Math.max(0, crop.y) : 0;\n const cropW = (!isActivelyCropping && crop) ? Math.min(naturalWidth - cropX, crop.width) : naturalWidth;\n const cropH = (!isActivelyCropping && crop) ? Math.min(naturalHeight - cropY, crop.height) : naturalHeight;\n\n const angle = ((transform.rotate % 360) + 360) % 360;\n const isSwapped = angle === 90 || angle === 270;\n const baseW = isSwapped ? cropH : cropW;\n const baseH = isSwapped ? cropW : cropH;\n\n // 1. Offscreen canvas for Base Image + Transform (Flip/Rotate) + Crop + Adjustments\n const baseKey = `${state.sourceUrl}-${naturalWidth}x${naturalHeight}-${cropX},${cropY},${cropW},${cropH}-${angle},${transform.flipH},${transform.flipV}-${adjustments.brightness},${adjustments.contrast},${adjustments.saturation},${adjustments.exposure},${adjustments.temperature},${adjustments.blur},${adjustments.opacity}-${depthMask.enabled},${depthMask.depthRange?.[0]}-${depthMask.depthRange?.[1]},${depthMask.softness},${depthMask.invert},${depthMask.mode}`;\n\n let baseCanvas = this.cachedBaseCanvas;\n if (!baseCanvas || this.cachedBaseKey !== baseKey) {\n baseCanvas = this.createCanvas(baseW, baseH);\n const baseCtx = baseCanvas.getContext('2d');\n\n if (baseCtx) {\n baseCtx.save();\n\n // Handle Flip & Rotate\n const rad = (angle * Math.PI) / 180;\n baseCtx.translate(baseW / 2, baseH / 2);\n baseCtx.rotate(rad);\n baseCtx.scale(transform.flipH ? -1 : 1, transform.flipV ? -1 : 1);\n\n // Draw the cropped portion centered\n baseCtx.drawImage(\n img,\n cropX, cropY, cropW, cropH,\n -cropW / 2, -cropH / 2, cropW, cropH\n );\n\n baseCtx.restore();\n\n // 2. Pixel adjustments & Depth Masking\n const imageData = baseCtx.getImageData(0, 0, baseW, baseH);\n if (imageData) {\n applyAdjustments(imageData, adjustments);\n\n if (depthMask.enabled && depthMask.maskSource) {\n try {\n const maskImg = await this.imageCache.get(depthMask.maskSource);\n const maskCanvas = this.createCanvas(baseW, baseH);\n const maskCtx = maskCanvas.getContext('2d');\n if (maskCtx) {\n maskCtx.drawImage(maskImg, cropX, cropY, cropW, cropH, 0, 0, baseW, baseH);\n const maskData = maskCtx.getImageData(0, 0, baseW, baseH);\n if (maskData) {\n applyDepthMask(imageData, maskData, depthMask);\n }\n }\n } catch {\n // Mask failed to load; continue without crashing\n }\n }\n\n baseCtx.putImageData(imageData, 0, 0);\n }\n }\n this.cachedBaseCanvas = baseCanvas;\n this.cachedBaseKey = baseKey;\n }\n\n // 3. Render base canvas onto target canvas with viewport zoom & pan\n ctx.save();\n // Center of canvas\n ctx.translate(vpWidth / 2 + pan.x, vpHeight / 2 + pan.y);\n ctx.scale(zoom, zoom);\n\n // Calculate fitted dimensions\n const fitScale = Math.min((vpWidth * 0.85) / baseW, (vpHeight * 0.85) / baseH, 1);\n const renderW = baseW * fitScale;\n const renderH = baseH * fitScale;\n\n // Draw base image\n ctx.drawImage(baseCanvas, -renderW / 2, -renderH / 2, renderW, renderH);\n\n // 4. Render Annotations scaled to fit image space\n const scaleFactor = fitScale;\n ctx.save();\n ctx.translate(-renderW / 2, -renderH / 2);\n ctx.scale(scaleFactor, scaleFactor);\n\n for (const ann of annotations) {\n await this.drawAnnotation(ctx, ann);\n if (options.showSelectionOverlay && ann.id === selectedAnnotationId) {\n this.drawAnnotationSelection(ctx, ann);\n }\n }\n\n // Render active live draft annotation\n if (options.draftAnnotation) {\n await this.drawAnnotation(ctx, options.draftAnnotation);\n }\n\n ctx.restore();\n\n ctx.restore();\n\n // 5. Draw Crop Grid Overlay if crop overlay is requested\n const isCroppingActive = Boolean(options.showCropOverlay || state.activeTool === 'crop');\n const activeCrop =\n (options.draftCrop !== undefined && options.draftCrop !== null)\n ? options.draftCrop\n : (crop ?? (isCroppingActive ? {\n x: 0,\n y: 0,\n width: naturalWidth,\n height: naturalHeight,\n } : null));\n\n if (isCroppingActive && activeCrop) {\n this.drawCropOverlay(ctx, state, vpWidth, vpHeight, naturalWidth, naturalHeight, activeCrop);\n }\n }\n\n /**\n * Draws an individual annotation onto the canvas.\n */\n public async drawAnnotation(ctx: CanvasRenderingContext2D, ann: Annotation): Promise<void> {\n ctx.save();\n if (ann.opacity !== undefined) {\n ctx.globalAlpha = ann.opacity;\n }\n\n if (ann.rotation) {\n ctx.translate(ann.x, ann.y);\n ctx.rotate((ann.rotation * Math.PI) / 180);\n ctx.translate(-ann.x, -ann.y);\n }\n\n switch (ann.type) {\n case 'pen': {\n const pen = ann as PenAnnotation;\n if (pen.points.length > 0) {\n ctx.beginPath();\n ctx.strokeStyle = pen.strokeColor;\n ctx.lineWidth = pen.strokeWidth;\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n ctx.moveTo(pen.points[0].x, pen.points[0].y);\n for (let i = 1; i < pen.points.length; i++) {\n ctx.lineTo(pen.points[i].x, pen.points[i].y);\n }\n ctx.stroke();\n }\n break;\n }\n\n case 'rect': {\n const rect = ann as RectAnnotation;\n ctx.strokeStyle = rect.strokeColor;\n ctx.lineWidth = rect.strokeWidth;\n if (rect.fillColor) {\n ctx.fillStyle = rect.fillColor;\n ctx.fillRect(rect.x, rect.y, rect.width, rect.height);\n }\n if (rect.strokeWidth > 0) {\n ctx.strokeRect(rect.x, rect.y, rect.width, rect.height);\n }\n break;\n }\n\n case 'circle': {\n const circle = ann as CircleAnnotation;\n ctx.beginPath();\n ctx.strokeStyle = circle.strokeColor;\n ctx.lineWidth = circle.strokeWidth;\n ctx.ellipse(circle.x, circle.y, Math.abs(circle.radiusX), Math.abs(circle.radiusY), 0, 0, 2 * Math.PI);\n if (circle.fillColor) {\n ctx.fillStyle = circle.fillColor;\n ctx.fill();\n }\n if (circle.strokeWidth > 0) {\n ctx.stroke();\n }\n break;\n }\n\n case 'arrow': {\n const arrow = ann as ArrowAnnotation;\n ctx.strokeStyle = arrow.strokeColor;\n ctx.fillStyle = arrow.strokeColor;\n ctx.lineWidth = arrow.strokeWidth;\n\n // Line body\n ctx.beginPath();\n ctx.moveTo(arrow.x, arrow.y);\n ctx.lineTo(arrow.endX, arrow.endY);\n ctx.stroke();\n\n // Arrow head\n const angle = Math.atan2(arrow.endY - arrow.y, arrow.endX - arrow.x);\n const headLen = Math.max(12, arrow.strokeWidth * 3);\n ctx.beginPath();\n ctx.moveTo(arrow.endX, arrow.endY);\n ctx.lineTo(\n arrow.endX - headLen * Math.cos(angle - Math.PI / 6),\n arrow.endY - headLen * Math.sin(angle - Math.PI / 6)\n );\n ctx.lineTo(\n arrow.endX - headLen * Math.cos(angle + Math.PI / 6),\n arrow.endY - headLen * Math.sin(angle + Math.PI / 6)\n );\n ctx.closePath();\n ctx.fill();\n break;\n }\n\n case 'line': {\n const line = ann as LineAnnotation;\n ctx.beginPath();\n ctx.strokeStyle = line.strokeColor;\n ctx.lineWidth = line.strokeWidth;\n ctx.moveTo(line.x, line.y);\n ctx.lineTo(line.endX, line.endY);\n ctx.stroke();\n break;\n }\n\n case 'text': {\n const textAnn = ann as TextAnnotation;\n ctx.font = `${textAnn.fontWeight || 'normal'} ${textAnn.fontSize}px ${textAnn.fontFamily || 'sans-serif'}`;\n ctx.fillStyle = textAnn.color;\n ctx.textBaseline = 'top';\n ctx.fillText(textAnn.text, textAnn.x, textAnn.y);\n break;\n }\n\n case 'image': {\n const imgAnn = ann as ImageAnnotation;\n try {\n const loadedImg = await this.imageCache.get(imgAnn.src);\n ctx.drawImage(loadedImg, imgAnn.x, imgAnn.y, imgAnn.width, imgAnn.height);\n } catch {\n // Skip if watermark image failed to load\n }\n break;\n }\n }\n\n ctx.restore();\n }\n\n /**\n * Draws selection box around active annotation.\n */\n private drawAnnotationSelection(ctx: CanvasRenderingContext2D, ann: Annotation): void {\n ctx.save();\n ctx.strokeStyle = '#3b82f6'; // Tailwind blue-500\n ctx.lineWidth = 1.5;\n ctx.setLineDash([4, 4]);\n\n const bounds = this.getAnnotationBounds(ann);\n const pad = 4;\n ctx.strokeRect(bounds.x - pad, bounds.y - pad, bounds.width + pad * 2, bounds.height + pad * 2);\n\n // Draw handles\n ctx.fillStyle = '#ffffff';\n ctx.strokeStyle = '#3b82f6';\n ctx.setLineDash([]);\n const handleSize = 6;\n const corners = [\n { x: bounds.x - pad, y: bounds.y - pad },\n { x: bounds.x + bounds.width + pad, y: bounds.y - pad },\n { x: bounds.x - pad, y: bounds.y + bounds.height + pad },\n { x: bounds.x + bounds.width + pad, y: bounds.y + bounds.height + pad },\n ];\n for (const c of corners) {\n ctx.fillRect(c.x - handleSize / 2, c.y - handleSize / 2, handleSize, handleSize);\n ctx.strokeRect(c.x - handleSize / 2, c.y - handleSize / 2, handleSize, handleSize);\n }\n\n ctx.restore();\n }\n\n public getAnnotationBounds(ann: Annotation): { x: number; y: number; width: number; height: number } {\n switch (ann.type) {\n case 'rect':\n return { x: ann.x, y: ann.y, width: ann.width, height: ann.height };\n case 'circle':\n return {\n x: ann.x - Math.abs(ann.radiusX),\n y: ann.y - Math.abs(ann.radiusY),\n width: Math.abs(ann.radiusX) * 2,\n height: Math.abs(ann.radiusY) * 2,\n };\n case 'arrow':\n case 'line': {\n const minX = Math.min(ann.x, ann.endX);\n const minY = Math.min(ann.y, ann.endY);\n return {\n x: minX,\n y: minY,\n width: Math.max(Math.abs(ann.endX - ann.x), 10),\n height: Math.max(Math.abs(ann.endY - ann.y), 10),\n };\n }\n case 'pen': {\n if (!ann.points.length) return { x: ann.x, y: ann.y, width: 0, height: 0 };\n let minX = ann.points[0].x, maxX = ann.points[0].x;\n let minY = ann.points[0].y, maxY = ann.points[0].y;\n for (const pt of ann.points) {\n if (pt.x < minX) minX = pt.x;\n if (pt.x > maxX) maxX = pt.x;\n if (pt.y < minY) minY = pt.y;\n if (pt.y > maxY) maxY = pt.y;\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n }\n case 'text':\n return {\n x: ann.x,\n y: ann.y,\n width: (ann.text.length * ann.fontSize * 0.6),\n height: ann.fontSize * 1.2,\n };\n case 'image':\n return { x: ann.x, y: ann.y, width: ann.width, height: ann.height };\n }\n }\n\n /**\n * Draws a rule-of-thirds crop grid overlay.\n */\n private drawCropOverlay(\n ctx: CanvasRenderingContext2D,\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n imgWidth: number,\n imgHeight: number,\n cropOverride?: CropBox | null\n ): void {\n const crop =\n (cropOverride !== undefined && cropOverride !== null)\n ? cropOverride\n : (state.crop ?? {\n x: 0,\n y: 0,\n width: imgWidth,\n height: imgHeight,\n });\n if (!crop) return;\n\n const { transform, pan, zoom } = state;\n const angle = ((transform.rotate % 360) + 360) % 360;\n const isSwapped = angle === 90 || angle === 270;\n const baseW = isSwapped ? imgHeight : imgWidth;\n const baseH = isSwapped ? imgWidth : imgHeight;\n\n ctx.save();\n ctx.translate(vpWidth / 2 + pan.x, vpHeight / 2 + pan.y);\n ctx.scale(zoom, zoom);\n\n const fitScale = Math.min((vpWidth * 0.85) / baseW, (vpHeight * 0.85) / baseH, 1);\n const renderW = baseW * fitScale;\n const renderH = baseH * fitScale;\n\n const startX = -renderW / 2 + (crop.x / imgWidth) * renderW;\n const startY = -renderH / 2 + (crop.y / imgHeight) * renderH;\n const cropBoxW = (crop.width / imgWidth) * renderW;\n const cropBoxH = (crop.height / imgHeight) * renderH;\n\n // Dark semi-transparent scrim outside crop box\n ctx.fillStyle = 'rgba(0, 0, 0, 0.45)';\n // Top\n ctx.fillRect(-renderW / 2, -renderH / 2, renderW, startY - (-renderH / 2));\n // Bottom\n ctx.fillRect(-renderW / 2, startY + cropBoxH, renderW, renderH / 2 - (startY + cropBoxH));\n // Left\n ctx.fillRect(-renderW / 2, startY, startX - (-renderW / 2), cropBoxH);\n // Right\n ctx.fillRect(startX + cropBoxW, startY, renderW / 2 - (startX + cropBoxW), cropBoxH);\n\n // Crop border\n ctx.strokeStyle = '#ffffff';\n ctx.lineWidth = 2;\n ctx.strokeRect(startX, startY, cropBoxW, cropBoxH);\n\n // Rule of thirds lines\n ctx.strokeStyle = 'rgba(255, 255, 255, 0.4)';\n ctx.lineWidth = 1;\n ctx.beginPath();\n // Vertical lines\n ctx.moveTo(startX + cropBoxW / 3, startY);\n ctx.lineTo(startX + cropBoxW / 3, startY + cropBoxH);\n ctx.moveTo(startX + (cropBoxW * 2) / 3, startY);\n ctx.lineTo(startX + (cropBoxW * 2) / 3, startY + cropBoxH);\n // Horizontal lines\n ctx.moveTo(startX, startY + cropBoxH / 3);\n ctx.lineTo(startX + cropBoxW, startY + cropBoxH / 3);\n ctx.moveTo(startX, startY + (cropBoxH * 2) / 3);\n ctx.lineTo(startX + cropBoxW, startY + (cropBoxH * 2) / 3);\n ctx.stroke();\n\n // Corner and edge handles\n ctx.fillStyle = '#ffffff';\n ctx.strokeStyle = '#0284c7';\n ctx.lineWidth = 1.5;\n const handleSize = 10;\n const handles = [\n // Corners\n { x: startX, y: startY },\n { x: startX + cropBoxW, y: startY },\n { x: startX, y: startY + cropBoxH },\n { x: startX + cropBoxW, y: startY + cropBoxH },\n // Edges\n { x: startX + cropBoxW / 2, y: startY },\n { x: startX + cropBoxW / 2, y: startY + cropBoxH },\n { x: startX, y: startY + cropBoxH / 2 },\n { x: startX + cropBoxW, y: startY + cropBoxH / 2 },\n ];\n for (const h of handles) {\n ctx.fillRect(h.x - handleSize / 2, h.y - handleSize / 2, handleSize, handleSize);\n ctx.strokeRect(h.x - handleSize / 2, h.y - handleSize / 2, handleSize, handleSize);\n }\n\n ctx.restore();\n }\n\n private drawFittedImage(\n ctx: CanvasRenderingContext2D,\n img: CanvasImageSource,\n imgW: number,\n imgH: number,\n vpW: number,\n vpH: number,\n zoom: number,\n pan: { x: number; y: number }\n ): void {\n ctx.save();\n ctx.translate(vpW / 2 + pan.x, vpH / 2 + pan.y);\n ctx.scale(zoom, zoom);\n const fitScale = Math.min((vpW * 0.85) / imgW, (vpH * 0.85) / imgH, 1);\n const renderW = imgW * fitScale;\n const renderH = imgH * fitScale;\n ctx.drawImage(img, -renderW / 2, -renderH / 2, renderW, renderH);\n ctx.restore();\n }\n\n /**\n * Performs an export render at exact pixel dimensions without zoom/pan viewport offsets.\n */\n public async renderExport(\n imageSource: CanvasImageSource | string,\n state: ImageEditorState,\n options: ExportOptions = {}\n ): Promise<HTMLCanvasElement> {\n let img: CanvasImageSource;\n if (typeof imageSource === 'string') {\n img = await this.imageCache.get(imageSource);\n } else {\n img = imageSource;\n }\n\n const naturalWidth = (img as any).naturalWidth || (img as any).videoWidth || (img as any).width || 800;\n const naturalHeight = (img as any).naturalHeight || (img as any).videoHeight || (img as any).height || 600;\n\n const { crop, transform, adjustments, depthMask, annotations } = state;\n\n const cropX = crop ? Math.max(0, crop.x) : 0;\n const cropY = crop ? Math.max(0, crop.y) : 0;\n const cropW = crop ? Math.min(naturalWidth - cropX, crop.width) : naturalWidth;\n const cropH = crop ? Math.min(naturalHeight - cropY, crop.height) : naturalHeight;\n\n const angle = ((transform.rotate % 360) + 360) % 360;\n const isSwapped = angle === 90 || angle === 270;\n const baseW = isSwapped ? cropH : cropW;\n const baseH = isSwapped ? cropW : cropH;\n\n const exportW = options.width || baseW;\n const exportH = options.height || baseH;\n\n const exportCanvas = this.createCanvas(exportW, exportH);\n const ctx = exportCanvas.getContext('2d');\n if (!ctx) return exportCanvas;\n\n // Draw transformed base image\n const intermediateCanvas = this.createCanvas(baseW, baseH);\n const interCtx = intermediateCanvas.getContext('2d');\n if (interCtx) {\n interCtx.save();\n const rad = (angle * Math.PI) / 180;\n interCtx.translate(baseW / 2, baseH / 2);\n interCtx.rotate(rad);\n interCtx.scale(transform.flipH ? -1 : 1, transform.flipV ? -1 : 1);\n interCtx.drawImage(img, cropX, cropY, cropW, cropH, -cropW / 2, -cropH / 2, cropW, cropH);\n interCtx.restore();\n\n // Apply adjustments\n const imageData = interCtx.getImageData(0, 0, baseW, baseH);\n if (imageData) {\n applyAdjustments(imageData, adjustments);\n\n if (depthMask.enabled && depthMask.maskSource) {\n try {\n const maskImg = await this.imageCache.get(depthMask.maskSource);\n const maskCanvas = this.createCanvas(baseW, baseH);\n const maskCtx = maskCanvas.getContext('2d');\n if (maskCtx) {\n maskCtx.drawImage(maskImg, cropX, cropY, cropW, cropH, 0, 0, baseW, baseH);\n const maskData = maskCtx.getImageData(0, 0, baseW, baseH);\n if (maskData) {\n applyDepthMask(imageData, maskData, depthMask);\n }\n }\n } catch {\n // Mask skip\n }\n }\n\n interCtx.putImageData(imageData, 0, 0);\n }\n }\n\n // Scale to target export dimensions\n ctx.drawImage(intermediateCanvas, 0, 0, baseW, baseH, 0, 0, exportW, exportH);\n\n // Draw annotations if included\n if (options.includeAnnotations !== false && annotations.length > 0) {\n const annScaleX = exportW / baseW;\n const annScaleY = exportH / baseH;\n ctx.save();\n ctx.scale(annScaleX, annScaleY);\n for (const ann of annotations) {\n await this.drawAnnotation(ctx, ann);\n }\n ctx.restore();\n }\n\n return exportCanvas;\n }\n\n /**\n * Generates a binary mask canvas (white for mask/selected area, black for unmasked).\n * Useful for AI inpainting and selective generative fill.\n */\n public async renderMask(\n state: ImageEditorState,\n options?: { useAnnotations?: boolean; useCrop?: boolean }\n ): Promise<HTMLCanvasElement> {\n const naturalWidth = state.imageDimensions.width;\n const naturalHeight = state.imageDimensions.height;\n const maskCanvas = this.createCanvas(naturalWidth, naturalHeight);\n const ctx = maskCanvas.getContext('2d');\n if (!ctx) return maskCanvas;\n\n // Background: unmasked (black)\n ctx.fillStyle = '#000000';\n ctx.fillRect(0, 0, naturalWidth, naturalHeight);\n\n const useCrop = options?.useCrop ?? true;\n const useAnnotations = options?.useAnnotations ?? true;\n\n // Crop box mask (if active)\n if (useCrop && state.crop) {\n ctx.fillStyle = '#ffffff';\n ctx.fillRect(state.crop.x, state.crop.y, state.crop.width, state.crop.height);\n }\n\n // Annotation masks (drawn in solid white)\n if (useAnnotations && state.annotations.length > 0) {\n for (const ann of state.annotations) {\n ctx.save();\n if (ann.rotation) {\n ctx.translate(ann.x, ann.y);\n ctx.rotate((ann.rotation * Math.PI) / 180);\n ctx.translate(-ann.x, -ann.y);\n }\n\n if (ann.type === 'pen') {\n const pen = ann as PenAnnotation;\n if (pen.points.length > 0) {\n ctx.beginPath();\n ctx.strokeStyle = '#ffffff';\n ctx.lineWidth = Math.max(pen.strokeWidth, 8);\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n ctx.moveTo(pen.points[0].x, pen.points[0].y);\n for (let i = 1; i < pen.points.length; i++) {\n ctx.lineTo(pen.points[i].x, pen.points[i].y);\n }\n ctx.stroke();\n }\n } else if (ann.type === 'rect') {\n const rect = ann as RectAnnotation;\n ctx.fillStyle = '#ffffff';\n ctx.fillRect(rect.x, rect.y, rect.width, rect.height);\n } else if (ann.type === 'circle') {\n const circ = ann as CircleAnnotation;\n ctx.fillStyle = '#ffffff';\n ctx.beginPath();\n ctx.ellipse(circ.x, circ.y, circ.radiusX, circ.radiusY, 0, 0, Math.PI * 2);\n ctx.fill();\n } else {\n ctx.strokeStyle = '#ffffff';\n ctx.fillStyle = '#ffffff';\n await this.drawAnnotation(ctx, ann);\n }\n ctx.restore();\n }\n }\n\n return maskCanvas;\n }\n}\n\n","import {\n Annotation,\n CreateAnnotationPayload,\n AspectRatio,\n CropBox,\n DepthMaskOptions,\n ExportOptions,\n ImageAdjustments,\n ImageDimensions,\n ImageEditorOptions,\n ImageEditorState,\n ImageEditorTool,\n ImageTransform,\n ImagePoint,\n SerializedImageEditorState,\n} from './types';\nimport { ImageEditorRenderer, RenderOptions } from './renderer';\n\nexport const DEFAULT_ADJUSTMENTS: ImageAdjustments = {\n brightness: 0,\n contrast: 0,\n saturation: 0,\n exposure: 0,\n temperature: 0,\n blur: 0,\n opacity: 1,\n};\n\nexport const DEFAULT_TRANSFORM: ImageTransform = {\n rotate: 0,\n flipH: false,\n flipV: false,\n};\n\nexport const DEFAULT_DEPTH_MASK: DepthMaskOptions = {\n enabled: false,\n maskSource: null,\n mode: 'threshold',\n depthRange: [0, 255],\n softness: 10,\n invert: false,\n};\n\n/**\n * ImageEditorController manages the complete lifecycle, canvas rendering pipeline,\n * tool interaction states, undo/redo history, serialization, and image export.\n */\nexport class ImageEditorController {\n private state: ImageEditorState;\n private renderer: ImageEditorRenderer;\n private imageElement: CanvasImageSource | null = null;\n private listeners = new Set<(state: ImageEditorState) => void>();\n private onStateChange?: (state: ImageEditorState) => void;\n\n // History stacks\n private undoStack: SerializedImageEditorState[] = [];\n private redoStack: SerializedImageEditorState[] = [];\n private maxHistoryDepth: number;\n private isApplyingHistory = false;\n private initialSnapshot: SerializedImageEditorState;\n\n constructor(options: ImageEditorOptions = {}) {\n this.maxHistoryDepth = options.maxHistoryDepth ?? 50;\n this.onStateChange = options.onStateChange;\n this.renderer = new ImageEditorRenderer();\n\n const initialAdjustments: ImageAdjustments = {\n ...DEFAULT_ADJUSTMENTS,\n ...options.initialState?.adjustments,\n };\n\n const initialTransform: ImageTransform = {\n ...DEFAULT_TRANSFORM,\n ...options.initialState?.transform,\n };\n\n const initialDepthMask: DepthMaskOptions = {\n ...DEFAULT_DEPTH_MASK,\n ...options.initialState?.depthMask,\n };\n\n this.state = {\n sourceUrl: typeof options.image === 'string' ? options.image : null,\n imageDimensions: { width: 800, height: 600 },\n crop: options.initialState?.crop ?? null,\n transform: initialTransform,\n adjustments: initialAdjustments,\n depthMask: initialDepthMask,\n annotations: options.initialState?.annotations ?? [],\n selectedAnnotationId: null,\n activeTool: 'select',\n zoom: 1,\n pan: { x: 0, y: 0 },\n isOriginalCompared: false,\n };\n\n if (options.image instanceof Object && 'width' in options.image) {\n this.imageElement = options.image as CanvasImageSource;\n this.state.imageDimensions = {\n width: (options.image as any).naturalWidth || (options.image as any).width || 800,\n height: (options.image as any).naturalHeight || (options.image as any).height || 600,\n };\n }\n\n this.initialSnapshot = this.serializeState();\n\n if (typeof options.image === 'string') {\n this.loadImage(options.image);\n }\n }\n\n // --- Image Loading ---\n\n public async loadImage(src: string | HTMLImageElement): Promise<void> {\n if (typeof src === 'string') {\n this.state.sourceUrl = src;\n try {\n const img = await this.renderer.imageCache.get(src);\n this.imageElement = img;\n this.state.imageDimensions = {\n width: img.naturalWidth || img.width || 800,\n height: img.naturalHeight || img.height || 600,\n };\n } catch (err) {\n // In SSR / non-DOM environments, retain default dimensions\n }\n } else {\n this.imageElement = src;\n this.state.sourceUrl = (src as any).src || null;\n this.state.imageDimensions = {\n width: src.naturalWidth || src.width || 800,\n height: src.naturalHeight || src.height || 600,\n };\n }\n\n this.initialSnapshot = this.serializeState();\n this.notify();\n }\n\n public getImageElement(): CanvasImageSource | null {\n return this.imageElement;\n }\n\n // --- State & Subscription ---\n\n public getState(): ImageEditorState {\n return this.state;\n }\n\n public subscribe(listener: (state: ImageEditorState) => void): () => void {\n this.listeners.add(listener);\n listener(this.state);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private notify(): void {\n const currentState = { ...this.state };\n this.onStateChange?.(currentState);\n this.listeners.forEach((l) => l(currentState));\n }\n\n // --- History (Undo / Redo / Reset) ---\n\n private recordHistory(): void {\n if (this.isApplyingHistory) return;\n this.undoStack.push(this.serializeState());\n if (this.undoStack.length > this.maxHistoryDepth) {\n this.undoStack.shift();\n }\n this.redoStack = [];\n }\n\n public get canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n public get canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n public undo(): boolean {\n if (!this.canUndo) return false;\n this.isApplyingHistory = true;\n const current = this.serializeState();\n this.redoStack.push(current);\n\n const prev = this.undoStack.pop()!;\n this.applySerializedState(prev);\n this.isApplyingHistory = false;\n this.notify();\n return true;\n }\n\n public redo(): boolean {\n if (!this.canRedo) return false;\n this.isApplyingHistory = true;\n const current = this.serializeState();\n this.undoStack.push(current);\n\n const next = this.redoStack.pop()!;\n this.applySerializedState(next);\n this.isApplyingHistory = false;\n this.notify();\n return true;\n }\n\n public reset(): void {\n this.recordHistory();\n this.applySerializedState(this.initialSnapshot);\n this.state.zoom = 1;\n this.state.pan = { x: 0, y: 0 };\n this.state.activeTool = 'select';\n this.state.selectedAnnotationId = null;\n this.notify();\n }\n\n // --- Active Tool ---\n\n public setTool(tool: ImageEditorTool): void {\n if (this.state.activeTool === tool) return;\n this.state.activeTool = tool;\n if (tool !== 'select') {\n this.state.selectedAnnotationId = null;\n }\n // If switching to crop tool and no crop is defined, initialize crop to full image\n if (tool === 'crop' && !this.state.crop) {\n this.state.crop = {\n x: 0,\n y: 0,\n width: this.state.imageDimensions.width,\n height: this.state.imageDimensions.height,\n };\n }\n this.notify();\n }\n\n // --- Crop ---\n\n public setCrop(crop: CropBox | null, addToHistory = true): void {\n if (addToHistory) {\n this.recordHistory();\n }\n this.state.crop = crop;\n this.notify();\n }\n\n public applyCropPreset(ratio: AspectRatio): void {\n this.recordHistory();\n const { width, height } = this.state.imageDimensions;\n if (!ratio) {\n // Freeform: full image\n this.state.crop = { x: 0, y: 0, width, height };\n } else {\n let targetW = width;\n let targetH = targetW / ratio;\n\n if (targetH > height) {\n targetH = height;\n targetW = targetH * ratio;\n }\n\n const x = Math.max(0, Math.round((width - targetW) / 2));\n const y = Math.max(0, Math.round((height - targetH) / 2));\n this.state.crop = {\n x,\n y,\n width: Math.round(targetW),\n height: Math.round(targetH),\n };\n }\n this.notify();\n }\n\n public resetCrop(): void {\n this.recordHistory();\n this.state.crop = null;\n this.notify();\n }\n\n // --- Transformations (Rotate / Flip) ---\n\n public rotate(degrees: number): void {\n this.recordHistory();\n const current = this.state.transform.rotate;\n this.state.transform.rotate = (current + degrees) % 360;\n this.notify();\n }\n\n public setRotation(degrees: number): void {\n this.recordHistory();\n this.state.transform.rotate = degrees % 360;\n this.notify();\n }\n\n public flipHorizontal(): void {\n this.recordHistory();\n this.state.transform.flipH = !this.state.transform.flipH;\n this.notify();\n }\n\n public flipVertical(): void {\n this.recordHistory();\n this.state.transform.flipV = !this.state.transform.flipV;\n this.notify();\n }\n\n // --- Adjustments ---\n\n public setAdjustments(partial: Partial<ImageAdjustments>, commitToHistory = true): void {\n if (commitToHistory) {\n this.recordHistory();\n }\n this.state.adjustments = {\n ...this.state.adjustments,\n ...partial,\n };\n this.notify();\n }\n\n public resetAdjustments(): void {\n this.recordHistory();\n this.state.adjustments = { ...DEFAULT_ADJUSTMENTS };\n this.notify();\n }\n\n // --- Depth Masking (Gleamforge) ---\n\n public setDepthMask(partial: Partial<DepthMaskOptions>): void {\n this.recordHistory();\n this.state.depthMask = {\n ...this.state.depthMask,\n ...partial,\n };\n this.notify();\n }\n\n public resetDepthMask(): void {\n this.recordHistory();\n this.state.depthMask = { ...DEFAULT_DEPTH_MASK };\n this.notify();\n }\n\n // --- Annotations & Layers ---\n\n public addAnnotation(annotation: CreateAnnotationPayload): string {\n this.recordHistory();\n const id = `ann_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;\n const fullAnnotation = { ...annotation, id } as Annotation;\n this.state.annotations = [...this.state.annotations, fullAnnotation];\n this.state.selectedAnnotationId = id;\n this.notify();\n return id;\n }\n\n public updateAnnotation(id: string, partial: Partial<Annotation>, commitToHistory = true): void {\n if (commitToHistory) {\n this.recordHistory();\n }\n this.state.annotations = this.state.annotations.map((ann) => {\n if (ann.id === id) {\n return { ...ann, ...partial } as Annotation;\n }\n return ann;\n });\n this.notify();\n }\n\n public removeAnnotation(id: string): void {\n this.recordHistory();\n this.state.annotations = this.state.annotations.filter((ann) => ann.id !== id);\n if (this.state.selectedAnnotationId === id) {\n this.state.selectedAnnotationId = null;\n }\n this.notify();\n }\n\n public clearAnnotations(): void {\n this.recordHistory();\n this.state.annotations = [];\n this.state.selectedAnnotationId = null;\n this.notify();\n }\n\n public selectAnnotation(id: string | null): void {\n this.state.selectedAnnotationId = id;\n this.notify();\n }\n\n // --- Zoom & Pan ---\n\n public setZoom(zoom: number): void {\n this.state.zoom = Math.max(0.1, Math.min(10, zoom));\n this.notify();\n }\n\n public zoomIn(factor = 1.2): void {\n this.setZoom(this.state.zoom * factor);\n }\n\n public zoomOut(factor = 1.2): void {\n this.setZoom(this.state.zoom / factor);\n }\n\n public resetZoom(): void {\n this.state.zoom = 1;\n this.state.pan = { x: 0, y: 0 };\n this.notify();\n }\n\n public setPan(pan: ImagePoint): void {\n this.state.pan = pan;\n this.notify();\n }\n\n public setComparing(comparing: boolean): void {\n if (this.state.isOriginalCompared === comparing) return;\n this.state.isOriginalCompared = comparing;\n this.notify();\n }\n\n // --- Rendering & Export ---\n\n public async render(targetCanvas: HTMLCanvasElement, options?: RenderOptions): Promise<void> {\n const source = this.imageElement || this.state.sourceUrl;\n if (!source) return;\n try {\n await this.renderer.renderToCanvas(targetCanvas, source, this.state, options);\n } catch {\n // In non-DOM or test mock environments without image loading, safely ignore\n }\n }\n\n public async renderExport(options?: ExportOptions): Promise<HTMLCanvasElement> {\n const source = this.imageElement || this.state.sourceUrl;\n if (!source) {\n return this.renderer.createCanvas(1, 1);\n }\n return this.renderer.renderExport(source, this.state, options);\n }\n\n public async toDataURL(options: ExportOptions = {}): Promise<string> {\n const canvas = await this.renderExport(options);\n const format = options.format || 'image/png';\n const quality = options.quality ?? 0.92;\n return canvas.toDataURL(format, quality);\n }\n\n public async toBlob(options: ExportOptions = {}): Promise<Blob> {\n const canvas = await this.renderExport(options);\n const format = options.format || 'image/png';\n const quality = options.quality ?? 0.92;\n\n return new Promise((resolve, reject) => {\n if (canvas.toBlob) {\n canvas.toBlob((blob) => {\n if (blob) resolve(blob);\n else reject(new Error('Failed to create Blob from canvas'));\n }, format, quality);\n } else {\n // Fallback for environments lacking canvas.toBlob\n try {\n const dataUrl = canvas.toDataURL(format, quality);\n const parts = dataUrl.split(',');\n const byteStr = atob(parts[1]);\n const ab = new ArrayBuffer(byteStr.length);\n const ia = new Uint8Array(ab);\n for (let i = 0; i < byteStr.length; i++) {\n ia[i] = byteStr.charCodeAt(i);\n }\n resolve(new Blob([ab], { type: format }));\n } catch (err) {\n reject(err);\n }\n }\n });\n }\n\n // --- AI Masking & Transformation Helpers ---\n\n public async renderMask(options?: { useAnnotations?: boolean; useCrop?: boolean }): Promise<HTMLCanvasElement> {\n return this.renderer.renderMask(this.state, options);\n }\n\n public async toMaskDataURL(options?: { useAnnotations?: boolean; useCrop?: boolean }): Promise<string> {\n const canvas = await this.renderMask(options);\n return canvas.toDataURL('image/png');\n }\n\n public async applyInpaintedImage(newDataUrl: string): Promise<void> {\n this.recordHistory();\n await this.loadImage(newDataUrl);\n this.clearAnnotations();\n }\n\n public async applyBackgroundRemovedImage(newDataUrl: string): Promise<void> {\n this.recordHistory();\n await this.loadImage(newDataUrl);\n }\n\n\n // --- Serialization ---\n\n public toJSON(): SerializedImageEditorState {\n return this.serializeState();\n }\n\n public loadJSON(data: SerializedImageEditorState): void {\n this.recordHistory();\n this.applySerializedState(data);\n this.notify();\n }\n\n private serializeState(): SerializedImageEditorState {\n return {\n version: 1,\n crop: this.state.crop ? { ...this.state.crop } : null,\n transform: { ...this.state.transform },\n adjustments: { ...this.state.adjustments },\n depthMask: {\n ...this.state.depthMask,\n depthRange: [...this.state.depthMask.depthRange] as [number, number],\n },\n annotations: JSON.parse(JSON.stringify(this.state.annotations)),\n };\n }\n\n private applySerializedState(data: SerializedImageEditorState): void {\n this.state.crop = data.crop ? { ...data.crop } : null;\n this.state.transform = { ...data.transform };\n this.state.adjustments = { ...data.adjustments };\n this.state.depthMask = {\n ...data.depthMask,\n depthRange: [...data.depthMask.depthRange] as [number, number],\n };\n this.state.annotations = JSON.parse(JSON.stringify(data.annotations || []));\n }\n}\n","import type { CropBox, ImageEditorState, ImagePoint } from './types';\n\nexport type CropHandle = 'nw' | 'ne' | 'se' | 'sw' | 'n' | 's' | 'e' | 'w' | 'inside' | null;\n\nexport interface ViewportMetrics {\n vpWidth: number;\n vpHeight: number;\n centerX: number;\n centerY: number;\n baseW: number;\n baseH: number;\n fitScale: number;\n renderW: number;\n renderH: number;\n totalScale: number;\n imageRect: { x: number; y: number; width: number; height: number };\n cropRect: { x: number; y: number; width: number; height: number } | null;\n}\n\n/**\n * Calculates current viewport projection metrics for canvas <-> image coordinate mapping.\n */\nexport function getViewportMetrics(\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping = false,\n cropOverride?: CropBox | null\n): ViewportMetrics {\n const { imageDimensions, crop: stateCrop, transform, zoom, pan } = state;\n const naturalWidth = imageDimensions.width || 800;\n const naturalHeight = imageDimensions.height || 600;\n const activeCrop =\n (cropOverride !== undefined && cropOverride !== null)\n ? cropOverride\n : (stateCrop ?? (isActivelyCropping ? { x: 0, y: 0, width: naturalWidth, height: naturalHeight } : null));\n\n const cropW = (!isActivelyCropping && activeCrop) ? activeCrop.width : naturalWidth;\n const cropH = (!isActivelyCropping && activeCrop) ? activeCrop.height : naturalHeight;\n\n const angle = ((transform.rotate % 360) + 360) % 360;\n const isSwapped = angle === 90 || angle === 270;\n const baseW = isSwapped ? cropH : cropW;\n const baseH = isSwapped ? cropW : cropH;\n\n const fitScale = Math.min((vpWidth * 0.85) / baseW, (vpHeight * 0.85) / baseH, 1);\n const renderW = baseW * fitScale;\n const renderH = baseH * fitScale;\n const totalScale = zoom * fitScale;\n\n const centerX = vpWidth / 2 + pan.x;\n const centerY = vpHeight / 2 + pan.y;\n\n const imageRect = {\n x: centerX - (renderW * zoom) / 2,\n y: centerY - (renderH * zoom) / 2,\n width: renderW * zoom,\n height: renderH * zoom,\n };\n\n let cropRect: { x: number; y: number; width: number; height: number } | null = null;\n if (activeCrop) {\n const startX = -renderW / 2 + (activeCrop.x / naturalWidth) * renderW;\n const startY = -renderH / 2 + (activeCrop.y / naturalHeight) * renderH;\n const cropBoxW = (activeCrop.width / naturalWidth) * renderW;\n const cropBoxH = (activeCrop.height / naturalHeight) * renderH;\n\n cropRect = {\n x: centerX + zoom * startX,\n y: centerY + zoom * startY,\n width: zoom * cropBoxW,\n height: zoom * cropBoxH,\n };\n }\n\n return {\n vpWidth,\n vpHeight,\n centerX,\n centerY,\n baseW,\n baseH,\n fitScale,\n renderW,\n renderH,\n totalScale,\n imageRect,\n cropRect,\n };\n}\n\n/**\n * Converts a point on the canvas (in internal canvas pixel space) to image/annotation pixel space.\n */\nexport function canvasToImagePoint(\n canvasPt: ImagePoint,\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping = false\n): ImagePoint {\n const metrics = getViewportMetrics(state, vpWidth, vpHeight, isActivelyCropping);\n const unzoomedX = (canvasPt.x - metrics.centerX) / state.zoom;\n const unzoomedY = (canvasPt.y - metrics.centerY) / state.zoom;\n\n const x = (unzoomedX + metrics.renderW / 2) / metrics.fitScale;\n const y = (unzoomedY + metrics.renderH / 2) / metrics.fitScale;\n\n return { x: Math.round(x), y: Math.round(y) };\n}\n\n/**\n * Converts a point in image/annotation pixel space to internal canvas pixel space.\n */\nexport function imageToCanvasPoint(\n imgPt: ImagePoint,\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping = false\n): ImagePoint {\n const metrics = getViewportMetrics(state, vpWidth, vpHeight, isActivelyCropping);\n const unzoomedX = (imgPt.x - metrics.baseW / 2) * metrics.fitScale;\n const unzoomedY = (imgPt.y - metrics.baseH / 2) * metrics.fitScale;\n\n const canvasX = metrics.centerX + unzoomedX * state.zoom;\n const canvasY = metrics.centerY + unzoomedY * state.zoom;\n\n return { x: Math.round(canvasX), y: Math.round(canvasY) };\n}\n\n/**\n * Hit-tests the crop box and its corner/edge handles given a canvas point.\n */\nexport function hitTestCrop(\n canvasPt: ImagePoint,\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n handleThreshold = 14,\n cropOverride?: CropBox | null\n): CropHandle {\n const metrics = getViewportMetrics(state, vpWidth, vpHeight, true, cropOverride);\n if (!metrics.cropRect) return null;\n\n const { x, y, width: w, height: h } = metrics.cropRect;\n const px = canvasPt.x;\n const py = canvasPt.y;\n\n // 1. Corners (highest priority)\n const dist = (x1: number, y1: number, x2: number, y2: number) =>\n Math.hypot(x1 - x2, y1 - y2);\n\n if (dist(px, py, x, y) <= handleThreshold) return 'nw';\n if (dist(px, py, x + w, y) <= handleThreshold) return 'ne';\n if (dist(px, py, x + w, y + h) <= handleThreshold) return 'se';\n if (dist(px, py, x, y + h) <= handleThreshold) return 'sw';\n\n // 2. Edges\n const nearX = px >= x - handleThreshold && px <= x + w + handleThreshold;\n const nearY = py >= y - handleThreshold && py <= y + h + handleThreshold;\n\n if (nearX && Math.abs(py - y) <= handleThreshold) return 'n';\n if (nearX && Math.abs(py - (y + h)) <= handleThreshold) return 's';\n if (nearY && Math.abs(px - x) <= handleThreshold) return 'w';\n if (nearY && Math.abs(px - (x + w)) <= handleThreshold) return 'e';\n\n // 3. Inside crop region\n if (px >= x && px <= x + w && py >= y && py <= y + h) {\n return 'inside';\n }\n\n return null;\n}\n\n/**\n * Returns CSS cursor style corresponding to a crop handle.\n */\nexport function getCropCursor(handle: CropHandle): string {\n switch (handle) {\n case 'nw':\n case 'se':\n return 'nwse-resize';\n case 'ne':\n case 'sw':\n return 'nesw-resize';\n case 'n':\n case 's':\n return 'ns-resize';\n case 'e':\n case 'w':\n return 'ew-resize';\n case 'inside':\n return 'move';\n default:\n return 'crosshair';\n }\n}\n\n/**\n * Calculates updated crop rectangle given a drag interaction.\n */\nexport function calculateCropDrag(\n startCrop: CropBox,\n handle: CropHandle,\n startImgPt: ImagePoint,\n currentImgPt: ImagePoint,\n imgWidth: number,\n imgHeight: number,\n aspectRatio?: number | null\n): CropBox {\n const dx = currentImgPt.x - startImgPt.x;\n const dy = currentImgPt.y - startImgPt.y;\n\n // Whole crop box move\n if (handle === 'inside') {\n const maxX = Math.max(0, imgWidth - startCrop.width);\n const maxY = Math.max(0, imgHeight - startCrop.height);\n const newX = Math.max(0, Math.min(maxX, startCrop.x + dx));\n const newY = Math.max(0, Math.min(maxY, startCrop.y + dy));\n return {\n x: Math.round(newX),\n y: Math.round(newY),\n width: startCrop.width,\n height: startCrop.height,\n };\n }\n\n // Handle resizing\n let left = startCrop.x;\n let top = startCrop.y;\n let right = startCrop.x + startCrop.width;\n let bottom = startCrop.y + startCrop.height;\n\n const minSize = 20;\n\n if (handle === 'e' || handle === 'ne' || handle === 'se') {\n right = Math.min(imgWidth, Math.max(left + minSize, startCrop.x + startCrop.width + dx));\n }\n if (handle === 'w' || handle === 'nw' || handle === 'sw') {\n left = Math.max(0, Math.min(right - minSize, startCrop.x + dx));\n }\n if (handle === 's' || handle === 'se' || handle === 'sw') {\n bottom = Math.min(imgHeight, Math.max(top + minSize, startCrop.y + startCrop.height + dy));\n }\n if (handle === 'n' || handle === 'nw' || handle === 'ne') {\n top = Math.max(0, Math.min(bottom - minSize, startCrop.y + dy));\n }\n\n // Maintain aspect ratio if requested\n if (aspectRatio && aspectRatio > 0) {\n let currentW = right - left;\n let currentH = bottom - top;\n\n if (handle === 'e' || handle === 'w') {\n currentH = Math.min(imgHeight, currentW / aspectRatio);\n bottom = Math.min(imgHeight, top + currentH);\n } else if (handle === 'n' || handle === 's') {\n currentW = Math.min(imgWidth, currentH * aspectRatio);\n right = Math.min(imgWidth, left + currentW);\n } else {\n // Corner resizing\n const targetH = currentW / aspectRatio;\n if (top + targetH <= imgHeight) {\n bottom = top + targetH;\n } else {\n const targetW = currentH * aspectRatio;\n right = Math.min(imgWidth, left + targetW);\n }\n }\n }\n\n return {\n x: Math.round(left),\n y: Math.round(top),\n width: Math.round(Math.max(minSize, right - left)),\n height: Math.round(Math.max(minSize, bottom - top)),\n };\n}\n\n/**\n * Calculates bounding box of an annotation.\n */\nexport function getAnnotationBounds(ann: import('./types').Annotation): { x: number; y: number; width: number; height: number } {\n switch (ann.type) {\n case 'rect':\n return { x: ann.x, y: ann.y, width: ann.width, height: ann.height };\n case 'circle':\n return {\n x: ann.x - ann.radiusX,\n y: ann.y - ann.radiusY,\n width: ann.radiusX * 2,\n height: ann.radiusY * 2,\n };\n case 'arrow':\n case 'line': {\n const minX = Math.min(ann.x, ann.endX);\n const minY = Math.min(ann.y, ann.endY);\n return {\n x: minX,\n y: minY,\n width: Math.max(Math.abs(ann.endX - ann.x), 10),\n height: Math.max(Math.abs(ann.endY - ann.y), 10),\n };\n }\n case 'pen': {\n if (!ann.points.length) return { x: ann.x, y: ann.y, width: 0, height: 0 };\n let minX = ann.points[0].x;\n let maxX = ann.points[0].x;\n let minY = ann.points[0].y;\n let maxY = ann.points[0].y;\n for (const pt of ann.points) {\n if (pt.x < minX) minX = pt.x;\n if (pt.x > maxX) maxX = pt.x;\n if (pt.y < minY) minY = pt.y;\n if (pt.y > maxY) maxY = pt.y;\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n }\n case 'text':\n return {\n x: ann.x,\n y: ann.y,\n width: ann.text.length * ann.fontSize * 0.6,\n height: ann.fontSize * 1.2,\n };\n case 'image':\n return { x: ann.x, y: ann.y, width: ann.width, height: ann.height };\n }\n}\n\n/**\n * Hit tests if a point in image space is within an annotation's bounds.\n */\nexport function hitTestAnnotation(imgPt: ImagePoint, ann: import('./types').Annotation, padding = 10): boolean {\n const b = getAnnotationBounds(ann);\n return (\n imgPt.x >= b.x - padding &&\n imgPt.x <= b.x + b.width + padding &&\n imgPt.y >= b.y - padding &&\n imgPt.y <= b.y + b.height + padding\n );\n}\n\n"],"mappings":"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","names":["overlaps","Plugin","Extension","Node","Extension","Extension","Plugin","Decoration","DecorationSet","Extension","MarkdownTightLists","Extension","create","name","addOptions","tight","tightClass","listTypes","addGlobalAttributes","types","options","attributes","default","parseHTML","element","getAttribute","querySelector","renderHTML","class","addCommands","_this","toggleTight","arguments","length","undefined","_ref","editor","commands","isActive","attrs","getAttributes","updateAttributes","some","md","markdownit","scanDelims","text","pos","inline","State","prototype","call","src","posMax","state","shiftDelim","delim","start","offset","res","substring","trimStart","from","to","can_open","trimEnd","can_close","trimInline","MarkdownSerializerState","BaseMarkdownSerializerState","constructor","nodes","marks","inTable","inlines","render","node","parent","index","top","end","delimiter","normalizeInline","out","pop","markString","mark","open","info","type","expelEnclosingWhitespace","push","charAt","match","Mark","addStorage","markdown","serialize","_getMarkTags$","_getMarkTags","storage","html","console","warn","getMarkTags","close","_getMarkTags$2","_getMarkTags2","parse","schema","getHTMLFromFragment","Fragment","elementFromString","value","wrappedValue","window","DOMParser","parseFromString","body","escapeHTML","replace","extractElement","parentElement","prepend","cloneNode","firstChild","appendChild","childNodes","insertBefore","remove","unwrapElement","parentNode","removeChild","Node","write","serializeHTML","isBlock","closeBlock","topNodeType","formatBlock","dom","firstElementChild","innerHTML","trim","outerHTML","Blockquote","extend","defaultMarkdownSerializer","blockquote","BulletList","renderList","bulletListMarker","CodeBlock","language","textContent","ensureNewLine","setup","_this$options$languag","set","langPrefix","languageClassPrefix","updateDOM","HardBreak","i","childCount","child","HTMLNode","Heading","heading","HorizontalRule","horizontal_rule","Image","image","ListItem","list_item","OrderedList","findIndexOfAdjacentNode","maxW","String","space","repeat","adjacentIndex","separator","nStr","Paragraph","paragraph","_node$content$content","_node$content","content","Table","isMarkdownSerializable","forEach","row","p","col","j","cellContent","renderInline","delimiterRow","Array","map","join","hasSpan","colspan","rowspan","rows","firstRow","bodyRows","slice","cell","TaskItem","check","checked","renderContent","querySelectorAll","item","input","setAttribute","TaskList","use","taskListPlugin","list","Text","Bold","strong","Code","code","Italic","em","Link","link","Strike","HTMLMark","getMarkdownSpec","extension","_extension$storage","_markdownExtensions$f","markdownSpec","defaultMarkdownSpec","markdownExtensions","find","e","MarkdownSerializer","hardBreakNodeName","_this$editor$extensio","Object","fromEntries","keys","serializeNode","extensionManager","extensions","filter","_this$editor$extensio2","serializeMark","_getMarkdownSpec","bind","_getMarkdownSpec2","MarkdownParser","linkify","breaks","withPatchedRenderer","renderedHTML","normalizeDOM","_ref2","normalizeBlocks","el","_el$nextSibling","nextSibling","nodeType","TEXT_NODE","closest","blocks","values","selector","block","_block$spec$parseDOM","spec","parseDOM","tag","flat","Boolean","matches","_node$firstElementChi","_content$match$","_content$match","_content$match$2","_content$match2","firstParagraph","nextElementSibling","startSpaces","endSpaces","withoutNewLine","renderer","rendered","rules","hardbreak","softbreak","fence","code_block","renderToken","MarkdownClipboard","transformPastedText","transformCopiedText","addProseMirrorPlugins","Plugin","key","PluginKey","props","clipboardTextParser","context","plainText","parsed","parser","fromSchema","parseSlice","preserveWhitespace","clipboardTextSerializer","serializer","Markdown","priority","tightLists","tightListClass","Commands","config","setContent","emitUpdate","parseOptions","insertContentAt","range","onBeforeCreate","getMarkdown","doc","initialContent","onCreate","addExtensions","configure","Markdown","Plugin","PluginKey","resolveExt","Image","resolveExt","Link","TaskList","TaskItem","extensions","Markdown","Image","match","md","Fragment","Fragment","extensions","document","dagre","childNodes"]}
|