@sendbird/actionbook-core 0.7.2 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ui/schema.ts","../../src/ui/plugin/registry.ts","../../src/ui/components/ActionbookRenderer.tsx","../../src/ui/components/icons.tsx","../../src/ui/components/EditorShell.tsx","../../src/ui/nodeView/ReactNodeView.ts","../../src/ui/hooks/useEditorView.ts","../../src/compat/prosemirror.ts","../../src/markdown/serializer.ts","../../node_modules/devlop/lib/default.js","../../node_modules/micromark-util-normalize-identifier/index.js","../../node_modules/mdast-util-gfm-footnote/lib/index.js","../../node_modules/mdast-util-gfm-strikethrough/lib/index.js","../../node_modules/markdown-table/index.js","../../node_modules/mdast-util-gfm-table/lib/index.js","../../node_modules/mdast-util-gfm-task-list-item/lib/index.js","../../src/markdown/plugins/resourceTag.ts","../../src/markdown/plugins/jumpPoint.ts","../../src/markdown/mdastAdapter.ts","../../src/ui/bridge/toProseMirrorJSON.ts","../../src/ui/plugin/inputRulesPlugin.ts","../../src/ui/plugin/keymapPlugin.ts","../../src/ui/plugin/markdownClipboard.ts","../../src/ast/traverse.ts","../../src/markdown/parser.ts","../../node_modules/micromark-util-chunked/index.js","../../node_modules/micromark-util-combine-extensions/index.js","../../node_modules/micromark-util-classify-character/index.js","../../node_modules/micromark-util-resolve-all/index.js","../../node_modules/micromark-factory-space/index.js","../../node_modules/micromark-core-commonmark/lib/blank-line.js","../../node_modules/micromark-extension-gfm-footnote/lib/syntax.js","../../node_modules/micromark-extension-gfm-strikethrough/lib/syntax.js","../../node_modules/micromark-extension-gfm-table/lib/syntax.js","../../node_modules/micromark-extension-gfm-table/lib/edit-map.js","../../node_modules/micromark-extension-gfm-table/lib/infer.js","../../node_modules/micromark-extension-gfm-task-list-item/lib/syntax.js","../../src/markdown/plugins/jinjaBlock.ts","../../src/markdown/fragment.ts","../../src/jinja/scanner.ts","../../src/jinja/structurer.ts","../../src/jinja/analyzer.ts","../../src/ui/plugin/jumpPointPlugin.ts","../../src/ui/plugin/jumpPointNodeViewPlugin.tsx","../../src/ui/plugin/inlineToolTagNodeViewPlugin.tsx","../../src/ui/plugin/jinjaDecoration.ts","../../src/ui/plugin/linkPlugin.ts","../../src/ui/plugin/dragHandlePlugin.ts","../../src/ui/plugin/todoNodeViewPlugin.tsx","../../src/ui/plugin/slashCommandPlugin.ts","../../src/ui/components/SlashCommandMenu.tsx","../../src/ui/components/JinjaTreeView.tsx","../../src/ui/components/FloatingMenu.tsx","../../src/ui/plugin/inlineSuggestPlugin.ts"],"sourcesContent":["import { Schema } from 'prosemirror-model';\n\n/**\n * ProseMirror Schema for Actionbook documents.\n */\nexport const actionbookSchema = new Schema({\n nodes: {\n doc: {\n content: 'block*',\n },\n\n paragraph: {\n content: 'inline*',\n group: 'block',\n parseDOM: [{ tag: 'p' }],\n toDOM() {\n return ['p', 0];\n },\n },\n\n heading: {\n content: 'inline*',\n group: 'block',\n attrs: { level: { default: 1 } },\n parseDOM: [\n { tag: 'h1', attrs: { level: 1 } },\n { tag: 'h2', attrs: { level: 2 } },\n { tag: 'h3', attrs: { level: 3 } },\n { tag: 'h4', attrs: { level: 4 } },\n { tag: 'h5', attrs: { level: 5 } },\n { tag: 'h6', attrs: { level: 6 } },\n ],\n toDOM(node) {\n return [`h${node.attrs.level}`, 0];\n },\n },\n\n bulletList: {\n content: 'listItem+',\n group: 'block',\n parseDOM: [{ tag: 'ul' }],\n toDOM() {\n return ['ul', 0];\n },\n },\n\n orderedList: {\n content: 'listItem+',\n group: 'block',\n attrs: { start: { default: 1 } },\n parseDOM: [\n {\n tag: 'ol',\n getAttrs(dom) {\n return { start: (dom as HTMLOListElement).start || 1 };\n },\n },\n ],\n toDOM(node) {\n return node.attrs.start === 1 ? ['ol', 0] : ['ol', { start: node.attrs.start }, 0];\n },\n },\n\n listItem: {\n content: 'block+',\n attrs: { checked: { default: null } },\n parseDOM: [\n {\n tag: 'li',\n getAttrs(dom) {\n const el = dom as HTMLLIElement;\n const checkbox = el.querySelector('input[type=\"checkbox\"]');\n if (checkbox) {\n return { checked: (checkbox as HTMLInputElement).checked };\n }\n if (el.dataset.checked != null) {\n return { checked: el.dataset.checked === 'true' };\n }\n return { checked: null };\n },\n },\n ],\n toDOM(node) {\n if (node.attrs.checked != null) {\n return ['li', { class: 'todo-item', 'data-checked': String(node.attrs.checked) }, 0];\n }\n return ['li', 0];\n },\n defining: true,\n },\n\n blockquote: {\n content: 'block+',\n group: 'block',\n parseDOM: [{ tag: 'blockquote' }],\n toDOM() {\n return ['blockquote', 0];\n },\n defining: true,\n },\n\n horizontalRule: {\n group: 'block',\n parseDOM: [{ tag: 'hr' }],\n toDOM() {\n return ['hr'];\n },\n },\n\n // ── Table nodes ──\n\n table: {\n content: 'tableRow+',\n group: 'block',\n tableRole: 'table',\n isolating: true,\n parseDOM: [{ tag: 'table' }],\n toDOM() {\n return ['table', ['tbody', 0]];\n },\n },\n\n tableRow: {\n content: '(tableCell | tableHeader)+',\n tableRole: 'row',\n parseDOM: [{ tag: 'tr' }],\n toDOM() {\n return ['tr', 0];\n },\n },\n\n tableCell: {\n content: 'inline*',\n tableRole: 'cell',\n attrs: {\n colspan: { default: 1 },\n rowspan: { default: 1 },\n },\n isolating: true,\n parseDOM: [\n {\n tag: 'td',\n getAttrs(dom) {\n const el = dom as HTMLTableCellElement;\n return {\n colspan: el.colSpan || 1,\n rowspan: el.rowSpan || 1,\n };\n },\n },\n ],\n toDOM(node) {\n const attrs: Record<string, string | number> = {};\n if (node.attrs.colspan !== 1) attrs.colspan = node.attrs.colspan;\n if (node.attrs.rowspan !== 1) attrs.rowspan = node.attrs.rowspan;\n return ['td', attrs, 0];\n },\n },\n\n tableHeader: {\n content: 'inline*',\n tableRole: 'header_cell',\n attrs: {\n colspan: { default: 1 },\n rowspan: { default: 1 },\n },\n isolating: true,\n parseDOM: [\n {\n tag: 'th',\n getAttrs(dom) {\n const el = dom as HTMLTableCellElement;\n return {\n colspan: el.colSpan || 1,\n rowspan: el.rowSpan || 1,\n };\n },\n },\n ],\n toDOM(node) {\n const attrs: Record<string, string | number> = {};\n if (node.attrs.colspan !== 1) attrs.colspan = node.attrs.colspan;\n if (node.attrs.rowspan !== 1) attrs.rowspan = node.attrs.rowspan;\n return ['th', attrs, 0];\n },\n },\n\n text: {\n group: 'inline',\n },\n\n inlineToolTag: {\n group: 'inline',\n inline: true,\n atom: true,\n attrs: {\n type: { default: 'tool' },\n resourceId: { default: '' },\n text: { default: '' },\n },\n toDOM(node) {\n return [\n 'span',\n {\n class: 'inline-tool-tag',\n 'data-type': node.attrs.type,\n 'data-resource-id': node.attrs.resourceId,\n },\n node.attrs.text,\n ];\n },\n parseDOM: [\n {\n tag: 'span.inline-tool-tag',\n getAttrs(dom) {\n const el = dom as HTMLElement;\n return {\n type: el.getAttribute('data-type') || 'tool',\n resourceId: el.getAttribute('data-resource-id') || '',\n text: el.textContent || '',\n };\n },\n },\n ],\n },\n\n jumpPoint: {\n group: 'inline',\n inline: true,\n atom: true,\n attrs: {\n id: { default: '' },\n },\n toDOM(node) {\n return [\n 'span',\n {\n class: 'jump-point',\n 'data-jump-point-id': node.attrs.id,\n },\n `^${node.attrs.id}^`,\n ];\n },\n parseDOM: [\n {\n tag: 'span.jump-point',\n getAttrs(dom) {\n return {\n id: (dom as HTMLElement).getAttribute('data-jump-point-id') || '',\n };\n },\n },\n ],\n },\n\n hardBreak: {\n group: 'inline',\n inline: true,\n selectable: false,\n parseDOM: [{ tag: 'br' }],\n toDOM() {\n return ['br'];\n },\n },\n },\n\n marks: {\n bold: {\n parseDOM: [\n { tag: 'strong' },\n { tag: 'b', getAttrs: (node) => (node as HTMLElement).style.fontWeight !== 'normal' && null },\n {\n style: 'font-weight',\n getAttrs: (value) => /^(bold(er)?|[5-9]\\d{2,})$/.test(value as string) && null,\n },\n ],\n toDOM() {\n return ['strong', 0];\n },\n },\n\n italic: {\n parseDOM: [\n { tag: 'em' },\n { tag: 'i', getAttrs: (node) => (node as HTMLElement).style.fontStyle !== 'normal' && null },\n {\n style: 'font-style',\n getAttrs: (value) => (value as string) === 'italic' && null,\n },\n ],\n toDOM() {\n return ['em', 0];\n },\n },\n\n underline: {\n parseDOM: [\n { tag: 'u' },\n {\n style: 'text-decoration',\n getAttrs: (value) => (value as string).includes('underline') && null,\n },\n ],\n toDOM() {\n return ['u', 0];\n },\n },\n\n strikethrough: {\n parseDOM: [\n { tag: 's' },\n { tag: 'del' },\n { tag: 'strike' },\n {\n style: 'text-decoration',\n getAttrs: (value) => (value as string).includes('line-through') && null,\n },\n ],\n toDOM() {\n return ['s', 0];\n },\n },\n\n code: {\n parseDOM: [{ tag: 'code' }],\n toDOM() {\n return ['code', 0];\n },\n },\n\n link: {\n attrs: {\n href: { default: '' },\n title: { default: null },\n },\n inclusive: false,\n parseDOM: [\n {\n tag: 'a[href]',\n getAttrs(dom) {\n return {\n href: (dom as HTMLElement).getAttribute('href'),\n title: (dom as HTMLElement).getAttribute('title'),\n };\n },\n },\n ],\n toDOM(node) {\n const { href, title } = node.attrs;\n return ['a', { href, title, rel: 'noopener noreferrer nofollow' }, 0];\n },\n },\n\n diffMark: {\n attrs: {\n type: { default: 'added' },\n },\n parseDOM: [\n {\n tag: 'span[data-diff-type]',\n getAttrs(dom) {\n return { type: (dom as HTMLElement).getAttribute('data-diff-type') || 'added' };\n },\n },\n ],\n toDOM(node) {\n return ['span', { 'data-diff-type': node.attrs.type, class: `diff-${node.attrs.type}` }, 0];\n },\n },\n },\n});\n","import { Plugin } from 'prosemirror-state';\nimport { keymap } from 'prosemirror-keymap';\nimport { inputRules } from 'prosemirror-inputrules';\nimport type { ActionbookPlugin, NodeViewFactory } from './types';\n\n/**\n * Converts ActionbookPlugin[] into a flat array of PM Plugins.\n * Merges inputRules and keymaps from all plugins.\n *\n * Priority order (ProseMirror tries plugins in array order — first wins):\n * 1. Merged inputRules — highest priority for text-input transforms\n * 2. Merged keymap — custom handlers (e.g. splitListItem on Enter)\n * 3. Raw PM plugins — baseline behaviors (history, baseKeymap, etc.)\n *\n * Putting the merged keymap BEFORE raw plugins ensures that handlers like\n * `splitListItem` on Enter take priority over `baseKeymap`'s `splitBlock`.\n */\nexport function createPluginArray(plugins: ActionbookPlugin[]): {\n pmPlugins: Plugin[];\n nodeViews: Record<string, NodeViewFactory>;\n} {\n const rawPlugins: Plugin[] = [];\n const allNodeViews: Record<string, NodeViewFactory> = {};\n const allInputRules: import('prosemirror-inputrules').InputRule[] = [];\n const allKeymaps: Record<string, import('prosemirror-state').Command> = {};\n\n for (const plugin of plugins) {\n if (plugin.plugins) {\n rawPlugins.push(...plugin.plugins());\n }\n if (plugin.inputRules) {\n allInputRules.push(...plugin.inputRules());\n }\n if (plugin.keymap) {\n for (const [key, handler] of Object.entries(plugin.keymap())) {\n const prev = allKeymaps[key];\n // Chain: if an earlier plugin already claimed this key, run it first;\n // fall through to the new handler only if the earlier one returns false.\n allKeymaps[key] = prev\n ? (state, dispatch, view) => prev(state, dispatch, view) || handler(state, dispatch, view)\n : handler;\n }\n }\n if (plugin.nodeViews) {\n Object.assign(allNodeViews, plugin.nodeViews());\n }\n }\n\n const pmPlugins: Plugin[] = [];\n\n // 1. Input rules first (text-input events, no conflict with keydown)\n if (allInputRules.length > 0) {\n pmPlugins.push(inputRules({ rules: allInputRules }));\n }\n\n // 2. Merged keymap before raw plugins so custom handlers win on key conflicts\n if (Object.keys(allKeymaps).length > 0) {\n pmPlugins.push(keymap(allKeymaps));\n }\n\n // 3. Raw PM plugins (history, baseKeymap, etc.) as fallback\n pmPlugins.push(...rawPlugins);\n\n return { pmPlugins, nodeViews: allNodeViews };\n}\n","import React, { type ReactElement } from 'react';\nimport type {\n DocumentNode,\n BlockNode,\n InlineNode,\n AstNode,\n Mark,\n} from '../../ast/types';\nimport {\n IconAnchor,\n IconHandoff,\n IconManual,\n IconMessageTemplate,\n IconTimeDiff,\n IconTool,\n} from './icons';\n\nexport interface ActionbookRendererProps {\n doc: DocumentNode;\n className?: string;\n /** Custom node renderer for extension points */\n renderNode?: (node: AstNode, defaultRender: () => ReactElement) => ReactElement;\n}\n\n// Color values matching Feather design tokens used in sbdashboard.\nconst RESOURCE_TAG_COLORS: Record<string, string> = {\n tool: '#027D69', // green-6\n manual: '#5959D3', // blue-6\n agent_message_template: '#8012B3', // violet-6\n handoff: '#D25309', // orange-6\n time_diff: '#FB6B6B', // data-viz-4 (red-4)\n};\nconst DEFAULT_RESOURCE_TAG_COLOR = '#027D69';\n\ntype IconComponent = typeof IconTool;\nconst RESOURCE_TAG_ICONS: Record<string, IconComponent> = {\n tool: IconTool,\n manual: IconManual,\n agent_message_template: IconMessageTemplate,\n handoff: IconHandoff,\n time_diff: IconTimeDiff,\n};\nconst DEFAULT_RESOURCE_TAG_ICON = IconTool;\n\nfunction renderMark(mark: Mark, children: ReactElement, key: string): ReactElement {\n switch (mark.type) {\n case 'bold':\n return <strong key={key}>{children}</strong>;\n case 'italic':\n return <em key={key}>{children}</em>;\n case 'underline':\n return <u key={key}>{children}</u>;\n case 'strikethrough':\n return <s key={key}>{children}</s>;\n case 'code':\n return <code key={key}>{children}</code>;\n case 'link':\n return (\n <a key={key} href={mark.href} title={mark.title} rel=\"noopener noreferrer nofollow\">\n {children}\n </a>\n );\n }\n}\n\nfunction wrapWithMarks(text: string, marks: readonly Mark[] | undefined, key: string): ReactElement {\n let element: ReactElement = <React.Fragment key={key}>{text}</React.Fragment>;\n if (!marks || marks.length === 0) return element;\n for (let i = 0; i < marks.length; i++) {\n element = renderMark(marks[i], element, `${key}-m${i}`);\n }\n return element;\n}\n\nfunction renderInline(\n node: InlineNode,\n key: string,\n renderNode?: ActionbookRendererProps['renderNode'],\n): ReactElement {\n const defaultRender = (): ReactElement => {\n switch (node.type) {\n case 'text':\n return wrapWithMarks(node.text, node.marks, key);\n case 'resourceTag': {\n const color = RESOURCE_TAG_COLORS[node.tagType] ?? DEFAULT_RESOURCE_TAG_COLOR;\n const Icon = RESOURCE_TAG_ICONS[node.tagType] ?? DEFAULT_RESOURCE_TAG_ICON;\n return (\n <span\n key={key}\n className=\"inline-tool-tag\"\n data-type={node.tagType}\n data-resource-id={node.resourceId}\n style={{\n display: 'inline-flex',\n height: '20px',\n padding: '1px',\n border: '1px solid #CCCCCC',\n borderRadius: '2px',\n alignItems: 'center',\n backgroundColor: 'white',\n verticalAlign: 'middle',\n userSelect: 'none',\n }}\n >\n <span\n style={{\n display: 'inline-flex',\n justifyContent: 'center',\n alignItems: 'center',\n width: '16px',\n height: '16px',\n backgroundColor: color,\n borderRadius: '2px',\n flexShrink: 0,\n }}\n >\n <Icon size={9} fill=\"white\" />\n </span>\n <span\n style={{\n padding: '0 4px',\n color,\n fontSize: '11px',\n lineHeight: 1,\n userSelect: 'none',\n }}\n >\n {node.text}\n </span>\n </span>\n );\n }\n case 'jumpPoint':\n return (\n <span\n key={key}\n className=\"jump-point\"\n data-jump-point-id={node.id}\n id={`jp-${node.id}`}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n backgroundColor: '#FFF2B6',\n border: '1px solid #FFC233',\n color: '#AA5D04',\n borderRadius: '4px',\n height: 'max(20px, 1em)',\n padding: '0 max(0.3em, 2px)',\n fontSize: 'max(0.9em, 14px)',\n lineHeight: '0.9em',\n verticalAlign: 'middle',\n userSelect: 'none',\n }}\n >\n <IconAnchor\n size={12}\n fill=\"#AA5D04\"\n style={{ marginRight: 'max(0.15em, 2px)', flexShrink: 0 }}\n />\n {node.id}\n </span>\n );\n case 'hardBreak':\n return <br key={key} />;\n default:\n return <span key={key} />;\n }\n };\n\n if (renderNode) return renderNode(node, defaultRender);\n return defaultRender();\n}\n\nfunction renderInlineContent(\n content: readonly InlineNode[],\n keyPrefix: string,\n renderNode?: ActionbookRendererProps['renderNode'],\n): ReactElement[] {\n return content.map((node, i) => renderInline(node, `${keyPrefix}-${i}`, renderNode));\n}\n\nfunction renderBlock(\n node: BlockNode,\n key: string,\n renderNode?: ActionbookRendererProps['renderNode'],\n): ReactElement {\n const defaultRender = (): ReactElement => {\n switch (node.type) {\n case 'paragraph':\n return <p key={key}>{renderInlineContent(node.content, key, renderNode)}</p>;\n case 'heading': {\n const Tag = `h${node.level}` as keyof JSX.IntrinsicElements;\n return <Tag key={key}>{renderInlineContent(node.content, key, renderNode)}</Tag>;\n }\n case 'bulletList':\n return (\n <ul key={key}>\n {node.content.map((item, i) => renderBlock(item, `${key}-${i}`, renderNode))}\n </ul>\n );\n case 'orderedList':\n return (\n <ol key={key} start={node.start !== 1 ? node.start : undefined}>\n {node.content.map((item, i) => renderBlock(item, `${key}-${i}`, renderNode))}\n </ol>\n );\n case 'listItem':\n if (node.checked != null) {\n return (\n <li key={key} style={{ display: 'flex', alignItems: 'flex-start', listStyle: 'none' }}>\n <input\n type=\"checkbox\"\n checked={node.checked}\n readOnly\n style={{ marginRight: 6, marginTop: 4, flexShrink: 0 }}\n />\n <div style={node.checked ? { textDecoration: 'line-through', opacity: 0.6 } : undefined}>\n {node.content.map((child, i) => renderBlock(child, `${key}-${i}`, renderNode))}\n </div>\n </li>\n );\n }\n return (\n <li key={key}>\n {node.content.map((child, i) => renderBlock(child, `${key}-${i}`, renderNode))}\n </li>\n );\n case 'blockquote':\n return (\n <blockquote key={key}>\n {node.content.map((child, i) => renderBlock(child, `${key}-${i}`, renderNode))}\n </blockquote>\n );\n case 'horizontalRule':\n return <hr key={key} />;\n case 'table':\n return (\n <table key={key}>\n <tbody>\n {node.content.map((row, ri) => (\n <tr key={`${key}-r${ri}`}>\n {row.content.map((cell, ci) => {\n const CellTag = cell.header ? 'th' : 'td';\n return (\n <CellTag key={`${key}-r${ri}-c${ci}`}>\n {renderInlineContent(cell.content, `${key}-r${ri}-c${ci}`, renderNode)}\n </CellTag>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n );\n default:\n return <div key={key} />;\n }\n };\n\n if (renderNode) return renderNode(node, defaultRender);\n return defaultRender();\n}\n\nexport function ActionbookRenderer({ doc, className, renderNode }: ActionbookRendererProps): ReactElement {\n return (\n <div className={className}>\n {doc.content.map((node, i) => renderBlock(node, `ab-${i}`, renderNode))}\n </div>\n );\n}\n","/**\n * Inline SVG icons copied from sbdashboard/app/feather/components/icons/svg/.\n * Intentionally minimal — no external icon library required.\n */\nimport React from 'react';\n\ninterface IconProps {\n size?: number;\n fill?: string;\n style?: React.CSSProperties;\n}\n\n/** SBiDeveloperResources — used for \"tool\" resource tags */\nexport function IconTool({ size = 16, fill = 'currentColor', style }: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill={fill}\n style={style}\n >\n <path d=\"m14.064 3.649-6 16 1.873.702 6-16-1.873-.702ZM6.293 5.793.086 12l6.207 6.207 1.414-1.414L2.914 12l4.793-4.793-1.414-1.414ZM17.707 5.793 23.914 12l-6.207 6.207-1.414-1.414L21.086 12l-4.793-4.793 1.414-1.414Z\" />\n </svg>\n );\n}\n\n/** SBiDivide — used for \"manual\" resource tags */\nexport function IconManual({ size = 16, fill = 'currentColor', style }: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill={fill}\n style={style}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M18.5 4C19.3284 4 20 4.67157 20 5.5C20 6.32843 19.3284 7 18.5 7C17.6716 7 17 6.32843 17 5.5C17 4.67157 17.6716 4 18.5 4ZM18.5 2C16.9145 2 15.5752 3.05426 15.1449 4.5H10.5V11H8.91946C8.57612 9.42741 7.17556 8.25 5.5 8.25C3.567 8.25 2 9.817 2 11.75C2 13.683 3.567 15.25 5.5 15.25C6.9926 15.25 8.26697 14.3157 8.77019 13H10.5V19.5H15.1449C15.5752 20.9457 16.9145 22 18.5 22C20.433 22 22 20.433 22 18.5C22 16.567 20.433 15 18.5 15C16.9145 15 15.5752 16.0543 15.1449 17.5H12.5V13V11V6.5H15.1449C15.5752 7.94574 16.9145 9 18.5 9C20.433 9 22 7.433 22 5.5C22 3.567 20.433 2 18.5 2ZM17 18.5C17 17.6716 17.6716 17 18.5 17C19.3284 17 20 17.6716 20 18.5C20 19.3284 19.3284 20 18.5 20C17.6716 20 17 19.3284 17 18.5ZM5.5 10.25C6.32843 10.25 7 10.9216 7 11.75C7 12.5784 6.32843 13.25 5.5 13.25C4.67157 13.25 4 12.5784 4 11.75C4 10.9216 4.67157 10.25 5.5 10.25Z\"\n />\n </svg>\n );\n}\n\n/** SBiReplyTemplate — used for \"agent_message_template\" resource tags */\nexport function IconMessageTemplate({ size = 16, fill = 'currentColor', style }: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill={fill}\n style={style}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 4.5A2.5 2.5 0 0 1 4.5 2h15A2.5 2.5 0 0 1 22 4.5v11a2.5 2.5 0 0 1-2.5 2.5H6l-4 4V4.5Zm2 12.672L5.172 16H19.5a.5.5 0 0 0 .5-.5v-11a.5.5 0 0 0-.5-.5h-15a.5.5 0 0 0-.5.5v12.672Z\"\n />\n <path d=\"m12 12.404 2.781 1.687-.738-3.179L16.5 8.774l-3.236-.276L12 5.5l-1.264 2.998-3.236.276 2.457 2.138-.738 3.179L12 12.404Z\" />\n </svg>\n );\n}\n\n/** SBiAgents — used for \"handoff\" resource tags */\nexport function IconHandoff({ size = 16, fill = 'currentColor', style }: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill={fill}\n style={style}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 4a8 8 0 0 0-8 8v4a3 3 0 1 1 6 0v3a3 3 0 1 1-6 0v-.5H2V12C2 6.477 6.477 2 12 2s10 4.477 10 10v6.5h-2v.5a3 3 0 1 1-6 0v-3a3 3 0 1 1 6 0v-4a8 8 0 0 0-8-8ZM8 16v3a1 1 0 1 1-2 0v-3a1 1 0 1 1 2 0Zm10 3v-3a1 1 0 1 0-2 0v3a1 1 0 1 0 2 0Z\"\n />\n </svg>\n );\n}\n\n/** SBiTime — used for \"time_diff\" resource tags */\nexport function IconTimeDiff({ size = 16, fill = 'currentColor', style }: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill={fill}\n style={style}\n >\n <path d=\"M12.485 6.244h-2v6.618l4.553 2.277.895-1.79-3.448-1.723V6.244Z\" />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10Zm8-10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z\"\n />\n </svg>\n );\n}\n\n/** SBiAnchor — used for jump points */\nexport function IconAnchor({ size = 16, fill = 'currentColor', style }: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 16 16\"\n width={size}\n height={size}\n fill={fill}\n style={style}\n >\n <g fillRule=\"evenodd\" clipPath=\"url(#anchor-clip)\" clipRule=\"evenodd\">\n <path d=\"M8 5.333a2.667 2.667 0 1 1 0 5.333 2.667 2.667 0 0 1 0-5.333Zm0 1.333a1.333 1.333 0 1 0 0 2.667 1.333 1.333 0 0 0 0-2.667Z\" />\n <path d=\"M8.667 2.037a6 6 0 0 1 5.295 5.296h1.371v1.333h-1.37a6 6 0 0 1-5.296 5.295v1.372H7.333V13.96a6 6 0 0 1-5.295-5.295H.667V7.333h1.37a6 6 0 0 1 5.296-5.296V.666h1.334v1.371ZM8 3.333a4.667 4.667 0 1 0 0 9.333 4.667 4.667 0 0 0 0-9.333Z\" />\n </g>\n <defs>\n <clipPath id=\"anchor-clip\">\n <path d=\"M0 0H16V16H0z\" transform=\"translate(0 -.001)\" />\n </clipPath>\n </defs>\n </svg>\n );\n}\n","import React, { forwardRef } from 'react';\n\nexport interface EditorShellProps {\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * Contenteditable container for ProseMirror EditorView.\n * Pass the ref from `useEditorView().viewRef` to mount the editor.\n */\nexport const EditorShell = forwardRef<HTMLDivElement, EditorShellProps>(function EditorShell(\n { className, style },\n ref,\n) {\n return <div ref={ref} className={className} style={style} />;\n});\n","import { createElement } from 'react';\nimport { createRoot, type Root } from 'react-dom/client';\nimport type { Node as PMNode } from 'prosemirror-model';\nimport type { Decoration, DecorationSource, EditorView, NodeView } from 'prosemirror-view';\nimport type { NodeViewFactory } from '../plugin/types';\n\nexport interface ReactNodeViewProps {\n node: PMNode;\n view: EditorView;\n getPos: () => number | undefined;\n selected: boolean;\n /** Outer node decorations currently applied to this node. */\n decorations: readonly Decoration[];\n}\n\nexport interface ReactNodeViewOptions {\n /** The React component to render */\n component: React.ComponentType<ReactNodeViewProps>;\n /** Container tag name (default: 'span' for inline, 'div' for block) */\n as?: string;\n /** CSS class name for the container */\n className?: string;\n /** Whether this is an inline node (default: true) */\n inline?: boolean;\n}\n\nclass ReactNodeViewImpl implements NodeView {\n dom: HTMLElement;\n private root: Root;\n private component: React.ComponentType<ReactNodeViewProps>;\n private _node: PMNode;\n private _view: EditorView;\n private _getPos: () => number | undefined;\n private _selected = false;\n private _decorations: readonly Decoration[] = [];\n\n constructor(\n node: PMNode,\n view: EditorView,\n getPos: () => number | undefined,\n options: ReactNodeViewOptions,\n ) {\n this._node = node;\n this._view = view;\n this._getPos = getPos;\n this.component = options.component;\n\n const tag = options.as ?? (options.inline !== false ? 'span' : 'div');\n this.dom = document.createElement(tag);\n if (options.inline !== false) {\n this.dom.style.display = 'inline-flex';\n this.dom.style.verticalAlign = 'middle';\n }\n if (options.className) {\n this.dom.className = options.className;\n }\n\n this.root = createRoot(this.dom);\n this.render();\n }\n\n private render() {\n this.root.render(\n createElement(this.component, {\n node: this._node,\n view: this._view,\n getPos: this._getPos,\n selected: this._selected,\n decorations: this._decorations,\n }),\n );\n }\n\n update(node: PMNode, decorations: readonly Decoration[], _innerDecorations: DecorationSource): boolean {\n if (node.type !== this._node.type) return false;\n this._node = node;\n this._decorations = decorations;\n this.render();\n return true;\n }\n\n selectNode() {\n this._selected = true;\n this.render();\n }\n\n deselectNode() {\n this._selected = false;\n this.render();\n }\n\n destroy() {\n // Defer unmount to avoid flushSync warnings in React 18\n setTimeout(() => this.root.unmount(), 0);\n }\n\n stopEvent() {\n return false;\n }\n\n ignoreMutation() {\n return true;\n }\n}\n\n/**\n * Creates a NodeViewFactory that renders a React component as a PM NodeView.\n *\n * Usage:\n * ```ts\n * const jumpPointPlugin: ActionbookPlugin = {\n * name: 'jumpPoint',\n * nodeViews: () => ({\n * jumpPoint: createReactNodeView({ component: JumpPointView }),\n * }),\n * };\n * ```\n */\nexport function createReactNodeView(options: ReactNodeViewOptions): NodeViewFactory {\n return (node, view, getPos) => new ReactNodeViewImpl(node, view, getPos, options);\n}\n","import { useRef, useEffect, useCallback, useState, type RefObject } from 'react';\nimport { EditorState, type Transaction } from 'prosemirror-state';\nimport { EditorView } from 'prosemirror-view';\nimport { Node as PMNode } from 'prosemirror-model';\nimport type { DocumentNode } from '../../ast/types';\nimport type { LlmCompletionEndpoint } from '../../lint/types';\nimport { fromProseMirrorJSON, type JSONContent } from '../../compat/prosemirror';\nimport { serializeToMarkdown } from '../../markdown/serializer';\nimport { actionbookSchema } from '../schema';\nimport { createPluginArray } from '../plugin/registry';\nimport { toProseMirrorJSON } from '../bridge/toProseMirrorJSON';\nimport type { ActionbookPlugin } from '../plugin/types';\n\nexport interface EditorViewConfig {\n plugins?: ActionbookPlugin[];\n content?: DocumentNode | null;\n editable?: boolean;\n onTransaction?: (state: EditorState) => void;\n onContentChange?: (doc: DocumentNode) => void;\n /**\n * Optional LLM completion endpoint for LLM-based lint rules.\n * When provided, the editor can run async lint rules that leverage LLM analysis.\n * Accepts any backend: OpenAI, Anthropic, Gemini Nano, custom proxy, etc.\n */\n llmCompletionEndpoint?: LlmCompletionEndpoint;\n}\n\nexport interface EditorViewHandle {\n viewRef: RefObject<HTMLDivElement | null>;\n view: EditorView | null;\n getAST: () => DocumentNode | null;\n getMarkdown: () => string;\n setContent: (doc: DocumentNode) => void;\n focus: () => void;\n destroy: () => void;\n}\n\nfunction docToState(doc: DocumentNode | null | undefined, plugins: import('prosemirror-state').Plugin[]): EditorState {\n const pmJSON = doc ? toProseMirrorJSON(doc) : { type: 'doc', content: [{ type: 'paragraph' }] };\n const pmDoc = PMNode.fromJSON(actionbookSchema, pmJSON);\n return EditorState.create({ doc: pmDoc, plugins });\n}\n\nfunction pmDocToAST(pmDoc: PMNode): DocumentNode {\n const json = pmDoc.toJSON() as JSONContent;\n return fromProseMirrorJSON(json);\n}\n\nexport function useEditorView(config: EditorViewConfig): EditorViewHandle {\n const viewRef = useRef<HTMLDivElement | null>(null);\n const viewInstanceRef = useRef<EditorView | null>(null);\n const [, forceUpdate] = useState(0);\n\n // Stable refs for callbacks\n const configRef = useRef(config);\n configRef.current = config;\n\n useEffect(() => {\n const container = viewRef.current;\n if (!container) return;\n\n const { pmPlugins, nodeViews } = createPluginArray(config.plugins ?? []);\n const state = docToState(config.content, pmPlugins);\n\n const view = new EditorView(container, {\n state,\n nodeViews,\n editable: () => configRef.current.editable !== false,\n dispatchTransaction(tr: Transaction) {\n const newState = view.state.apply(tr);\n view.updateState(newState);\n configRef.current.onTransaction?.(newState);\n if (tr.docChanged) {\n const ast = pmDocToAST(newState.doc);\n configRef.current.onContentChange?.(ast);\n }\n },\n });\n\n viewInstanceRef.current = view;\n forceUpdate((n) => n + 1);\n\n return () => {\n view.destroy();\n viewInstanceRef.current = null;\n };\n // Only re-create on mount/unmount. Plugin and content changes are handled imperatively.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const getAST = useCallback((): DocumentNode | null => {\n const view = viewInstanceRef.current;\n if (!view) return null;\n return pmDocToAST(view.state.doc);\n }, []);\n\n const getMarkdown = useCallback((): string => {\n const ast = getAST();\n if (!ast) return '';\n return serializeToMarkdown(ast);\n }, [getAST]);\n\n const setContent = useCallback((doc: DocumentNode) => {\n const view = viewInstanceRef.current;\n if (!view) return;\n const pmJSON = toProseMirrorJSON(doc);\n const pmDoc = PMNode.fromJSON(actionbookSchema, pmJSON);\n const tr = view.state.tr.replaceWith(0, view.state.doc.content.size, pmDoc.content);\n view.dispatch(tr);\n }, []);\n\n const focus = useCallback(() => {\n viewInstanceRef.current?.focus();\n }, []);\n\n const destroy = useCallback(() => {\n viewInstanceRef.current?.destroy();\n viewInstanceRef.current = null;\n }, []);\n\n return {\n viewRef,\n view: viewInstanceRef.current,\n getAST,\n getMarkdown,\n setContent,\n focus,\n destroy,\n };\n}\n","/**\n * Convert ProseMirror/Tiptap JSONContent to ActionbookAST.\n *\n * This handles the legacy editor_data format stored in LogicV2.\n */\nimport type {\n DocumentNode,\n BlockNode,\n InlineNode,\n Mark,\n ResourceTagType,\n TableNode,\n TableRowNode,\n TableCellNode,\n} from '../ast/types';\n\nconst MAX_DEPTH = 128;\nconst ALLOWED_URL_PROTOCOLS = /^(https?:|mailto:|tel:|#|\\/)/i;\n\n// Minimal JSONContent type (compatible with @tiptap/core)\nexport type JSONContent = {\n type?: string;\n attrs?: Record<string, unknown>;\n content?: JSONContent[];\n marks?: { type: string; attrs?: Record<string, unknown> }[];\n text?: string;\n};\n\nfunction convertPMMark(mark: { type: string; attrs?: Record<string, unknown> }): Mark | null {\n switch (mark.type) {\n case 'bold':\n return { type: 'bold' };\n case 'italic':\n return { type: 'italic' };\n case 'underline':\n return { type: 'underline' };\n case 'strikethrough':\n return { type: 'strikethrough' };\n case 'code':\n return { type: 'code' };\n case 'link': {\n const rawHref = (mark.attrs?.href as string) ?? '';\n // Strip dangerous URL protocols\n if (!ALLOWED_URL_PROTOCOLS.test(rawHref)) return null;\n const title = mark.attrs?.title as string | undefined;\n return title ? { type: 'link', href: rawHref, title } : { type: 'link', href: rawHref };\n }\n // Ignored marks (UI-only or unused)\n case 'diffMark':\n case 'inlineResource':\n case 'textStyle':\n return null;\n default:\n return null;\n }\n}\n\nfunction convertPMInline(node: JSONContent, depth: number): InlineNode[] {\n if (depth > MAX_DEPTH) return [];\n const type = node.type ?? '';\n\n switch (type) {\n case 'text': {\n const marks = (node.marks ?? []).map(convertPMMark).filter((m): m is Mark => m !== null);\n const textNode = node.text ?? '';\n return marks.length > 0 ? [{ type: 'text', text: textNode, marks }] : [{ type: 'text', text: textNode }];\n }\n\n case 'inlineToolTag': {\n const attrs = node.attrs ?? {};\n return [\n {\n type: 'resourceTag',\n tagType: (attrs.type as ResourceTagType) ?? 'tool',\n resourceId: (attrs.resourceId as string) ?? '',\n text: (attrs.text as string) ?? '',\n },\n ];\n }\n\n case 'jumpPoint': {\n const id = (node.attrs?.id as string) ?? '';\n return [{ type: 'jumpPoint', id }];\n }\n\n case 'hardBreak':\n return [{ type: 'hardBreak' }];\n\n default:\n if (node.text) {\n return [{ type: 'text', text: node.text }];\n }\n if (node.content) {\n return node.content.flatMap((c) => convertPMInline(c, depth + 1));\n }\n return [];\n }\n}\n\nfunction convertPMBlock(node: JSONContent, depth: number = 0): BlockNode[] {\n if (depth > MAX_DEPTH) return [];\n const type = node.type ?? '';\n const children = node.content ?? [];\n\n switch (type) {\n case 'paragraph':\n return [{ type: 'paragraph', content: children.flatMap((c) => convertPMInline(c, depth + 1)) }];\n\n case 'heading': {\n const level = ((node.attrs?.level as number) ?? 1) as 1 | 2 | 3 | 4 | 5 | 6;\n return [{ type: 'heading', level, content: children.flatMap((c) => convertPMInline(c, depth + 1)) }];\n }\n\n case 'bulletList':\n return [\n {\n type: 'bulletList',\n content: children.map((c) => convertPMListItem(c, depth + 1)),\n },\n ];\n\n case 'orderedList': {\n const start = (node.attrs?.start as number) ?? 1;\n return [\n {\n type: 'orderedList',\n start,\n content: children.map((c) => convertPMListItem(c, depth + 1)),\n },\n ];\n }\n\n case 'listItem': {\n return [convertPMListItem(node, depth)];\n }\n\n case 'blockquote':\n return [{ type: 'blockquote', content: children.flatMap((c) => convertPMBlock(c, depth + 1)) }];\n\n case 'horizontalRule':\n return [{ type: 'horizontalRule' }];\n\n case 'table': {\n const rows: TableRowNode[] = children.map((rowNode) => {\n const cells: TableCellNode[] = (rowNode.content ?? []).map((cellNode) => {\n const cellType = cellNode.type ?? '';\n const isHeader = cellType === 'tableHeader';\n const inlines = (cellNode.content ?? []).flatMap((c) => convertPMInline(c, depth + 3));\n return {\n type: 'tableCell' as const,\n ...(isHeader ? { header: true } : {}),\n content: inlines,\n };\n });\n return { type: 'tableRow' as const, content: cells };\n });\n return [{ type: 'table', content: rows }];\n }\n\n default:\n if (children.length > 0) {\n return children.flatMap((c) => convertPMBlock(c, depth + 1));\n }\n return [];\n }\n}\n\nfunction convertPMListItem(node: JSONContent, depth: number = 0): { type: 'listItem'; checked?: boolean | null; content: BlockNode[] } {\n if (depth > MAX_DEPTH) return { type: 'listItem', content: [{ type: 'paragraph', content: [] }] };\n const children = node.content ?? [];\n const content = children.flatMap((c) => convertPMBlock(c, depth + 1));\n const checked = node.attrs?.checked as boolean | null | undefined;\n const base: { type: 'listItem'; checked?: boolean | null; content: BlockNode[] } = {\n type: 'listItem',\n content: content.length > 0 ? content : [{ type: 'paragraph', content: [] }],\n };\n if (typeof checked === 'boolean') {\n base.checked = checked;\n }\n return base;\n}\n\nexport function fromProseMirrorJSON(pmJSON: JSONContent): DocumentNode {\n if (pmJSON.type !== 'doc') {\n const blocks = convertPMBlock(pmJSON, 0);\n return { type: 'doc', content: blocks.length > 0 ? blocks : [{ type: 'paragraph', content: [] }] };\n }\n\n const children = pmJSON.content ?? [];\n const blocks = children.flatMap((c) => convertPMBlock(c, 0));\n return { type: 'doc', content: blocks.length > 0 ? blocks : [{ type: 'paragraph', content: [] }] };\n}\n","import type { Parents, Text } from 'mdast';\nimport { defaultHandlers, toMarkdown } from 'mdast-util-to-markdown';\nimport type { Handle, Info, Options, State } from 'mdast-util-to-markdown';\nimport { gfmFootnoteToMarkdown } from 'mdast-util-gfm-footnote';\nimport { gfmStrikethroughToMarkdown } from 'mdast-util-gfm-strikethrough';\nimport { gfmTableToMarkdown } from 'mdast-util-gfm-table';\nimport { gfmTaskListItemToMarkdown } from 'mdast-util-gfm-task-list-item';\nimport { resourceTagToMarkdown } from './plugins/resourceTag';\nimport { jumpPointToMarkdown } from './plugins/jumpPoint';\nimport { toMdast } from './mdastAdapter';\nimport type { DocumentNode } from '../ast/types';\n\n// GFM without autolink literal — see parser.ts for rationale.\nconst gfmNoAutolinkToMarkdown = () => ({\n extensions: [\n gfmFootnoteToMarkdown(),\n gfmStrikethroughToMarkdown(),\n gfmTableToMarkdown(),\n gfmTaskListItemToMarkdown(),\n ],\n});\n\nfunction isEmptyParagraph(node: Parents | { type: string; children?: unknown[] }): boolean {\n return node.type === 'paragraph' && (!('children' in node) || !node.children || node.children.length === 0);\n}\n\n/**\n * Custom text handler that prevents unnecessary `_` escaping in inline text.\n *\n * mdast-util-to-markdown's default unsafe rules include\n * `{character: '_', inConstruct: 'phrasing'}`, which escapes every underscore\n * in paragraph/heading text (e.g. `ENUM_VALUE` → `ENUM\\_VALUE`). Since we\n * generate emphasis and strong with `*`, underscores in plain text are never\n * interpreted as emphasis markers and do not need escaping.\n *\n * The `unsafe` option in `toMarkdown` is ADDITIVE (it pushes into the default\n * list, never replaces it), so we cannot override this via options alone.\n * Instead, we temporarily remove the phrasing-`_` rule from `state.unsafe`\n * before delegating to the default text handler.\n */\nfunction textHandler(node: Text, parent: Parents | undefined, state: State, info: Info): string {\n const originalUnsafe = state.unsafe;\n state.unsafe = originalUnsafe.filter((p) => !(p.character === '_' && !p.atBreak));\n const result = (defaultHandlers.text as Options['handlers'] & ((n: Text, p: Parents | undefined, s: State, i: Info) => string))(node, parent, state, info);\n state.unsafe = originalUnsafe;\n return result;\n}\n\nexport function serializeToMarkdown(doc: DocumentNode): string {\n const mdastTree = toMdast(doc);\n\n const result = toMarkdown(mdastTree, {\n bullet: '-',\n rule: '-',\n listItemIndent: 'one',\n emphasis: '*',\n strong: '*',\n resourceLink: true,\n join: [\n // Empty paragraphs represent blank-line spacers.\n // Reduce the separator after an empty paragraph from \\n\\n to \\n\n // so that 1 empty paragraph = 1 extra blank line in the output.\n (left) => (isEmptyParagraph(left) ? 0 : null),\n ],\n handlers: {\n text: textHandler as Handle,\n ...resourceTagToMarkdown().handlers,\n ...jumpPointToMarkdown().handlers,\n },\n extensions: [gfmNoAutolinkToMarkdown()],\n });\n\n return result;\n}\n","export function deprecate(fn) {\n return fn\n}\n\nexport function equal() {}\n\nexport function ok() {}\n\nexport function unreachable() {}\n","/**\n * Normalize an identifier (as found in references, definitions).\n *\n * Collapses markdown whitespace, trim, and then lower- and uppercase.\n *\n * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their\n * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different\n * uppercase character (U+0398 (`Θ`)).\n * So, to get a canonical form, we perform both lower- and uppercase.\n *\n * Using uppercase last makes sure keys will never interact with default\n * prototypal values (such as `constructor`): nothing in the prototype of\n * `Object` is uppercase.\n *\n * @param {string} value\n * Identifier to normalize.\n * @returns {string}\n * Normalized identifier.\n */\nexport function normalizeIdentifier(value) {\n return value\n // Collapse markdown whitespace.\n .replace(/[\\t\\n\\r ]+/g, \" \")\n // Trim.\n .replace(/^ | $/g, '')\n // Some characters are considered “uppercase”, but if their lowercase\n // counterpart is uppercased will result in a different uppercase\n // character.\n // Hence, to get that form, we perform both lower- and uppercase.\n // Upper case makes sure keys will not interact with default prototypal\n // methods: no method is uppercase.\n .toLowerCase().toUpperCase();\n}","/**\n * @import {\n * CompileContext,\n * Extension as FromMarkdownExtension,\n * Handle as FromMarkdownHandle\n * } from 'mdast-util-from-markdown'\n * @import {ToMarkdownOptions} from 'mdast-util-gfm-footnote'\n * @import {\n * Handle as ToMarkdownHandle,\n * Map,\n * Options as ToMarkdownExtension\n * } from 'mdast-util-to-markdown'\n * @import {FootnoteDefinition, FootnoteReference} from 'mdast'\n */\n\nimport {ok as assert} from 'devlop'\nimport {normalizeIdentifier} from 'micromark-util-normalize-identifier'\n\nfootnoteReference.peek = footnoteReferencePeek\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterFootnoteCallString() {\n this.buffer()\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterFootnoteCall(token) {\n this.enter({type: 'footnoteReference', identifier: '', label: ''}, token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterFootnoteDefinitionLabelString() {\n this.buffer()\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterFootnoteDefinition(token) {\n this.enter(\n {type: 'footnoteDefinition', identifier: '', label: '', children: []},\n token\n )\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitFootnoteCallString(token) {\n const label = this.resume()\n const node = this.stack[this.stack.length - 1]\n assert(node.type === 'footnoteReference')\n node.identifier = normalizeIdentifier(\n this.sliceSerialize(token)\n ).toLowerCase()\n node.label = label\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitFootnoteCall(token) {\n this.exit(token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitFootnoteDefinitionLabelString(token) {\n const label = this.resume()\n const node = this.stack[this.stack.length - 1]\n assert(node.type === 'footnoteDefinition')\n node.identifier = normalizeIdentifier(\n this.sliceSerialize(token)\n ).toLowerCase()\n node.label = label\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitFootnoteDefinition(token) {\n this.exit(token)\n}\n\n/** @type {ToMarkdownHandle} */\nfunction footnoteReferencePeek() {\n return '['\n}\n\n/**\n * @type {ToMarkdownHandle}\n * @param {FootnoteReference} node\n */\nfunction footnoteReference(node, _, state, info) {\n const tracker = state.createTracker(info)\n let value = tracker.move('[^')\n const exit = state.enter('footnoteReference')\n const subexit = state.enter('reference')\n value += tracker.move(\n state.safe(state.associationId(node), {after: ']', before: value})\n )\n subexit()\n exit()\n value += tracker.move(']')\n return value\n}\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM footnotes\n * in markdown.\n *\n * @returns {FromMarkdownExtension}\n * Extension for `mdast-util-from-markdown`.\n */\nexport function gfmFootnoteFromMarkdown() {\n return {\n enter: {\n gfmFootnoteCallString: enterFootnoteCallString,\n gfmFootnoteCall: enterFootnoteCall,\n gfmFootnoteDefinitionLabelString: enterFootnoteDefinitionLabelString,\n gfmFootnoteDefinition: enterFootnoteDefinition\n },\n exit: {\n gfmFootnoteCallString: exitFootnoteCallString,\n gfmFootnoteCall: exitFootnoteCall,\n gfmFootnoteDefinitionLabelString: exitFootnoteDefinitionLabelString,\n gfmFootnoteDefinition: exitFootnoteDefinition\n }\n }\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM footnotes\n * in markdown.\n *\n * @param {ToMarkdownOptions | null | undefined} [options]\n * Configuration (optional).\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown`.\n */\nexport function gfmFootnoteToMarkdown(options) {\n // To do: next major: change default.\n let firstLineBlank = false\n\n if (options && options.firstLineBlank) {\n firstLineBlank = true\n }\n\n return {\n handlers: {footnoteDefinition, footnoteReference},\n // This is on by default already.\n unsafe: [{character: '[', inConstruct: ['label', 'phrasing', 'reference']}]\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {FootnoteDefinition} node\n */\n function footnoteDefinition(node, _, state, info) {\n const tracker = state.createTracker(info)\n let value = tracker.move('[^')\n const exit = state.enter('footnoteDefinition')\n const subexit = state.enter('label')\n value += tracker.move(\n state.safe(state.associationId(node), {before: value, after: ']'})\n )\n subexit()\n\n value += tracker.move(']:')\n\n if (node.children && node.children.length > 0) {\n tracker.shift(4)\n\n value += tracker.move(\n (firstLineBlank ? '\\n' : ' ') +\n state.indentLines(\n state.containerFlow(node, tracker.current()),\n firstLineBlank ? mapAll : mapExceptFirst\n )\n )\n }\n\n exit()\n\n return value\n }\n}\n\n/** @type {Map} */\nfunction mapExceptFirst(line, index, blank) {\n return index === 0 ? line : mapAll(line, index, blank)\n}\n\n/** @type {Map} */\nfunction mapAll(line, index, blank) {\n return (blank ? '' : ' ') + line\n}\n","/**\n * @typedef {import('mdast').Delete} Delete\n *\n * @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext\n * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension\n * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle\n *\n * @typedef {import('mdast-util-to-markdown').ConstructName} ConstructName\n * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle\n * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension\n */\n\n/**\n * List of constructs that occur in phrasing (paragraphs, headings), but cannot\n * contain strikethrough.\n * So they sort of cancel each other out.\n * Note: could use a better name.\n *\n * Note: keep in sync with: <https://github.com/syntax-tree/mdast-util-to-markdown/blob/8ce8dbf/lib/unsafe.js#L14>\n *\n * @type {Array<ConstructName>}\n */\nconst constructsWithoutStrikethrough = [\n 'autolink',\n 'destinationLiteral',\n 'destinationRaw',\n 'reference',\n 'titleQuote',\n 'titleApostrophe'\n]\n\nhandleDelete.peek = peekDelete\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM\n * strikethrough in markdown.\n *\n * @returns {FromMarkdownExtension}\n * Extension for `mdast-util-from-markdown` to enable GFM strikethrough.\n */\nexport function gfmStrikethroughFromMarkdown() {\n return {\n canContainEols: ['delete'],\n enter: {strikethrough: enterStrikethrough},\n exit: {strikethrough: exitStrikethrough}\n }\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM\n * strikethrough in markdown.\n *\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown` to enable GFM strikethrough.\n */\nexport function gfmStrikethroughToMarkdown() {\n return {\n unsafe: [\n {\n character: '~',\n inConstruct: 'phrasing',\n notInConstruct: constructsWithoutStrikethrough\n }\n ],\n handlers: {delete: handleDelete}\n }\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterStrikethrough(token) {\n this.enter({type: 'delete', children: []}, token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitStrikethrough(token) {\n this.exit(token)\n}\n\n/**\n * @type {ToMarkdownHandle}\n * @param {Delete} node\n */\nfunction handleDelete(node, _, state, info) {\n const tracker = state.createTracker(info)\n const exit = state.enter('strikethrough')\n let value = tracker.move('~~')\n value += state.containerPhrasing(node, {\n ...tracker.current(),\n before: value,\n after: '~'\n })\n value += tracker.move('~~')\n exit()\n return value\n}\n\n/** @type {ToMarkdownHandle} */\nfunction peekDelete() {\n return '~'\n}\n","// To do: next major: remove.\n/**\n * @typedef {Options} MarkdownTableOptions\n * Configuration.\n */\n\n/**\n * @typedef Options\n * Configuration.\n * @property {boolean | null | undefined} [alignDelimiters=true]\n * Whether to align the delimiters (default: `true`);\n * they are aligned by default:\n *\n * ```markdown\n * | Alpha | B |\n * | ----- | ----- |\n * | C | Delta |\n * ```\n *\n * Pass `false` to make them staggered:\n *\n * ```markdown\n * | Alpha | B |\n * | - | - |\n * | C | Delta |\n * ```\n * @property {ReadonlyArray<string | null | undefined> | string | null | undefined} [align]\n * How to align columns (default: `''`);\n * one style for all columns or styles for their respective columns;\n * each style is either `'l'` (left), `'r'` (right), or `'c'` (center);\n * other values are treated as `''`, which doesn’t place the colon in the\n * alignment row but does align left;\n * *only the lowercased first character is used, so `Right` is fine.*\n * @property {boolean | null | undefined} [delimiterEnd=true]\n * Whether to end each row with the delimiter (default: `true`).\n *\n * > 👉 **Note**: please don’t use this: it could create fragile structures\n * > that aren’t understandable to some markdown parsers.\n *\n * When `true`, there are ending delimiters:\n *\n * ```markdown\n * | Alpha | B |\n * | ----- | ----- |\n * | C | Delta |\n * ```\n *\n * When `false`, there are no ending delimiters:\n *\n * ```markdown\n * | Alpha | B\n * | ----- | -----\n * | C | Delta\n * ```\n * @property {boolean | null | undefined} [delimiterStart=true]\n * Whether to begin each row with the delimiter (default: `true`).\n *\n * > 👉 **Note**: please don’t use this: it could create fragile structures\n * > that aren’t understandable to some markdown parsers.\n *\n * When `true`, there are starting delimiters:\n *\n * ```markdown\n * | Alpha | B |\n * | ----- | ----- |\n * | C | Delta |\n * ```\n *\n * When `false`, there are no starting delimiters:\n *\n * ```markdown\n * Alpha | B |\n * ----- | ----- |\n * C | Delta |\n * ```\n * @property {boolean | null | undefined} [padding=true]\n * Whether to add a space of padding between delimiters and cells\n * (default: `true`).\n *\n * When `true`, there is padding:\n *\n * ```markdown\n * | Alpha | B |\n * | ----- | ----- |\n * | C | Delta |\n * ```\n *\n * When `false`, there is no padding:\n *\n * ```markdown\n * |Alpha|B |\n * |-----|-----|\n * |C |Delta|\n * ```\n * @property {((value: string) => number) | null | undefined} [stringLength]\n * Function to detect the length of table cell content (optional);\n * this is used when aligning the delimiters (`|`) between table cells;\n * full-width characters and emoji mess up delimiter alignment when viewing\n * the markdown source;\n * to fix this, you can pass this function,\n * which receives the cell content and returns its “visible” size;\n * note that what is and isn’t visible depends on where the text is displayed.\n *\n * Without such a function, the following:\n *\n * ```js\n * markdownTable([\n * ['Alpha', 'Bravo'],\n * ['中文', 'Charlie'],\n * ['👩‍❤️‍👩', 'Delta']\n * ])\n * ```\n *\n * Yields:\n *\n * ```markdown\n * | Alpha | Bravo |\n * | - | - |\n * | 中文 | Charlie |\n * | 👩‍❤️‍👩 | Delta |\n * ```\n *\n * With [`string-width`](https://github.com/sindresorhus/string-width):\n *\n * ```js\n * import stringWidth from 'string-width'\n *\n * markdownTable(\n * [\n * ['Alpha', 'Bravo'],\n * ['中文', 'Charlie'],\n * ['👩‍❤️‍👩', 'Delta']\n * ],\n * {stringLength: stringWidth}\n * )\n * ```\n *\n * Yields:\n *\n * ```markdown\n * | Alpha | Bravo |\n * | ----- | ------- |\n * | 中文 | Charlie |\n * | 👩‍❤️‍👩 | Delta |\n * ```\n */\n\n/**\n * @param {string} value\n * Cell value.\n * @returns {number}\n * Cell size.\n */\nfunction defaultStringLength(value) {\n return value.length\n}\n\n/**\n * Generate a markdown\n * ([GFM](https://docs.github.com/en/github/writing-on-github/working-with-advanced-formatting/organizing-information-with-tables))\n * table.\n *\n * @param {ReadonlyArray<ReadonlyArray<string | null | undefined>>} table\n * Table data (matrix of strings).\n * @param {Readonly<Options> | null | undefined} [options]\n * Configuration (optional).\n * @returns {string}\n * Result.\n */\nexport function markdownTable(table, options) {\n const settings = options || {}\n // To do: next major: change to spread.\n const align = (settings.align || []).concat()\n const stringLength = settings.stringLength || defaultStringLength\n /** @type {Array<number>} Character codes as symbols for alignment per column. */\n const alignments = []\n /** @type {Array<Array<string>>} Cells per row. */\n const cellMatrix = []\n /** @type {Array<Array<number>>} Sizes of each cell per row. */\n const sizeMatrix = []\n /** @type {Array<number>} */\n const longestCellByColumn = []\n let mostCellsPerRow = 0\n let rowIndex = -1\n\n // This is a superfluous loop if we don’t align delimiters, but otherwise we’d\n // do superfluous work when aligning, so optimize for aligning.\n while (++rowIndex < table.length) {\n /** @type {Array<string>} */\n const row = []\n /** @type {Array<number>} */\n const sizes = []\n let columnIndex = -1\n\n if (table[rowIndex].length > mostCellsPerRow) {\n mostCellsPerRow = table[rowIndex].length\n }\n\n while (++columnIndex < table[rowIndex].length) {\n const cell = serialize(table[rowIndex][columnIndex])\n\n if (settings.alignDelimiters !== false) {\n const size = stringLength(cell)\n sizes[columnIndex] = size\n\n if (\n longestCellByColumn[columnIndex] === undefined ||\n size > longestCellByColumn[columnIndex]\n ) {\n longestCellByColumn[columnIndex] = size\n }\n }\n\n row.push(cell)\n }\n\n cellMatrix[rowIndex] = row\n sizeMatrix[rowIndex] = sizes\n }\n\n // Figure out which alignments to use.\n let columnIndex = -1\n\n if (typeof align === 'object' && 'length' in align) {\n while (++columnIndex < mostCellsPerRow) {\n alignments[columnIndex] = toAlignment(align[columnIndex])\n }\n } else {\n const code = toAlignment(align)\n\n while (++columnIndex < mostCellsPerRow) {\n alignments[columnIndex] = code\n }\n }\n\n // Inject the alignment row.\n columnIndex = -1\n /** @type {Array<string>} */\n const row = []\n /** @type {Array<number>} */\n const sizes = []\n\n while (++columnIndex < mostCellsPerRow) {\n const code = alignments[columnIndex]\n let before = ''\n let after = ''\n\n if (code === 99 /* `c` */) {\n before = ':'\n after = ':'\n } else if (code === 108 /* `l` */) {\n before = ':'\n } else if (code === 114 /* `r` */) {\n after = ':'\n }\n\n // There *must* be at least one hyphen-minus in each alignment cell.\n let size =\n settings.alignDelimiters === false\n ? 1\n : Math.max(\n 1,\n longestCellByColumn[columnIndex] - before.length - after.length\n )\n\n const cell = before + '-'.repeat(size) + after\n\n if (settings.alignDelimiters !== false) {\n size = before.length + size + after.length\n\n if (size > longestCellByColumn[columnIndex]) {\n longestCellByColumn[columnIndex] = size\n }\n\n sizes[columnIndex] = size\n }\n\n row[columnIndex] = cell\n }\n\n // Inject the alignment row.\n cellMatrix.splice(1, 0, row)\n sizeMatrix.splice(1, 0, sizes)\n\n rowIndex = -1\n /** @type {Array<string>} */\n const lines = []\n\n while (++rowIndex < cellMatrix.length) {\n const row = cellMatrix[rowIndex]\n const sizes = sizeMatrix[rowIndex]\n columnIndex = -1\n /** @type {Array<string>} */\n const line = []\n\n while (++columnIndex < mostCellsPerRow) {\n const cell = row[columnIndex] || ''\n let before = ''\n let after = ''\n\n if (settings.alignDelimiters !== false) {\n const size =\n longestCellByColumn[columnIndex] - (sizes[columnIndex] || 0)\n const code = alignments[columnIndex]\n\n if (code === 114 /* `r` */) {\n before = ' '.repeat(size)\n } else if (code === 99 /* `c` */) {\n if (size % 2) {\n before = ' '.repeat(size / 2 + 0.5)\n after = ' '.repeat(size / 2 - 0.5)\n } else {\n before = ' '.repeat(size / 2)\n after = before\n }\n } else {\n after = ' '.repeat(size)\n }\n }\n\n if (settings.delimiterStart !== false && !columnIndex) {\n line.push('|')\n }\n\n if (\n settings.padding !== false &&\n // Don’t add the opening space if we’re not aligning and the cell is\n // empty: there will be a closing space.\n !(settings.alignDelimiters === false && cell === '') &&\n (settings.delimiterStart !== false || columnIndex)\n ) {\n line.push(' ')\n }\n\n if (settings.alignDelimiters !== false) {\n line.push(before)\n }\n\n line.push(cell)\n\n if (settings.alignDelimiters !== false) {\n line.push(after)\n }\n\n if (settings.padding !== false) {\n line.push(' ')\n }\n\n if (\n settings.delimiterEnd !== false ||\n columnIndex !== mostCellsPerRow - 1\n ) {\n line.push('|')\n }\n }\n\n lines.push(\n settings.delimiterEnd === false\n ? line.join('').replace(/ +$/, '')\n : line.join('')\n )\n }\n\n return lines.join('\\n')\n}\n\n/**\n * @param {string | null | undefined} [value]\n * Value to serialize.\n * @returns {string}\n * Result.\n */\nfunction serialize(value) {\n return value === null || value === undefined ? '' : String(value)\n}\n\n/**\n * @param {string | null | undefined} value\n * Value.\n * @returns {number}\n * Alignment.\n */\nfunction toAlignment(value) {\n const code = typeof value === 'string' ? value.codePointAt(0) : 0\n\n return code === 67 /* `C` */ || code === 99 /* `c` */\n ? 99 /* `c` */\n : code === 76 /* `L` */ || code === 108 /* `l` */\n ? 108 /* `l` */\n : code === 82 /* `R` */ || code === 114 /* `r` */\n ? 114 /* `r` */\n : 0\n}\n","/**\n * @typedef {import('mdast').InlineCode} InlineCode\n * @typedef {import('mdast').Table} Table\n * @typedef {import('mdast').TableCell} TableCell\n * @typedef {import('mdast').TableRow} TableRow\n *\n * @typedef {import('markdown-table').Options} MarkdownTableOptions\n *\n * @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext\n * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension\n * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle\n *\n * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension\n * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle\n * @typedef {import('mdast-util-to-markdown').State} State\n * @typedef {import('mdast-util-to-markdown').Info} Info\n */\n\n/**\n * @typedef Options\n * Configuration.\n * @property {boolean | null | undefined} [tableCellPadding=true]\n * Whether to add a space of padding between delimiters and cells (default:\n * `true`).\n * @property {boolean | null | undefined} [tablePipeAlign=true]\n * Whether to align the delimiters (default: `true`).\n * @property {MarkdownTableOptions['stringLength'] | null | undefined} [stringLength]\n * Function to detect the length of table cell content, used when aligning\n * the delimiters between cells (optional).\n */\n\nimport {ok as assert} from 'devlop'\nimport {markdownTable} from 'markdown-table'\nimport {defaultHandlers} from 'mdast-util-to-markdown'\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM tables in\n * markdown.\n *\n * @returns {FromMarkdownExtension}\n * Extension for `mdast-util-from-markdown` to enable GFM tables.\n */\nexport function gfmTableFromMarkdown() {\n return {\n enter: {\n table: enterTable,\n tableData: enterCell,\n tableHeader: enterCell,\n tableRow: enterRow\n },\n exit: {\n codeText: exitCodeText,\n table: exitTable,\n tableData: exit,\n tableHeader: exit,\n tableRow: exit\n }\n }\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterTable(token) {\n const align = token._align\n assert(align, 'expected `_align` on table')\n this.enter(\n {\n type: 'table',\n align: align.map(function (d) {\n return d === 'none' ? null : d\n }),\n children: []\n },\n token\n )\n this.data.inTable = true\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitTable(token) {\n this.exit(token)\n this.data.inTable = undefined\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterRow(token) {\n this.enter({type: 'tableRow', children: []}, token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exit(token) {\n this.exit(token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterCell(token) {\n this.enter({type: 'tableCell', children: []}, token)\n}\n\n// Overwrite the default code text data handler to unescape escaped pipes when\n// they are in tables.\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitCodeText(token) {\n let value = this.resume()\n\n if (this.data.inTable) {\n value = value.replace(/\\\\([\\\\|])/g, replace)\n }\n\n const node = this.stack[this.stack.length - 1]\n assert(node.type === 'inlineCode')\n node.value = value\n this.exit(token)\n}\n\n/**\n * @param {string} $0\n * @param {string} $1\n * @returns {string}\n */\nfunction replace($0, $1) {\n // Pipes work, backslashes don’t (but can’t escape pipes).\n return $1 === '|' ? $1 : $0\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM tables in\n * markdown.\n *\n * @param {Options | null | undefined} [options]\n * Configuration.\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown` to enable GFM tables.\n */\nexport function gfmTableToMarkdown(options) {\n const settings = options || {}\n const padding = settings.tableCellPadding\n const alignDelimiters = settings.tablePipeAlign\n const stringLength = settings.stringLength\n const around = padding ? ' ' : '|'\n\n return {\n unsafe: [\n {character: '\\r', inConstruct: 'tableCell'},\n {character: '\\n', inConstruct: 'tableCell'},\n // A pipe, when followed by a tab or space (padding), or a dash or colon\n // (unpadded delimiter row), could result in a table.\n {atBreak: true, character: '|', after: '[\\t :-]'},\n // A pipe in a cell must be encoded.\n {character: '|', inConstruct: 'tableCell'},\n // A colon must be followed by a dash, in which case it could start a\n // delimiter row.\n {atBreak: true, character: ':', after: '-'},\n // A delimiter row can also start with a dash, when followed by more\n // dashes, a colon, or a pipe.\n // This is a stricter version than the built in check for lists, thematic\n // breaks, and setex heading underlines though:\n // <https://github.com/syntax-tree/mdast-util-to-markdown/blob/51a2038/lib/unsafe.js#L57>\n {atBreak: true, character: '-', after: '[:|-]'}\n ],\n handlers: {\n inlineCode: inlineCodeWithTable,\n table: handleTable,\n tableCell: handleTableCell,\n tableRow: handleTableRow\n }\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {Table} node\n */\n function handleTable(node, _, state, info) {\n return serializeData(handleTableAsData(node, state, info), node.align)\n }\n\n /**\n * This function isn’t really used normally, because we handle rows at the\n * table level.\n * But, if someone passes in a table row, this ensures we make somewhat sense.\n *\n * @type {ToMarkdownHandle}\n * @param {TableRow} node\n */\n function handleTableRow(node, _, state, info) {\n const row = handleTableRowAsData(node, state, info)\n const value = serializeData([row])\n // `markdown-table` will always add an align row\n return value.slice(0, value.indexOf('\\n'))\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {TableCell} node\n */\n function handleTableCell(node, _, state, info) {\n const exit = state.enter('tableCell')\n const subexit = state.enter('phrasing')\n const value = state.containerPhrasing(node, {\n ...info,\n before: around,\n after: around\n })\n subexit()\n exit()\n return value\n }\n\n /**\n * @param {Array<Array<string>>} matrix\n * @param {Array<string | null | undefined> | null | undefined} [align]\n */\n function serializeData(matrix, align) {\n return markdownTable(matrix, {\n align,\n // @ts-expect-error: `markdown-table` types should support `null`.\n alignDelimiters,\n // @ts-expect-error: `markdown-table` types should support `null`.\n padding,\n // @ts-expect-error: `markdown-table` types should support `null`.\n stringLength\n })\n }\n\n /**\n * @param {Table} node\n * @param {State} state\n * @param {Info} info\n */\n function handleTableAsData(node, state, info) {\n const children = node.children\n let index = -1\n /** @type {Array<Array<string>>} */\n const result = []\n const subexit = state.enter('table')\n\n while (++index < children.length) {\n result[index] = handleTableRowAsData(children[index], state, info)\n }\n\n subexit()\n\n return result\n }\n\n /**\n * @param {TableRow} node\n * @param {State} state\n * @param {Info} info\n */\n function handleTableRowAsData(node, state, info) {\n const children = node.children\n let index = -1\n /** @type {Array<string>} */\n const result = []\n const subexit = state.enter('tableRow')\n\n while (++index < children.length) {\n // Note: the positional info as used here is incorrect.\n // Making it correct would be impossible due to aligning cells?\n // And it would need copy/pasting `markdown-table` into this project.\n result[index] = handleTableCell(children[index], node, state, info)\n }\n\n subexit()\n\n return result\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {InlineCode} node\n */\n function inlineCodeWithTable(node, parent, state) {\n let value = defaultHandlers.inlineCode(node, parent, state)\n\n if (state.stack.includes('tableCell')) {\n value = value.replace(/\\|/g, '\\\\$&')\n }\n\n return value\n }\n}\n","/**\n * @typedef {import('mdast').ListItem} ListItem\n * @typedef {import('mdast').Paragraph} Paragraph\n * @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext\n * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension\n * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle\n * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension\n * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle\n */\n\nimport {ok as assert} from 'devlop'\nimport {defaultHandlers} from 'mdast-util-to-markdown'\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM task\n * list items in markdown.\n *\n * @returns {FromMarkdownExtension}\n * Extension for `mdast-util-from-markdown` to enable GFM task list items.\n */\nexport function gfmTaskListItemFromMarkdown() {\n return {\n exit: {\n taskListCheckValueChecked: exitCheck,\n taskListCheckValueUnchecked: exitCheck,\n paragraph: exitParagraphWithTaskListItem\n }\n }\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM task list\n * items in markdown.\n *\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown` to enable GFM task list items.\n */\nexport function gfmTaskListItemToMarkdown() {\n return {\n unsafe: [{atBreak: true, character: '-', after: '[:|-]'}],\n handlers: {listItem: listItemWithTaskListItem}\n }\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitCheck(token) {\n // We’re always in a paragraph, in a list item.\n const node = this.stack[this.stack.length - 2]\n assert(node.type === 'listItem')\n node.checked = token.type === 'taskListCheckValueChecked'\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitParagraphWithTaskListItem(token) {\n const parent = this.stack[this.stack.length - 2]\n\n if (\n parent &&\n parent.type === 'listItem' &&\n typeof parent.checked === 'boolean'\n ) {\n const node = this.stack[this.stack.length - 1]\n assert(node.type === 'paragraph')\n const head = node.children[0]\n\n if (head && head.type === 'text') {\n const siblings = parent.children\n let index = -1\n /** @type {Paragraph | undefined} */\n let firstParaghraph\n\n while (++index < siblings.length) {\n const sibling = siblings[index]\n if (sibling.type === 'paragraph') {\n firstParaghraph = sibling\n break\n }\n }\n\n if (firstParaghraph === node) {\n // Must start with a space or a tab.\n head.value = head.value.slice(1)\n\n if (head.value.length === 0) {\n node.children.shift()\n } else if (\n node.position &&\n head.position &&\n typeof head.position.start.offset === 'number'\n ) {\n head.position.start.column++\n head.position.start.offset++\n node.position.start = Object.assign({}, head.position.start)\n }\n }\n }\n }\n\n this.exit(token)\n}\n\n/**\n * @type {ToMarkdownHandle}\n * @param {ListItem} node\n */\nfunction listItemWithTaskListItem(node, parent, state, info) {\n const head = node.children[0]\n const checkable =\n typeof node.checked === 'boolean' && head && head.type === 'paragraph'\n const checkbox = '[' + (node.checked ? 'x' : ' ') + '] '\n const tracker = state.createTracker(info)\n\n if (checkable) {\n tracker.move(checkbox)\n }\n\n let value = defaultHandlers.listItem(node, parent, state, {\n ...info,\n ...tracker.current()\n })\n\n if (checkable) {\n value = value.replace(/^(?:[*+-]|\\d+\\.)([\\r\\n]| {1,3})/, check)\n }\n\n return value\n\n /**\n * @param {string} $0\n * @returns {string}\n */\n function check($0) {\n return $0 + checkbox\n }\n}\n","/**\n * Micromark syntax extension + mdast extension for resource tags: {{type:resourceId:text}}\n *\n * Instead of a full micromark extension (which requires complex token/state handling),\n * we use mdast-util-from-markdown's transform hook to post-process text nodes.\n * This is simpler and matches the existing regex approach.\n */\nimport type { Root, PhrasingContent, Text } from 'mdast';\n\nconst RESOURCE_TAG_RE = /\\{\\{([^:}]+):([^:}]*):([^}]+)\\}\\}/g;\nconst VALID_TYPES = new Set(['tool', 'manual', 'agent_message_template', 'handoff', 'time_diff']);\nconst MAX_DEPTH = 128;\n\nexport type ResourceTagMdastNode = {\n type: 'resourceTagMdast';\n data: {\n tagType: string;\n resourceId: string;\n };\n value: string;\n};\n\ndeclare module 'mdast' {\n interface PhrasingContentMap {\n resourceTagMdast: ResourceTagMdastNode;\n }\n\n interface RootContentMap {\n resourceTagMdast: ResourceTagMdastNode;\n }\n}\n\nfunction splitTextWithResourceTags(text: string): (Text | ResourceTagMdastNode)[] {\n const results: (Text | ResourceTagMdastNode)[] = [];\n let lastIndex = 0;\n\n RESOURCE_TAG_RE.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = RESOURCE_TAG_RE.exec(text)) !== null) {\n const [full, tagType, resourceId, displayText] = match;\n if (!VALID_TYPES.has(tagType)) continue;\n\n if (match.index > lastIndex) {\n results.push({ type: 'text', value: text.slice(lastIndex, match.index) });\n }\n results.push({\n type: 'resourceTagMdast',\n data: { tagType, resourceId },\n value: displayText,\n });\n lastIndex = match.index + full.length;\n }\n\n if (lastIndex < text.length) {\n results.push({ type: 'text', value: text.slice(lastIndex) });\n }\n\n return results;\n}\n\nfunction visitNode(node: { children?: unknown[] }, depth: number = 0): void {\n if (depth > MAX_DEPTH) return;\n if (!node.children) return;\n for (const child of node.children) {\n visitNode(child as { children?: unknown[] }, depth + 1);\n }\n if (Array.isArray(node.children)) {\n const newChildren: unknown[] = [];\n for (const child of node.children) {\n if ((child as { type: string }).type === 'text') {\n const parts = splitTextWithResourceTags((child as Text).value);\n newChildren.push(...parts);\n } else {\n newChildren.push(child);\n }\n }\n node.children = newChildren;\n }\n}\n\nexport function resourceTagFromMarkdown() {\n return (tree: Root) => {\n visitNode(tree as unknown as { children?: unknown[] }, 0);\n };\n}\n\n/**\n * Exported for use in combined single-pass transform.\n * Returns the per-node text splitter without constructing a full plugin.\n */\nexport { splitTextWithResourceTags };\n\nexport function resourceTagToMarkdown() {\n return {\n handlers: {\n resourceTagMdast(node: ResourceTagMdastNode): string {\n return `{{${node.data.tagType}:${node.data.resourceId}:${node.value}}}`;\n },\n },\n };\n}\n","/**\n * mdast transform for jump points: ^id^\n * id must match /^[A-Za-z_]+$/\n */\nimport type { Root, Text, PhrasingContent } from 'mdast';\n\nconst JUMP_POINT_RE = /\\^([A-Za-z_]+)\\^/g;\nconst MAX_DEPTH = 128;\n\nexport type JumpPointMdastNode = {\n type: 'jumpPointMdast';\n data: {\n id: string;\n };\n value: string;\n};\n\ndeclare module 'mdast' {\n interface PhrasingContentMap {\n jumpPointMdast: JumpPointMdastNode;\n }\n\n interface RootContentMap {\n jumpPointMdast: JumpPointMdastNode;\n }\n}\n\nfunction splitTextWithJumpPoints(text: string): (Text | JumpPointMdastNode)[] {\n const results: (Text | JumpPointMdastNode)[] = [];\n let lastIndex = 0;\n\n JUMP_POINT_RE.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = JUMP_POINT_RE.exec(text)) !== null) {\n const [full, id] = match;\n\n if (match.index > lastIndex) {\n results.push({ type: 'text', value: text.slice(lastIndex, match.index) });\n }\n results.push({\n type: 'jumpPointMdast',\n data: { id },\n value: id,\n });\n lastIndex = match.index + full.length;\n }\n\n if (lastIndex < text.length) {\n results.push({ type: 'text', value: text.slice(lastIndex) });\n }\n\n return results;\n}\n\nfunction visitNode(node: { children?: unknown[] }, depth: number = 0): void {\n if (depth > MAX_DEPTH) return;\n if (!node.children) return;\n for (const child of node.children) {\n visitNode(child as { children?: unknown[] }, depth + 1);\n }\n if (Array.isArray(node.children)) {\n const newChildren: unknown[] = [];\n for (const child of node.children) {\n if ((child as { type: string }).type === 'text') {\n const parts = splitTextWithJumpPoints((child as Text).value);\n newChildren.push(...parts);\n } else {\n newChildren.push(child);\n }\n }\n node.children = newChildren;\n }\n}\n\nexport function jumpPointFromMarkdown() {\n return (tree: Root) => {\n visitNode(tree as unknown as { children?: unknown[] }, 0);\n };\n}\n\n/**\n * Exported for use in combined single-pass transform.\n * Returns the per-node text splitter without constructing a full plugin.\n */\nexport { splitTextWithJumpPoints };\n\nexport function jumpPointToMarkdown() {\n return {\n handlers: {\n jumpPointMdast(node: JumpPointMdastNode): string {\n return `^${node.data.id}^`;\n },\n },\n };\n}\n","/**\n * Bidirectional conversion between mdast and ActionbookAST.\n */\nimport type { Root, RootContent, PhrasingContent, List, ListItem, Paragraph, Heading, Blockquote, ThematicBreak, Text as MdastText, Strong, Emphasis, InlineCode, Link, Break, Delete } from 'mdast';\nimport type { ResourceTagMdastNode } from './plugins/resourceTag';\nimport type { JumpPointMdastNode } from './plugins/jumpPoint';\nimport type { JinjaIfBlockMdastNode, JinjaIfInlineMdastNode, JinjaBranchMdast } from './plugins/jinjaBlock';\nimport type {\n DocumentNode,\n BlockNode,\n InlineNode,\n Mark,\n TextNode,\n ParagraphNode,\n HeadingNode,\n BulletListNode,\n OrderedListNode,\n ListItemNode,\n BlockquoteNode,\n HorizontalRuleNode,\n ResourceTagNode,\n JumpPointNode,\n HardBreakNode,\n TableNode,\n TableRowNode,\n TableCellNode,\n JinjaIfBlockNode,\n JinjaIfInlineNode,\n JinjaIfBranch,\n} from '../ast/types';\n\nconst MAX_DEPTH = 128;\nconst ALLOWED_URL_PROTOCOLS = /^(https?:|mailto:|tel:|#|\\/)/i;\n\nfunction sanitizeUrl(url: string): string {\n if (ALLOWED_URL_PROTOCOLS.test(url)) return url;\n // Strip dangerous protocols (javascript:, data:, vbscript:, etc.)\n return '';\n}\n\nclass DepthError extends Error {\n constructor(depth: number) {\n super(`Maximum mdast conversion depth (${MAX_DEPTH}) exceeded at depth ${depth}`);\n this.name = 'DepthError';\n }\n}\n\n// === mdast → ActionbookAST ===\n\nfunction convertInline(node: PhrasingContent, marks: Mark[] = [], depth: number = 0): InlineNode[] {\n if (depth > MAX_DEPTH) throw new DepthError(depth);\n\n switch (node.type) {\n case 'text':\n return [marks.length > 0 ? { type: 'text', text: node.value, marks } : { type: 'text', text: node.value }];\n\n case 'strong': {\n const childMarks: Mark[] = [...marks, { type: 'bold' }];\n return (node as Strong).children.flatMap((child) => convertInline(child as PhrasingContent, childMarks, depth + 1));\n }\n\n case 'emphasis': {\n const childMarks: Mark[] = [...marks, { type: 'italic' }];\n return (node as Emphasis).children.flatMap((child) => convertInline(child as PhrasingContent, childMarks, depth + 1));\n }\n\n case 'delete': {\n const childMarks: Mark[] = [...marks, { type: 'strikethrough' }];\n return (node as Delete).children.flatMap((child) => convertInline(child as PhrasingContent, childMarks, depth + 1));\n }\n\n case 'inlineCode':\n return [\n marks.length > 0\n ? { type: 'text', text: (node as InlineCode).value, marks: [...marks, { type: 'code' }] }\n : { type: 'text', text: (node as InlineCode).value, marks: [{ type: 'code' }] },\n ];\n\n case 'link': {\n const href = sanitizeUrl((node as Link).url);\n if (!href) {\n // Dangerous URL protocol → strip the link, keep children as plain text\n return (node as Link).children.flatMap((child) => convertInline(child as PhrasingContent, marks, depth + 1));\n }\n const linkMark: Mark = { type: 'link', href, ...((node as Link).title ? { title: (node as Link).title! } : {}) };\n const childMarks: Mark[] = [...marks, linkMark];\n return (node as Link).children.flatMap((child) => convertInline(child as PhrasingContent, childMarks, depth + 1));\n }\n\n case 'break':\n return [{ type: 'hardBreak' }];\n\n case 'resourceTagMdast' as string: {\n const rtNode = node as unknown as ResourceTagMdastNode;\n return [\n {\n type: 'resourceTag',\n tagType: rtNode.data.tagType as ResourceTagNode['tagType'],\n resourceId: rtNode.data.resourceId,\n text: rtNode.value,\n },\n ];\n }\n\n case 'jumpPointMdast' as string: {\n const jpNode = node as unknown as JumpPointMdastNode;\n return [{ type: 'jumpPoint', id: jpNode.data.id }];\n }\n\n case 'jinjaIfInlineMdast' as string: {\n const jNode = node as unknown as JinjaIfInlineMdastNode;\n const branches: JinjaIfBranch<InlineNode>[] = jNode.branches.map(b => ({\n branchType: b.branchType,\n ...(b.condition ? { condition: b.condition } : {}),\n content: (b.content as PhrasingContent[]).flatMap(c => convertInline(c, [], depth + 1)),\n }));\n return [{ type: 'jinjaIfInline', branches } as InlineNode];\n }\n\n default:\n if ('value' in node && typeof (node as { value: unknown }).value === 'string') {\n return [{ type: 'text', text: (node as { value: string }).value }];\n }\n if ('children' in node && Array.isArray((node as { children: unknown[] }).children)) {\n return (node as { children: PhrasingContent[] }).children.flatMap((child) => convertInline(child, marks, depth + 1));\n }\n return [];\n }\n}\n\nfunction convertBlock(node: RootContent, depth: number = 0): BlockNode[] {\n if (depth > MAX_DEPTH) throw new DepthError(depth);\n\n switch (node.type) {\n case 'paragraph': {\n const para = node as Paragraph;\n const content = para.children.flatMap((child) => convertInline(child as PhrasingContent, [], depth + 1));\n return [{ type: 'paragraph', content }];\n }\n\n case 'heading': {\n const h = node as Heading;\n const content = h.children.flatMap((child) => convertInline(child as PhrasingContent, [], depth + 1));\n return [{ type: 'heading', level: h.depth as HeadingNode['level'], content }];\n }\n\n case 'list': {\n const list = node as List;\n const items = list.children.map((li) => convertListItem(li, depth + 1));\n if (list.ordered) {\n return [{ type: 'orderedList', start: list.start ?? 1, content: items }];\n }\n return [{ type: 'bulletList', content: items }];\n }\n\n case 'blockquote': {\n const bq = node as Blockquote;\n const content = bq.children.flatMap((child) => convertBlock(child, depth + 1));\n return [{ type: 'blockquote', content }];\n }\n\n case 'thematicBreak':\n return [{ type: 'horizontalRule' }];\n\n case 'jinjaIfBlockMdast' as string: {\n const jNode = node as unknown as JinjaIfBlockMdastNode;\n const branches: JinjaIfBranch<BlockNode>[] = jNode.branches.map(b => ({\n branchType: b.branchType,\n ...(b.condition ? { condition: b.condition } : {}),\n content: (b.content as RootContent[]).flatMap(c => convertBlock(c, depth + 1)),\n }));\n return [{ type: 'jinjaIfBlock', branches } as BlockNode];\n }\n\n case 'table': {\n const tbl = node as { type: 'table'; children: Array<{ type: 'tableRow'; children: Array<{ type: 'tableCell'; children: PhrasingContent[] }> }>; align?: (string | null)[] };\n const rows: TableRowNode[] = tbl.children.map((row, rowIdx) => {\n const cells: TableCellNode[] = row.children.map((cell) => {\n const content = cell.children.flatMap((child) => convertInline(child as PhrasingContent, [], depth + 2));\n return {\n type: 'tableCell' as const,\n ...(rowIdx === 0 ? { header: true } : {}),\n content,\n };\n });\n return { type: 'tableRow' as const, content: cells };\n });\n return [{ type: 'table', content: rows }];\n }\n\n default:\n if ('children' in node && Array.isArray((node as { children: unknown[] }).children)) {\n const inlines = (node as { children: PhrasingContent[] }).children.flatMap((child) =>\n convertInline(child as PhrasingContent, [], depth + 1),\n );\n if (inlines.length > 0) return [{ type: 'paragraph', content: inlines }];\n }\n if ('value' in node && typeof (node as { value: unknown }).value === 'string') {\n return [{ type: 'paragraph', content: [{ type: 'text', text: (node as { value: string }).value }] }];\n }\n return [];\n }\n}\n\nfunction convertListItem(node: ListItem, depth: number = 0): ListItemNode {\n if (depth > MAX_DEPTH) throw new DepthError(depth);\n const content = node.children.flatMap((child) => convertBlock(child as RootContent, depth + 1));\n const base: ListItemNode = { type: 'listItem', content: content.length > 0 ? content : [{ type: 'paragraph', content: [] }] };\n if (typeof node.checked === 'boolean') {\n return { ...base, checked: node.checked };\n }\n return base;\n}\n\nexport function fromMdast(root: Root): DocumentNode {\n const blocks: BlockNode[] = [];\n\n for (let i = 0; i < root.children.length; i++) {\n // Detect extra blank lines between consecutive blocks and restore as empty paragraphs.\n // Standard markdown block separation = 1 blank line. Each additional blank line\n // maps to one empty paragraph (1:1), matching the serializer's join function\n // that outputs \\n (instead of \\n\\n) after empty paragraphs.\n if (i > 0) {\n const prev = root.children[i - 1] as { position?: { end?: { line?: number } } };\n const curr = root.children[i] as { position?: { start?: { line?: number } } };\n const prevEndLine = prev.position?.end?.line ?? 0;\n const currStartLine = curr.position?.start?.line ?? 0;\n const emptyCount = currStartLine - prevEndLine - 2;\n for (let j = 0; j < emptyCount; j++) {\n blocks.push({ type: 'paragraph', content: [] });\n }\n }\n\n blocks.push(...convertBlock(root.children[i], 0));\n }\n\n return { type: 'doc', content: blocks.length > 0 ? blocks : [{ type: 'paragraph', content: [] }] };\n}\n\n// === ActionbookAST → mdast ===\n\nfunction inlineToMdast(node: InlineNode, depth: number = 0): PhrasingContent[] {\n if (depth > MAX_DEPTH) throw new DepthError(depth);\n\n switch (node.type) {\n case 'text': {\n const marks = node.marks ?? [];\n let result: PhrasingContent[] = [{ type: 'text', value: node.text } as MdastText];\n\n for (const mark of marks) {\n switch (mark.type) {\n case 'bold':\n result = [{ type: 'strong', children: result as Strong['children'] }];\n break;\n case 'italic':\n result = [{ type: 'emphasis', children: result as Emphasis['children'] }];\n break;\n case 'strikethrough':\n result = [{ type: 'delete', children: result as Delete['children'] }];\n break;\n case 'underline':\n // Underline has no markdown representation; mark is lost on serialization\n break;\n case 'code':\n result = [{ type: 'inlineCode', value: node.text }];\n break;\n case 'link':\n result = [\n {\n type: 'link',\n url: mark.href,\n ...(mark.title ? { title: mark.title } : {}),\n children: result as Link['children'],\n },\n ];\n break;\n }\n }\n return result;\n }\n\n case 'resourceTag':\n return [\n {\n type: 'resourceTagMdast',\n data: { tagType: node.tagType, resourceId: node.resourceId },\n value: node.text,\n } as unknown as PhrasingContent,\n ];\n\n case 'jumpPoint':\n return [\n {\n type: 'jumpPointMdast',\n data: { id: node.id },\n value: node.id,\n } as unknown as PhrasingContent,\n ];\n\n case 'hardBreak':\n return [{ type: 'break' } as Break];\n\n case 'jinjaIfInline': {\n const jNode = node as JinjaIfInlineNode;\n const result: PhrasingContent[] = [];\n for (const branch of jNode.branches) {\n const tagText = branch.branchType === 'else'\n ? '{% else %}'\n : `{% ${branch.branchType} ${branch.condition ?? ''} %}`.trim();\n result.push({ type: 'text', value: tagText } as MdastText);\n for (const child of branch.content) {\n result.push(...inlineToMdast(child, depth + 1));\n }\n }\n result.push({ type: 'text', value: '{% endif %}' } as MdastText);\n return result;\n }\n }\n}\n\nfunction blockToMdast(node: BlockNode, depth: number = 0): RootContent[] {\n if (depth > MAX_DEPTH) throw new DepthError(depth);\n\n switch (node.type) {\n case 'paragraph':\n return [{ type: 'paragraph', children: node.content.flatMap((c) => inlineToMdast(c, depth + 1)) }];\n\n case 'heading':\n return [{ type: 'heading', depth: node.level, children: node.content.flatMap((c) => inlineToMdast(c, depth + 1)) }];\n\n case 'bulletList':\n return [\n {\n type: 'list',\n ordered: false,\n spread: false,\n children: node.content.map((li) => listItemToMdast(li, depth + 1)),\n },\n ];\n\n case 'orderedList':\n return [\n {\n type: 'list',\n ordered: true,\n start: node.start,\n spread: false,\n children: node.content.map((li) => listItemToMdast(li, depth + 1)),\n },\n ];\n\n case 'listItem':\n return listItemToMdast(node, depth).children.flatMap((child) => [child as RootContent]);\n\n case 'blockquote':\n return [{ type: 'blockquote', children: node.content.flatMap((c) => blockToMdast(c, depth + 1)) as Blockquote['children'] }];\n\n case 'horizontalRule':\n return [{ type: 'thematicBreak' }];\n\n case 'jinjaIfBlock': {\n const jNode = node as JinjaIfBlockNode;\n const result: RootContent[] = [];\n for (const branch of jNode.branches) {\n const tagText = branch.branchType === 'else'\n ? '{% else %}'\n : `{% ${branch.branchType} ${branch.condition ?? ''} %}`.trim();\n result.push({ type: 'paragraph', children: [{ type: 'text', value: tagText } as MdastText] } as Paragraph);\n for (const child of branch.content) {\n result.push(...blockToMdast(child, depth + 1));\n }\n }\n result.push({ type: 'paragraph', children: [{ type: 'text', value: '{% endif %}' } as MdastText] } as Paragraph);\n return result;\n }\n\n case 'table': {\n const rows = node.content.map((row) => ({\n type: 'tableRow' as const,\n children: row.content.map((cell) => ({\n type: 'tableCell' as const,\n children: cell.content.flatMap((c) => inlineToMdast(c, depth + 2)) as PhrasingContent[],\n })),\n }));\n return [{ type: 'table', children: rows } as unknown as RootContent];\n }\n }\n}\n\nfunction listItemToMdast(node: ListItemNode, depth: number = 0): ListItem {\n if (depth > MAX_DEPTH) throw new DepthError(depth);\n const result: ListItem = {\n type: 'listItem',\n spread: false,\n children: node.content.flatMap((child) => blockToMdast(child, depth + 1)) as ListItem['children'],\n };\n if (typeof node.checked === 'boolean') {\n result.checked = node.checked;\n }\n return result;\n}\n\nexport function toMdast(doc: DocumentNode): Root {\n return {\n type: 'root',\n children: doc.content.flatMap((c) => blockToMdast(c, 0)),\n };\n}\n","/**\n * Convert ActionbookAST → ProseMirror JSONContent.\n */\nimport type { BlockNode, DocumentNode, InlineNode, JinjaIfBlockNode, JinjaIfInlineNode, Mark } from '../../ast/types';\nimport type { JSONContent } from '../../compat/prosemirror';\n\nconst ALLOWED_URL_PROTOCOLS = /^(https?:|mailto:|tel:|#|\\/)/i;\n\nfunction assertNever(value: never): never {\n throw new Error(`Unexpected AST node: ${JSON.stringify(value)}`);\n}\n\nfunction convertMark(mark: Mark): NonNullable<JSONContent['marks']>[number] {\n switch (mark.type) {\n case 'bold':\n return { type: 'bold' };\n case 'italic':\n return { type: 'italic' };\n case 'underline':\n return { type: 'underline' };\n case 'strikethrough':\n return { type: 'strikethrough' };\n case 'code':\n return { type: 'code' };\n case 'link': {\n const href = ALLOWED_URL_PROTOCOLS.test(mark.href) ? mark.href : '';\n return mark.title ? { type: 'link', attrs: { href, title: mark.title } } : { type: 'link', attrs: { href } };\n }\n default:\n return assertNever(mark);\n }\n}\n\nfunction convertInlineToArray(node: InlineNode): JSONContent[] {\n switch (node.type) {\n case 'jinjaIfInline': {\n const jNode = node as JinjaIfInlineNode;\n const parts: JSONContent[] = [];\n for (const branch of jNode.branches) {\n const tagText = branch.branchType === 'else'\n ? '{% else %}'\n : `{% ${branch.branchType} ${branch.condition ?? ''} %}`.trim();\n parts.push({ type: 'text', text: tagText });\n for (const child of branch.content) {\n parts.push(...convertInlineToArray(child));\n }\n }\n parts.push({ type: 'text', text: '{% endif %}' });\n return parts;\n }\n default:\n return [convertInline(node)];\n }\n}\n\nexport function convertInline(node: InlineNode): JSONContent {\n switch (node.type) {\n case 'text': {\n const result: JSONContent = { type: 'text', text: node.text };\n if (node.marks && node.marks.length > 0) {\n result.marks = node.marks.map(convertMark);\n }\n return result;\n }\n case 'resourceTag':\n return {\n type: 'inlineToolTag',\n attrs: {\n type: node.tagType,\n resourceId: node.resourceId,\n text: node.text,\n },\n };\n case 'jumpPoint':\n return {\n type: 'jumpPoint',\n attrs: { id: node.id },\n };\n case 'hardBreak':\n return { type: 'hardBreak' };\n case 'jinjaIfInline': {\n // Flatten to single text node for PM\n const parts = convertInlineToArray(node);\n const fullText = parts.map(p => p.text ?? '').join('');\n return { type: 'text', text: fullText };\n }\n default:\n return assertNever(node as never);\n }\n}\n\n/**\n * Maximum list nesting depth. Beyond this, nested lists are flattened\n * to prevent browser layout hangs with deeply indented markdown.\n */\nconst MAX_LIST_DEPTH = 3;\n\nfunction convertBlockToArray(node: BlockNode, listDepth: number = 0): JSONContent[] {\n if (node.type === 'jinjaIfBlock') {\n const jNode = node as JinjaIfBlockNode;\n const result: JSONContent[] = [];\n for (const branch of jNode.branches) {\n const tagText = branch.branchType === 'else'\n ? '{% else %}'\n : `{% ${branch.branchType} ${branch.condition ?? ''} %}`.trim();\n result.push({ type: 'paragraph', content: [{ type: 'text', text: tagText }] });\n for (const child of branch.content) {\n result.push(...convertBlockToArray(child, listDepth));\n }\n }\n result.push({ type: 'paragraph', content: [{ type: 'text', text: '{% endif %}' }] });\n return result;\n }\n return [convertBlock(node, listDepth)];\n}\n\nexport function convertBlock(node: BlockNode, listDepth: number = 0): JSONContent {\n switch (node.type) {\n case 'paragraph':\n return {\n type: 'paragraph',\n content: node.content.flatMap(convertInlineToArray),\n };\n case 'heading':\n return {\n type: 'heading',\n attrs: { level: node.level },\n content: node.content.flatMap(convertInlineToArray),\n };\n case 'bulletList': {\n if (listDepth >= MAX_LIST_DEPTH) {\n // Flatten: extract list item contents as paragraphs\n return flattenListToBlock(node);\n }\n return {\n type: 'bulletList',\n content: node.content.map((c) => convertBlock(c, listDepth + 1)),\n };\n }\n case 'orderedList': {\n if (listDepth >= MAX_LIST_DEPTH) {\n return flattenListToBlock(node);\n }\n return {\n type: 'orderedList',\n attrs: { start: node.start },\n content: node.content.map((c) => convertBlock(c, listDepth + 1)),\n };\n }\n case 'listItem': {\n const result: JSONContent = {\n type: 'listItem',\n content: node.content.flatMap((c) => convertBlockToArray(c, listDepth)),\n };\n if (node.checked != null) {\n result.attrs = { checked: node.checked };\n }\n return result;\n }\n case 'blockquote':\n return {\n type: 'blockquote',\n content: node.content.flatMap((c) => convertBlockToArray(c, listDepth)),\n };\n case 'horizontalRule':\n return { type: 'horizontalRule' };\n case 'table':\n return {\n type: 'table',\n content: node.content.map((row) => ({\n type: 'tableRow',\n content: row.content.map((cell) => ({\n type: cell.header ? 'tableHeader' : 'tableCell',\n content: cell.content.flatMap(convertInlineToArray),\n })),\n })),\n };\n case 'jinjaIfBlock': {\n // Should be handled by convertBlockToArray, but handle here for direct calls\n const jNode = node as JinjaIfBlockNode;\n const result: JSONContent[] = [];\n for (const branch of jNode.branches) {\n const tagText = branch.branchType === 'else'\n ? '{% else %}'\n : `{% ${branch.branchType} ${branch.condition ?? ''} %}`.trim();\n result.push({ type: 'paragraph', content: [{ type: 'text', text: tagText }] });\n for (const child of branch.content) {\n result.push(...convertBlockToArray(child, listDepth));\n }\n }\n result.push({ type: 'paragraph', content: [{ type: 'text', text: '{% endif %}' }] });\n return result[0] ?? { type: 'paragraph', content: [] };\n }\n default:\n return assertNever(node as never);\n }\n}\n\n/**\n * Flatten a list node that exceeds MAX_LIST_DEPTH into paragraphs.\n * Preserves text content but removes further nesting.\n */\nfunction flattenListToBlock(node: BlockNode): JSONContent {\n const paragraphs: JSONContent[] = [];\n function extractInlines(n: BlockNode) {\n switch (n.type) {\n case 'paragraph':\n case 'heading':\n paragraphs.push({\n type: 'paragraph',\n content: n.content.flatMap(convertInlineToArray),\n });\n break;\n case 'listItem':\n case 'blockquote':\n for (const child of n.content) extractInlines(child);\n break;\n case 'bulletList':\n case 'orderedList':\n for (const item of n.content) extractInlines(item);\n break;\n default:\n break;\n }\n }\n extractInlines(node);\n return paragraphs.length > 0 ? paragraphs[0] : { type: 'paragraph', content: [] };\n}\n\nexport function toProseMirrorJSON(doc: DocumentNode): JSONContent {\n return {\n type: 'doc',\n content: doc.content.flatMap((c) => convertBlockToArray(c, 0)),\n };\n}\n\n/**\n * Convert parseFragment() output (InlineNode[] | BlockNode[]) to PM JSONContent[].\n * If nodes are inline, wraps them in a single paragraph.\n */\nexport function astNodesToJSONContent(nodes: (InlineNode | BlockNode)[]): JSONContent[] {\n if (nodes.length === 0) return [];\n\n const firstType = nodes[0].type;\n const isInlineFragment =\n firstType === 'text' || firstType === 'resourceTag' || firstType === 'jumpPoint' || firstType === 'hardBreak';\n\n if (isInlineFragment) {\n return [{ type: 'paragraph', content: (nodes as InlineNode[]).flatMap(convertInlineToArray) }];\n }\n\n return (nodes as BlockNode[]).flatMap(convertBlockToArray);\n}\n","/**\n * Input rules for markdown-style text formatting.\n *\n * Provides real-time conversion of typed markdown syntax into ProseMirror nodes/marks:\n *\n * \"- \" or \"* \" → bulletList\n * \"1. \" → orderedList\n * \"- [ ] \" / \"- [x] \" → bulletList with todo item\n * \"^id^\" → jumpPoint (duplicate IDs are rejected)\n * **text** → bold\n * *text* → italic\n * ~~text~~ → strikethrough\n * `text` → inline code\n */\nimport { InputRule, wrappingInputRule } from 'prosemirror-inputrules';\nimport type { MarkType } from 'prosemirror-model';\nimport { actionbookSchema } from '../schema';\nimport type { ActionbookPlugin } from './types';\n\nconst BULLET_LIST_RE = /^\\s*([-*])\\s$/;\nconst ORDERED_LIST_RE = /^(\\d+)\\.\\s$/;\nconst JUMP_POINT_RE = /\\^([A-Za-z_][A-Za-z0-9_]*)\\^$/;\n\n// Inline mark autoformat patterns\n// **text** or __text__ → bold\nconst BOLD_STAR_RE = /(?:^|[^*])\\*\\*([^*]+)\\*\\*$/;\nconst BOLD_UNDER_RE = /(?:^|[^_])__([^_]+)__$/;\n// *text* or _text_ → italic (must not match **)\nconst ITALIC_STAR_RE = /(?:^|[^*])\\*([^*]+)\\*$/;\nconst ITALIC_UNDER_RE = /(?:^|[^_])_([^_]+)_$/;\n// ~~text~~ → strikethrough\nconst STRIKE_RE = /(?:^|[^~])~~([^~]+)~~$/;\n// `text` → inline code\nconst CODE_RE = /(?:^|[^`])`([^`]+)`$/;\n\nfunction markInputRule(pattern: RegExp, markType: MarkType, markerLen: number): InputRule {\n return new InputRule(pattern, (state, match, start, end) => {\n const textContent = match[1];\n // Adjust start to account for possible non-marker character before the opening marker\n const fullMatch = match[0];\n const actualStart = end - fullMatch.length + (fullMatch.length - markerLen * 2 - textContent.length);\n\n const tr = state.tr;\n tr.delete(actualStart, end);\n const textNode = state.schema.text(textContent, [markType.create()]);\n tr.insert(actualStart, textNode);\n return tr;\n });\n}\n\nexport function createInputRulesPlugin(): ActionbookPlugin {\n return {\n name: 'inputRules',\n inputRules: () => {\n const rules: InputRule[] = [];\n\n // \"- \" or \"* \" → bulletList\n rules.push(wrappingInputRule(BULLET_LIST_RE, actionbookSchema.nodes.bulletList));\n\n // \"1. \" → orderedList (preserves start number)\n rules.push(\n wrappingInputRule(ORDERED_LIST_RE, actionbookSchema.nodes.orderedList, (match) => ({\n start: +match[1],\n })),\n );\n\n // \"- [ ] \" or \"- [x] \" → bulletList with checked listItem\n rules.push(\n new InputRule(/^\\s*[-*]\\s\\[([ xX])\\]\\s$/, (state, match, start, end) => {\n const checked = match[1] !== ' ';\n const { bulletList: blType, listItem: liType } = actionbookSchema.nodes;\n const li = liType.create({ checked }, state.schema.nodes.paragraph.create());\n const list = blType.create(null, li);\n return state.tr.delete(start, end).insert(start, list);\n }),\n );\n\n // \"^id^\" → jumpPoint (rejects duplicate IDs)\n const jumpPointType = actionbookSchema.nodes.jumpPoint;\n rules.push(\n new InputRule(JUMP_POINT_RE, (state, match, start, end) => {\n const id = match[1];\n let exists = false;\n state.doc.descendants((node) => {\n if (node.type === jumpPointType && node.attrs.id === id) {\n exists = true;\n return false;\n }\n });\n if (exists) return null;\n return state.tr.delete(start, end).insert(start, jumpPointType.create({ id }));\n }),\n );\n\n // Inline mark input rules\n rules.push(markInputRule(BOLD_STAR_RE, actionbookSchema.marks.bold, 2));\n rules.push(markInputRule(BOLD_UNDER_RE, actionbookSchema.marks.bold, 2));\n rules.push(markInputRule(ITALIC_STAR_RE, actionbookSchema.marks.italic, 1));\n rules.push(markInputRule(ITALIC_UNDER_RE, actionbookSchema.marks.italic, 1));\n rules.push(markInputRule(STRIKE_RE, actionbookSchema.marks.strikethrough, 2));\n rules.push(markInputRule(CODE_RE, actionbookSchema.marks.code, 1));\n\n return rules;\n },\n };\n}\n","/**\n * Keymap plugin for the Actionbook editor.\n *\n * Provides keyboard shortcuts matching the sbdashboard Tiptap editor:\n *\n * Backspace — lift list item out one depth when cursor is at start\n * Tab — sink (indent) list item, or insert tab char\n * Shift-Tab — lift (outdent) list item, or delete tab char\n * Enter — split list item; lift empty list item out of list\n * Shift-Enter — insert hardBreak\n * Mod-Shift-7 — wrap selection in bulletList\n * Mod-Shift-8 — wrap selection in orderedList\n */\nimport { chainCommands, newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock, toggleMark } from 'prosemirror-commands';\nimport { liftListItem, sinkListItem, splitListItem, wrapInList } from 'prosemirror-schema-list';\nimport type { Command } from 'prosemirror-state';\nimport { actionbookSchema } from '../schema';\nimport type { ActionbookPlugin } from './types';\n\nconst TAB_CHAR = '\\u0009';\n\nconst { listItem, bulletList, orderedList, hardBreak } = actionbookSchema.nodes;\nconst { bold: boldMark, italic: italicMark, underline: underlineMark, strikethrough: strikethroughMark, code: codeMark } = actionbookSchema.marks;\n\n/**\n * Returns true only when the cursor's block is the direct child of a listItem.\n * Using `depth - 1` instead of walking all ancestors avoids false positives\n * when a listItem is a distant ancestor (e.g. cursor in a blockquote inside a\n * listItem) — those cases should fall through to the default Backspace handler.\n */\nfunction cursorDirectlyInListItem(state: Parameters<Command>[0]): boolean {\n const { $from } = state.selection;\n return $from.depth >= 2 && $from.node($from.depth - 1).type === listItem;\n}\n\n/**\n * Backspace at the start of a list item → lift one depth out.\n * Prevents the default join-backward behaviour and acts like Shift-Tab.\n */\nconst backspaceCommand: Command = (state, dispatch) => {\n const { $from } = state.selection;\n if (!state.selection.empty) return false;\n if ($from.parentOffset !== 0) return false;\n if (!cursorDirectlyInListItem(state)) return false;\n // Only intercept when cursor is in the FIRST child of the listItem.\n // If cursor is in a later block (e.g. empty paragraph after a nested list),\n // fall through to joinBackward so cursor moves to the end of the previous block.\n if ($from.index($from.depth - 1) !== 0) return false;\n return liftListItem(listItem)(state, dispatch);\n};\n\nconst tabCommand: Command = (state, dispatch) => {\n const { $from } = state.selection;\n if (cursorDirectlyInListItem(state) && $from.parentOffset === 0) {\n if (sinkListItem(listItem)(state, dispatch)) return true;\n }\n if (dispatch) dispatch(state.tr.insertText(TAB_CHAR));\n return true;\n};\n\nconst shiftTabCommand: Command = (state, dispatch) => {\n const { $from } = state.selection;\n if (cursorDirectlyInListItem(state) && $from.parentOffset === 0) {\n return liftListItem(listItem)(state, dispatch);\n }\n const pos = $from.pos;\n if (state.doc.textBetween(pos - 1, pos) === TAB_CHAR) {\n if (dispatch) dispatch(state.tr.delete(pos - 1, pos));\n return true;\n }\n return true;\n};\n\nconst enterCommand: Command = chainCommands(\n newlineInCode,\n // Split list item on Enter; lift empty list item out of list\n splitListItem(listItem),\n createParagraphNear,\n liftEmptyBlock,\n splitBlock,\n);\n\nconst shiftEnterCommand: Command = (state, dispatch) => {\n if (dispatch) {\n dispatch(\n state.tr.replaceSelectionWith(hardBreak.create()).scrollIntoView(),\n );\n }\n return true;\n};\n\nexport function createKeymapPlugin(): ActionbookPlugin {\n return {\n name: 'keymapPlugin',\n keymap: () => ({\n Backspace: backspaceCommand,\n Tab: tabCommand,\n 'Shift-Tab': shiftTabCommand,\n Enter: enterCommand,\n 'Shift-Enter': shiftEnterCommand,\n 'Mod-b': toggleMark(boldMark),\n 'Mod-i': toggleMark(italicMark),\n 'Mod-u': toggleMark(underlineMark),\n 'Mod-Shift-x': toggleMark(strikethroughMark),\n 'Mod-e': toggleMark(codeMark),\n 'Mod-Shift-7': wrapInList(bulletList),\n 'Mod-Shift-8': wrapInList(orderedList),\n }),\n };\n}\n","/**\n * Clipboard plugin: paste plain-text / markdown → ProseMirror nodes,\n * copy ProseMirror nodes → markdown text.\n *\n * Mirrors the MarkdownClipboardManager from sbdashboard, using\n * actionbook-core's own parseFragment / serializeFragment / fromProseMirrorJSON.\n *\n * Jump-point deduplication: if a pasted `^id^` already exists in the doc,\n * the caret `^...^` markers are stripped so the text is kept as plain text\n * rather than creating a duplicate node.\n */\nimport { Fragment, Slice } from 'prosemirror-model';\nimport { Plugin, PluginKey } from 'prosemirror-state';\nimport type { EditorView } from 'prosemirror-view';\nimport { parseFragment, serializeFragment, fromProseMirrorJSON } from '../../index';\nimport { astNodesToJSONContent } from '../bridge/toProseMirrorJSON';\nimport { actionbookSchema } from '../schema';\nimport type { ActionbookPlugin } from './types';\n\nconst key = new PluginKey('markdownClipboard');\n\nfunction textToSlice(text: string, view: EditorView): Slice | null {\n try {\n const existingIds = new Set<string>();\n view.state.doc.descendants((node) => {\n if (node.type.name === 'jumpPoint') existingIds.add(node.attrs.id as string);\n });\n\n // Strip duplicate jump-point markers\n const deduped = text.replace(/\\^([A-Za-z_][A-Za-z0-9_]*)\\^/gm, (match, id) => {\n if (existingIds.has(id)) return id; // keep as plain text\n existingIds.add(id);\n return match;\n });\n\n const astNodes = parseFragment(deduped);\n const pmJSONNodes = astNodesToJSONContent(astNodes);\n const pmNodes = pmJSONNodes.map((json) => actionbookSchema.nodeFromJSON(json));\n const fragment = Fragment.fromArray(pmNodes);\n // Single paragraph → inline paste (openDepth 1); otherwise block paste\n const openDepth = pmJSONNodes.length === 1 && pmJSONNodes[0].type === 'paragraph' ? 1 : 0;\n return new Slice(fragment, openDepth, openDepth);\n } catch {\n return null;\n }\n}\n\nfunction createPlugin(): Plugin {\n return new Plugin({\n key,\n props: {\n handlePaste(view: EditorView, event: ClipboardEvent) {\n const text = event.clipboardData?.getData('text/plain');\n if (!text) return false;\n\n const slice = textToSlice(text, view);\n if (!slice) return false;\n\n view.dispatch(view.state.tr.replaceSelection(slice));\n return true;\n },\n\n clipboardTextParser(text: string, _$context, _plain, view) {\n if (!text) return Slice.empty;\n const slice = textToSlice(text, view!);\n if (!slice) {\n const textNode = actionbookSchema.text(text);\n return new Slice(Fragment.from(textNode), 0, 0);\n }\n return slice;\n },\n\n // Discard pasted HTML — always prefer plain-text markdown\n transformPastedHTML() {\n return '';\n },\n\n clipboardTextSerializer(slice: Slice) {\n try {\n const jsonNodes: Record<string, unknown>[] = [];\n slice.content.forEach((node) => jsonNodes.push(node.toJSON()));\n const doc = fromProseMirrorJSON({ type: 'doc', content: jsonNodes });\n return serializeFragment(doc.content as Parameters<typeof serializeFragment>[0]);\n } catch {\n return '';\n }\n },\n },\n });\n}\n\nexport function createMarkdownClipboardPlugin(): ActionbookPlugin {\n return {\n name: 'markdownClipboard',\n plugins: () => [createPlugin()],\n };\n}\n","import type { AstNode, BlockNode, DocumentNode, InlineNode, JinjaIfBlockNode, JinjaIfInlineNode, NodePath } from './types';\n\n/**\n * Maximum recursion depth for all tree traversal functions.\n * Prevents stack overflow from maliciously deep or malformed input.\n */\nexport const MAX_DEPTH = 128;\n\nexport class TraversalDepthError extends Error {\n constructor(depth: number) {\n super(`Maximum traversal depth (${MAX_DEPTH}) exceeded at depth ${depth}`);\n this.name = 'TraversalDepthError';\n }\n}\n\nfunction getChildren(node: AstNode): readonly AstNode[] {\n switch (node.type) {\n case 'doc':\n case 'blockquote':\n case 'listItem':\n return node.content;\n case 'paragraph':\n case 'heading':\n return node.content;\n case 'bulletList':\n case 'orderedList':\n return node.content;\n case 'jinjaIfBlock':\n return node.branches.flatMap(b => b.content as readonly AstNode[]);\n case 'jinjaIfInline':\n return node.branches.flatMap(b => b.content as readonly AstNode[]);\n default:\n return [];\n }\n}\n\n// Internal recursive implementation shared by visit()\nfunction visitInternal(\n node: AstNode,\n callback: (node: AstNode, parent?: AstNode, path?: NodePath) => void,\n parent: AstNode | undefined,\n path: NodePath,\n depth: number,\n trackPath: boolean,\n): void {\n if (depth > MAX_DEPTH) {\n throw new TraversalDepthError(depth);\n }\n callback(node, parent, trackPath ? path : undefined);\n const children = getChildren(node);\n for (let i = 0; i < children.length; i++) {\n const nextPath = trackPath ? [...path, i] : path;\n visitInternal(children[i], callback, node, nextPath, depth + 1, trackPath);\n }\n}\n\nexport interface VisitOptions {\n /**\n * Whether to compute and pass a NodePath to each callback invocation.\n * Defaults to true for backward compatibility.\n * Set to false for performance-critical traversals that don't need path info.\n */\n trackPath?: boolean;\n}\n\nexport function visit(\n node: AstNode,\n callback: (node: AstNode, parent?: AstNode, path?: NodePath) => void,\n options?: VisitOptions,\n): void {\n visitInternal(node, callback, undefined, [], 0, options?.trackPath ?? true);\n}\n\nexport function map(node: AstNode, fn: (node: AstNode) => AstNode, _depth: number = 0): AstNode {\n if (_depth > MAX_DEPTH) {\n throw new TraversalDepthError(_depth);\n }\n const mapped = fn(node);\n const children = getChildren(mapped);\n if (children.length === 0) return mapped;\n\n const newChildren = children.map((child) => map(child, fn, _depth + 1));\n const changed = newChildren.some((c, i) => c !== children[i]);\n if (!changed) return mapped;\n\n switch (mapped.type) {\n case 'doc':\n return { ...mapped, content: newChildren as BlockNode[] };\n case 'blockquote':\n case 'listItem':\n return { ...mapped, content: newChildren as BlockNode[] };\n case 'paragraph':\n case 'heading':\n return { ...mapped, content: newChildren as InlineNode[] };\n case 'bulletList':\n return { ...mapped, content: newChildren as typeof mapped.content };\n case 'orderedList':\n return { ...mapped, content: newChildren as typeof mapped.content };\n case 'jinjaIfBlock': {\n const jNode = mapped as JinjaIfBlockNode;\n let offset = 0;\n const newBranches = jNode.branches.map(b => {\n const slice = newChildren.slice(offset, offset + b.content.length) as BlockNode[];\n offset += b.content.length;\n return { ...b, content: slice };\n });\n return { ...jNode, branches: newBranches };\n }\n case 'jinjaIfInline': {\n const jNode = mapped as JinjaIfInlineNode;\n let offset = 0;\n const newBranches = jNode.branches.map(b => {\n const slice = newChildren.slice(offset, offset + b.content.length) as InlineNode[];\n offset += b.content.length;\n return { ...b, content: slice };\n });\n return { ...jNode, branches: newBranches };\n }\n default:\n return mapped;\n }\n}\n\nexport function textContent(node: AstNode, _depth: number = 0): string {\n if (_depth > MAX_DEPTH) {\n throw new TraversalDepthError(_depth);\n }\n switch (node.type) {\n case 'text':\n return node.text;\n case 'resourceTag':\n return node.text;\n case 'jumpPoint':\n return `^${node.id}^`;\n case 'hardBreak':\n return '\\n';\n case 'jinjaIfInline': {\n // Reconstruct original {% %} text for analyzer compatibility\n let out = '';\n for (const branch of node.branches) {\n if (branch.branchType === 'if') out += `{% if ${branch.condition} %}`;\n else if (branch.branchType === 'elif') out += `{% elif ${branch.condition} %}`;\n else out += '{% else %}';\n for (const child of branch.content) out += textContent(child, _depth + 1);\n }\n out += '{% endif %}';\n return out;\n }\n case 'horizontalRule':\n return '';\n default: {\n const children = getChildren(node);\n let out = '';\n for (const child of children) out += textContent(child, _depth + 1);\n return out;\n }\n }\n}\n\nexport function findAll(node: AstNode, predicate: (n: AstNode) => boolean): AstNode[] {\n const results: AstNode[] = [];\n visit(node, (n) => {\n if (predicate(n)) results.push(n);\n }, { trackPath: false });\n return results;\n}\n\nexport function nodeAtPath(root: DocumentNode, path: NodePath): AstNode | undefined {\n if (path.length > MAX_DEPTH) {\n throw new TraversalDepthError(path.length);\n }\n let current: AstNode = root;\n for (const index of path) {\n const children = getChildren(current);\n if (index < 0 || index >= children.length) return undefined;\n current = children[index];\n }\n return current;\n}\n","import { fromMarkdown } from 'mdast-util-from-markdown';\nimport { combineExtensions } from 'micromark-util-combine-extensions';\nimport { gfmFootnote } from 'micromark-extension-gfm-footnote';\nimport { gfmStrikethrough } from 'micromark-extension-gfm-strikethrough';\nimport { gfmTable } from 'micromark-extension-gfm-table';\nimport { gfmTaskListItem } from 'micromark-extension-gfm-task-list-item';\nimport { gfmFootnoteFromMarkdown } from 'mdast-util-gfm-footnote';\nimport { gfmStrikethroughFromMarkdown } from 'mdast-util-gfm-strikethrough';\nimport { gfmTableFromMarkdown } from 'mdast-util-gfm-table';\nimport { gfmTaskListItemFromMarkdown } from 'mdast-util-gfm-task-list-item';\nimport { splitTextWithResourceTags } from './plugins/resourceTag';\nimport { splitTextWithJumpPoints } from './plugins/jumpPoint';\nimport type { ResourceTagMdastNode } from './plugins/resourceTag';\nimport type { JumpPointMdastNode } from './plugins/jumpPoint';\nimport { fromMdast } from './mdastAdapter';\nimport { jinjaBlockTransform } from './plugins/jinjaBlock';\nimport type { DocumentNode } from '../ast/types';\nimport type { Root, Text } from 'mdast';\n\nexport interface ParseMarkdownOptions {\n jinjaNodes?: boolean;\n}\n\n// GFM without autolink literal — autolink literal converts escaped emails/URLs\n// (e.g. bookings\\@flynorse.com) into link nodes during the mdast transform pass,\n// which then serialize as <bookings@flynorse.com> instead of preserving the\n// original backslash escaping.\nconst gfmNoAutolink = () =>\n combineExtensions([gfmFootnote(), gfmStrikethrough(), gfmTable(), gfmTaskListItem()]);\n\nconst gfmNoAutolinkFromMarkdown = () => [\n gfmFootnoteFromMarkdown(),\n gfmStrikethroughFromMarkdown(),\n gfmTableFromMarkdown(),\n gfmTaskListItemFromMarkdown(),\n];\n\nconst MAX_DEPTH = 128;\n\ntype CustomNode = ResourceTagMdastNode | JumpPointMdastNode;\n\n/**\n * Combined single-pass transform for resource tags and jump points.\n * Each text node is scanned for both patterns in one iteration,\n * avoiding two separate full-tree traversals.\n */\nfunction combinedTokensFromMarkdown(node: { children?: unknown[] }, depth: number = 0): void {\n if (depth > MAX_DEPTH) return;\n if (!node.children) return;\n for (const child of node.children) {\n combinedTokensFromMarkdown(child as { children?: unknown[] }, depth + 1);\n }\n if (Array.isArray(node.children)) {\n const newChildren: unknown[] = [];\n for (const child of node.children) {\n const c = child as { type: string };\n if (c.type === 'text') {\n // First split by resource tags, then split each resulting text segment by jump points\n const afterResourceTags = splitTextWithResourceTags((child as Text).value);\n for (const part of afterResourceTags) {\n if (part.type === 'text') {\n const afterJumpPoints = splitTextWithJumpPoints(part.value);\n newChildren.push(...afterJumpPoints);\n } else {\n newChildren.push(part as unknown as CustomNode);\n }\n }\n } else {\n newChildren.push(child);\n }\n }\n node.children = newChildren;\n }\n}\n\nexport function parseMarkdown(markdown: string, options?: ParseMarkdownOptions): DocumentNode {\n const tree = fromMarkdown(markdown, {\n extensions: [gfmNoAutolink()],\n mdastExtensions: [gfmNoAutolinkFromMarkdown()],\n });\n\n // Single combined pass for resource tags and jump points\n combinedTokensFromMarkdown(tree as unknown as { children?: unknown[] });\n\n // Optional: transform Jinja tags into structured mdast nodes\n if (options?.jinjaNodes) {\n jinjaBlockTransform(tree as unknown as { type: string; children?: unknown[] });\n }\n\n return fromMdast(tree);\n}\n","/**\n * Like `Array#splice`, but smarter for giant arrays.\n *\n * `Array#splice` takes all items to be inserted as individual argument which\n * causes a stack overflow in V8 when trying to insert 100k items for instance.\n *\n * Otherwise, this does not return the removed items, and takes `items` as an\n * array instead of rest parameters.\n *\n * @template {unknown} T\n * Item type.\n * @param {Array<T>} list\n * List to operate on.\n * @param {number} start\n * Index to remove/insert at (can be negative).\n * @param {number} remove\n * Number of items to remove.\n * @param {Array<T>} items\n * Items to inject into `list`.\n * @returns {undefined}\n * Nothing.\n */\nexport function splice(list, start, remove, items) {\n const end = list.length;\n let chunkStart = 0;\n /** @type {Array<unknown>} */\n let parameters;\n\n // Make start between zero and `end` (included).\n if (start < 0) {\n start = -start > end ? 0 : end + start;\n } else {\n start = start > end ? end : start;\n }\n remove = remove > 0 ? remove : 0;\n\n // No need to chunk the items if there’s only a couple (10k) items.\n if (items.length < 10000) {\n parameters = Array.from(items);\n parameters.unshift(start, remove);\n // @ts-expect-error Hush, it’s fine.\n list.splice(...parameters);\n } else {\n // Delete `remove` items starting from `start`\n if (remove) list.splice(start, remove);\n\n // Insert the items in chunks to not cause stack overflows.\n while (chunkStart < items.length) {\n parameters = items.slice(chunkStart, chunkStart + 10000);\n parameters.unshift(start, 0);\n // @ts-expect-error Hush, it’s fine.\n list.splice(...parameters);\n chunkStart += 10000;\n start += 10000;\n }\n }\n}\n\n/**\n * Append `items` (an array) at the end of `list` (another array).\n * When `list` was empty, returns `items` instead.\n *\n * This prevents a potentially expensive operation when `list` is empty,\n * and adds items in batches to prevent V8 from hanging.\n *\n * @template {unknown} T\n * Item type.\n * @param {Array<T>} list\n * List to operate on.\n * @param {Array<T>} items\n * Items to add to `list`.\n * @returns {Array<T>}\n * Either `list` or `items`.\n */\nexport function push(list, items) {\n if (list.length > 0) {\n splice(list, list.length, 0, items);\n return list;\n }\n return items;\n}","/**\n * @import {\n * Extension,\n * Handles,\n * HtmlExtension,\n * NormalizedExtension\n * } from 'micromark-util-types'\n */\n\nimport {splice} from 'micromark-util-chunked'\n\nconst hasOwnProperty = {}.hasOwnProperty\n\n/**\n * Combine multiple syntax extensions into one.\n *\n * @param {ReadonlyArray<Extension>} extensions\n * List of syntax extensions.\n * @returns {NormalizedExtension}\n * A single combined extension.\n */\nexport function combineExtensions(extensions) {\n /** @type {NormalizedExtension} */\n const all = {}\n let index = -1\n\n while (++index < extensions.length) {\n syntaxExtension(all, extensions[index])\n }\n\n return all\n}\n\n/**\n * Merge `extension` into `all`.\n *\n * @param {NormalizedExtension} all\n * Extension to merge into.\n * @param {Extension} extension\n * Extension to merge.\n * @returns {undefined}\n * Nothing.\n */\nfunction syntaxExtension(all, extension) {\n /** @type {keyof Extension} */\n let hook\n\n for (hook in extension) {\n const maybe = hasOwnProperty.call(all, hook) ? all[hook] : undefined\n /** @type {Record<string, unknown>} */\n const left = maybe || (all[hook] = {})\n /** @type {Record<string, unknown> | undefined} */\n const right = extension[hook]\n /** @type {string} */\n let code\n\n if (right) {\n for (code in right) {\n if (!hasOwnProperty.call(left, code)) left[code] = []\n const value = right[code]\n constructs(\n // @ts-expect-error Looks like a list.\n left[code],\n Array.isArray(value) ? value : value ? [value] : []\n )\n }\n }\n }\n}\n\n/**\n * Merge `list` into `existing` (both lists of constructs).\n * Mutates `existing`.\n *\n * @param {Array<unknown>} existing\n * List of constructs to merge into.\n * @param {Array<unknown>} list\n * List of constructs to merge.\n * @returns {undefined}\n * Nothing.\n */\nfunction constructs(existing, list) {\n let index = -1\n /** @type {Array<unknown>} */\n const before = []\n\n while (++index < list.length) {\n // @ts-expect-error Looks like an object.\n ;(list[index].add === 'after' ? existing : before).push(list[index])\n }\n\n splice(existing, 0, 0, before)\n}\n\n/**\n * Combine multiple HTML extensions into one.\n *\n * @param {ReadonlyArray<HtmlExtension>} htmlExtensions\n * List of HTML extensions.\n * @returns {HtmlExtension}\n * Single combined HTML extension.\n */\nexport function combineHtmlExtensions(htmlExtensions) {\n /** @type {HtmlExtension} */\n const handlers = {}\n let index = -1\n\n while (++index < htmlExtensions.length) {\n htmlExtension(handlers, htmlExtensions[index])\n }\n\n return handlers\n}\n\n/**\n * Merge `extension` into `all`.\n *\n * @param {HtmlExtension} all\n * Extension to merge into.\n * @param {HtmlExtension} extension\n * Extension to merge.\n * @returns {undefined}\n * Nothing.\n */\nfunction htmlExtension(all, extension) {\n /** @type {keyof HtmlExtension} */\n let hook\n\n for (hook in extension) {\n const maybe = hasOwnProperty.call(all, hook) ? all[hook] : undefined\n const left = maybe || (all[hook] = {})\n const right = extension[hook]\n /** @type {keyof Handles} */\n let type\n\n if (right) {\n for (type in right) {\n // @ts-expect-error assume document vs regular handler are managed correctly.\n left[type] = right[type]\n }\n }\n }\n}\n","/**\n * @import {Code} from 'micromark-util-types'\n */\n\nimport { markdownLineEndingOrSpace, unicodePunctuation, unicodeWhitespace } from 'micromark-util-character';\n/**\n * Classify whether a code represents whitespace, punctuation, or something\n * else.\n *\n * Used for attention (emphasis, strong), whose sequences can open or close\n * based on the class of surrounding characters.\n *\n * > 👉 **Note**: eof (`null`) is seen as whitespace.\n *\n * @param {Code} code\n * Code.\n * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined}\n * Group.\n */\nexport function classifyCharacter(code) {\n if (code === null || markdownLineEndingOrSpace(code) || unicodeWhitespace(code)) {\n return 1;\n }\n if (unicodePunctuation(code)) {\n return 2;\n }\n}","/**\n * @import {Event, Resolver, TokenizeContext} from 'micromark-util-types'\n */\n\n/**\n * Call all `resolveAll`s.\n *\n * @param {ReadonlyArray<{resolveAll?: Resolver | undefined}>} constructs\n * List of constructs, optionally with `resolveAll`s.\n * @param {Array<Event>} events\n * List of events.\n * @param {TokenizeContext} context\n * Context used by `tokenize`.\n * @returns {Array<Event>}\n * Changed events.\n */\nexport function resolveAll(constructs, events, context) {\n /** @type {Array<Resolver>} */\n const called = []\n let index = -1\n\n while (++index < constructs.length) {\n const resolve = constructs[index].resolveAll\n\n if (resolve && !called.includes(resolve)) {\n events = resolve(events, context)\n called.push(resolve)\n }\n }\n\n return events\n}\n","/**\n * @import {Effects, State, TokenType} from 'micromark-util-types'\n */\n\nimport { markdownSpace } from 'micromark-util-character';\n\n// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`.\n\n/**\n * Parse spaces and tabs.\n *\n * There is no `nok` parameter:\n *\n * * spaces in markdown are often optional, in which case this factory can be\n * used and `ok` will be switched to whether spaces were found or not\n * * one line ending or space can be detected with `markdownSpace(code)` right\n * before using `factorySpace`\n *\n * ###### Examples\n *\n * Where `␉` represents a tab (plus how much it expands) and `␠` represents a\n * single space.\n *\n * ```markdown\n * ␉\n * ␠␠␠␠\n * ␉␠\n * ```\n *\n * @param {Effects} effects\n * Context.\n * @param {State} ok\n * State switched to when successful.\n * @param {TokenType} type\n * Type (`' \\t'`).\n * @param {number | undefined} [max=Infinity]\n * Max (exclusive).\n * @returns {State}\n * Start state.\n */\nexport function factorySpace(effects, ok, type, max) {\n const limit = max ? max - 1 : Number.POSITIVE_INFINITY;\n let size = 0;\n return start;\n\n /** @type {State} */\n function start(code) {\n if (markdownSpace(code)) {\n effects.enter(type);\n return prefix(code);\n }\n return ok(code);\n }\n\n /** @type {State} */\n function prefix(code) {\n if (markdownSpace(code) && size++ < limit) {\n effects.consume(code);\n return prefix;\n }\n effects.exit(type);\n return ok(code);\n }\n}","/**\n * @import {\n * Construct,\n * State,\n * TokenizeContext,\n * Tokenizer\n * } from 'micromark-util-types'\n */\n\nimport { factorySpace } from 'micromark-factory-space';\nimport { markdownLineEnding, markdownSpace } from 'micromark-util-character';\n/** @type {Construct} */\nexport const blankLine = {\n partial: true,\n tokenize: tokenizeBlankLine\n};\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeBlankLine(effects, ok, nok) {\n return start;\n\n /**\n * Start of blank line.\n *\n * > 👉 **Note**: `␠` represents a space character.\n *\n * ```markdown\n * > | ␠␠␊\n * ^\n * > | ␊\n * ^\n * ```\n *\n * @type {State}\n */\n function start(code) {\n return markdownSpace(code) ? factorySpace(effects, after, \"linePrefix\")(code) : after(code);\n }\n\n /**\n * At eof/eol, after optional whitespace.\n *\n * > 👉 **Note**: `␠` represents a space character.\n *\n * ```markdown\n * > | ␠␠␊\n * ^\n * > | ␊\n * ^\n * ```\n *\n * @type {State}\n */\n function after(code) {\n return code === null || markdownLineEnding(code) ? ok(code) : nok(code);\n }\n}","/**\n * @import {Event, Exiter, Extension, Resolver, State, Token, TokenizeContext, Tokenizer} from 'micromark-util-types'\n */\n\nimport { blankLine } from 'micromark-core-commonmark';\nimport { factorySpace } from 'micromark-factory-space';\nimport { markdownLineEndingOrSpace } from 'micromark-util-character';\nimport { normalizeIdentifier } from 'micromark-util-normalize-identifier';\nconst indent = {\n tokenize: tokenizeIndent,\n partial: true\n};\n\n// To do: micromark should support a `_hiddenGfmFootnoteSupport`, which only\n// affects label start (image).\n// That will let us drop `tokenizePotentialGfmFootnote*`.\n// It currently has a `_hiddenFootnoteSupport`, which affects that and more.\n// That can be removed when `micromark-extension-footnote` is archived.\n\n/**\n * Create an extension for `micromark` to enable GFM footnote syntax.\n *\n * @returns {Extension}\n * Extension for `micromark` that can be passed in `extensions` to\n * enable GFM footnote syntax.\n */\nexport function gfmFootnote() {\n /** @type {Extension} */\n return {\n document: {\n [91]: {\n name: 'gfmFootnoteDefinition',\n tokenize: tokenizeDefinitionStart,\n continuation: {\n tokenize: tokenizeDefinitionContinuation\n },\n exit: gfmFootnoteDefinitionEnd\n }\n },\n text: {\n [91]: {\n name: 'gfmFootnoteCall',\n tokenize: tokenizeGfmFootnoteCall\n },\n [93]: {\n name: 'gfmPotentialFootnoteCall',\n add: 'after',\n tokenize: tokenizePotentialGfmFootnoteCall,\n resolveTo: resolveToPotentialGfmFootnoteCall\n }\n }\n };\n}\n\n// To do: remove after micromark update.\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizePotentialGfmFootnoteCall(effects, ok, nok) {\n const self = this;\n let index = self.events.length;\n const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []);\n /** @type {Token} */\n let labelStart;\n\n // Find an opening.\n while (index--) {\n const token = self.events[index][1];\n if (token.type === \"labelImage\") {\n labelStart = token;\n break;\n }\n\n // Exit if we’ve walked far enough.\n if (token.type === 'gfmFootnoteCall' || token.type === \"labelLink\" || token.type === \"label\" || token.type === \"image\" || token.type === \"link\") {\n break;\n }\n }\n return start;\n\n /**\n * @type {State}\n */\n function start(code) {\n if (!labelStart || !labelStart._balanced) {\n return nok(code);\n }\n const id = normalizeIdentifier(self.sliceSerialize({\n start: labelStart.end,\n end: self.now()\n }));\n if (id.codePointAt(0) !== 94 || !defined.includes(id.slice(1))) {\n return nok(code);\n }\n effects.enter('gfmFootnoteCallLabelMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteCallLabelMarker');\n return ok(code);\n }\n}\n\n// To do: remove after micromark update.\n/** @type {Resolver} */\nfunction resolveToPotentialGfmFootnoteCall(events, context) {\n let index = events.length;\n /** @type {Token | undefined} */\n let labelStart;\n\n // Find an opening.\n while (index--) {\n if (events[index][1].type === \"labelImage\" && events[index][0] === 'enter') {\n labelStart = events[index][1];\n break;\n }\n }\n // Change the `labelImageMarker` to a `data`.\n events[index + 1][1].type = \"data\";\n events[index + 3][1].type = 'gfmFootnoteCallLabelMarker';\n\n // The whole (without `!`):\n /** @type {Token} */\n const call = {\n type: 'gfmFootnoteCall',\n start: Object.assign({}, events[index + 3][1].start),\n end: Object.assign({}, events[events.length - 1][1].end)\n };\n // The `^` marker\n /** @type {Token} */\n const marker = {\n type: 'gfmFootnoteCallMarker',\n start: Object.assign({}, events[index + 3][1].end),\n end: Object.assign({}, events[index + 3][1].end)\n };\n // Increment the end 1 character.\n marker.end.column++;\n marker.end.offset++;\n marker.end._bufferIndex++;\n /** @type {Token} */\n const string = {\n type: 'gfmFootnoteCallString',\n start: Object.assign({}, marker.end),\n end: Object.assign({}, events[events.length - 1][1].start)\n };\n /** @type {Token} */\n const chunk = {\n type: \"chunkString\",\n contentType: 'string',\n start: Object.assign({}, string.start),\n end: Object.assign({}, string.end)\n };\n\n /** @type {Array<Event>} */\n const replacement = [\n // Take the `labelImageMarker` (now `data`, the `!`)\n events[index + 1], events[index + 2], ['enter', call, context],\n // The `[`\n events[index + 3], events[index + 4],\n // The `^`.\n ['enter', marker, context], ['exit', marker, context],\n // Everything in between.\n ['enter', string, context], ['enter', chunk, context], ['exit', chunk, context], ['exit', string, context],\n // The ending (`]`, properly parsed and labelled).\n events[events.length - 2], events[events.length - 1], ['exit', call, context]];\n events.splice(index, events.length - index + 1, ...replacement);\n return events;\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeGfmFootnoteCall(effects, ok, nok) {\n const self = this;\n const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []);\n let size = 0;\n /** @type {boolean} */\n let data;\n\n // Note: the implementation of `markdown-rs` is different, because it houses\n // core *and* extensions in one project.\n // Therefore, it can include footnote logic inside `label-end`.\n // We can’t do that, but luckily, we can parse footnotes in a simpler way than\n // needed for labels.\n return start;\n\n /**\n * Start of footnote label.\n *\n * ```markdown\n * > | a [^b] c\n * ^\n * ```\n *\n * @type {State}\n */\n function start(code) {\n effects.enter('gfmFootnoteCall');\n effects.enter('gfmFootnoteCallLabelMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteCallLabelMarker');\n return callStart;\n }\n\n /**\n * After `[`, at `^`.\n *\n * ```markdown\n * > | a [^b] c\n * ^\n * ```\n *\n * @type {State}\n */\n function callStart(code) {\n if (code !== 94) return nok(code);\n effects.enter('gfmFootnoteCallMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteCallMarker');\n effects.enter('gfmFootnoteCallString');\n effects.enter('chunkString').contentType = 'string';\n return callData;\n }\n\n /**\n * In label.\n *\n * ```markdown\n * > | a [^b] c\n * ^\n * ```\n *\n * @type {State}\n */\n function callData(code) {\n if (\n // Too long.\n size > 999 ||\n // Closing brace with nothing.\n code === 93 && !data ||\n // Space or tab is not supported by GFM for some reason.\n // `\\n` and `[` not being supported makes sense.\n code === null || code === 91 || markdownLineEndingOrSpace(code)) {\n return nok(code);\n }\n if (code === 93) {\n effects.exit('chunkString');\n const token = effects.exit('gfmFootnoteCallString');\n if (!defined.includes(normalizeIdentifier(self.sliceSerialize(token)))) {\n return nok(code);\n }\n effects.enter('gfmFootnoteCallLabelMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteCallLabelMarker');\n effects.exit('gfmFootnoteCall');\n return ok;\n }\n if (!markdownLineEndingOrSpace(code)) {\n data = true;\n }\n size++;\n effects.consume(code);\n return code === 92 ? callEscape : callData;\n }\n\n /**\n * On character after escape.\n *\n * ```markdown\n * > | a [^b\\c] d\n * ^\n * ```\n *\n * @type {State}\n */\n function callEscape(code) {\n if (code === 91 || code === 92 || code === 93) {\n effects.consume(code);\n size++;\n return callData;\n }\n return callData(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeDefinitionStart(effects, ok, nok) {\n const self = this;\n const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []);\n /** @type {string} */\n let identifier;\n let size = 0;\n /** @type {boolean | undefined} */\n let data;\n return start;\n\n /**\n * Start of GFM footnote definition.\n *\n * ```markdown\n * > | [^a]: b\n * ^\n * ```\n *\n * @type {State}\n */\n function start(code) {\n effects.enter('gfmFootnoteDefinition')._container = true;\n effects.enter('gfmFootnoteDefinitionLabel');\n effects.enter('gfmFootnoteDefinitionLabelMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteDefinitionLabelMarker');\n return labelAtMarker;\n }\n\n /**\n * In label, at caret.\n *\n * ```markdown\n * > | [^a]: b\n * ^\n * ```\n *\n * @type {State}\n */\n function labelAtMarker(code) {\n if (code === 94) {\n effects.enter('gfmFootnoteDefinitionMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteDefinitionMarker');\n effects.enter('gfmFootnoteDefinitionLabelString');\n effects.enter('chunkString').contentType = 'string';\n return labelInside;\n }\n return nok(code);\n }\n\n /**\n * In label.\n *\n * > 👉 **Note**: `cmark-gfm` prevents whitespace from occurring in footnote\n * > definition labels.\n *\n * ```markdown\n * > | [^a]: b\n * ^\n * ```\n *\n * @type {State}\n */\n function labelInside(code) {\n if (\n // Too long.\n size > 999 ||\n // Closing brace with nothing.\n code === 93 && !data ||\n // Space or tab is not supported by GFM for some reason.\n // `\\n` and `[` not being supported makes sense.\n code === null || code === 91 || markdownLineEndingOrSpace(code)) {\n return nok(code);\n }\n if (code === 93) {\n effects.exit('chunkString');\n const token = effects.exit('gfmFootnoteDefinitionLabelString');\n identifier = normalizeIdentifier(self.sliceSerialize(token));\n effects.enter('gfmFootnoteDefinitionLabelMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteDefinitionLabelMarker');\n effects.exit('gfmFootnoteDefinitionLabel');\n return labelAfter;\n }\n if (!markdownLineEndingOrSpace(code)) {\n data = true;\n }\n size++;\n effects.consume(code);\n return code === 92 ? labelEscape : labelInside;\n }\n\n /**\n * After `\\`, at a special character.\n *\n * > 👉 **Note**: `cmark-gfm` currently does not support escaped brackets:\n * > <https://github.com/github/cmark-gfm/issues/240>\n *\n * ```markdown\n * > | [^a\\*b]: c\n * ^\n * ```\n *\n * @type {State}\n */\n function labelEscape(code) {\n if (code === 91 || code === 92 || code === 93) {\n effects.consume(code);\n size++;\n return labelInside;\n }\n return labelInside(code);\n }\n\n /**\n * After definition label.\n *\n * ```markdown\n * > | [^a]: b\n * ^\n * ```\n *\n * @type {State}\n */\n function labelAfter(code) {\n if (code === 58) {\n effects.enter('definitionMarker');\n effects.consume(code);\n effects.exit('definitionMarker');\n if (!defined.includes(identifier)) {\n defined.push(identifier);\n }\n\n // Any whitespace after the marker is eaten, forming indented code\n // is not possible.\n // No space is also fine, just like a block quote marker.\n return factorySpace(effects, whitespaceAfter, 'gfmFootnoteDefinitionWhitespace');\n }\n return nok(code);\n }\n\n /**\n * After definition prefix.\n *\n * ```markdown\n * > | [^a]: b\n * ^\n * ```\n *\n * @type {State}\n */\n function whitespaceAfter(code) {\n // `markdown-rs` has a wrapping token for the prefix that is closed here.\n return ok(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeDefinitionContinuation(effects, ok, nok) {\n /// Start of footnote definition continuation.\n ///\n /// ```markdown\n /// | [^a]: b\n /// > | c\n /// ^\n /// ```\n //\n // Either a blank line, which is okay, or an indented thing.\n return effects.check(blankLine, ok, effects.attempt(indent, ok, nok));\n}\n\n/** @type {Exiter} */\nfunction gfmFootnoteDefinitionEnd(effects) {\n effects.exit('gfmFootnoteDefinition');\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeIndent(effects, ok, nok) {\n const self = this;\n return factorySpace(effects, afterPrefix, 'gfmFootnoteDefinitionIndent', 4 + 1);\n\n /**\n * @type {State}\n */\n function afterPrefix(code) {\n const tail = self.events[self.events.length - 1];\n return tail && tail[1].type === 'gfmFootnoteDefinitionIndent' && tail[2].sliceSerialize(tail[1], true).length === 4 ? ok(code) : nok(code);\n }\n}","/**\n * @import {Options} from 'micromark-extension-gfm-strikethrough'\n * @import {Event, Extension, Resolver, State, Token, TokenizeContext, Tokenizer} from 'micromark-util-types'\n */\n\nimport { splice } from 'micromark-util-chunked';\nimport { classifyCharacter } from 'micromark-util-classify-character';\nimport { resolveAll } from 'micromark-util-resolve-all';\n/**\n * Create an extension for `micromark` to enable GFM strikethrough syntax.\n *\n * @param {Options | null | undefined} [options={}]\n * Configuration.\n * @returns {Extension}\n * Extension for `micromark` that can be passed in `extensions`, to\n * enable GFM strikethrough syntax.\n */\nexport function gfmStrikethrough(options) {\n const options_ = options || {};\n let single = options_.singleTilde;\n const tokenizer = {\n name: 'strikethrough',\n tokenize: tokenizeStrikethrough,\n resolveAll: resolveAllStrikethrough\n };\n if (single === null || single === undefined) {\n single = true;\n }\n return {\n text: {\n [126]: tokenizer\n },\n insideSpan: {\n null: [tokenizer]\n },\n attentionMarkers: {\n null: [126]\n }\n };\n\n /**\n * Take events and resolve strikethrough.\n *\n * @type {Resolver}\n */\n function resolveAllStrikethrough(events, context) {\n let index = -1;\n\n // Walk through all events.\n while (++index < events.length) {\n // Find a token that can close.\n if (events[index][0] === 'enter' && events[index][1].type === 'strikethroughSequenceTemporary' && events[index][1]._close) {\n let open = index;\n\n // Now walk back to find an opener.\n while (open--) {\n // Find a token that can open the closer.\n if (events[open][0] === 'exit' && events[open][1].type === 'strikethroughSequenceTemporary' && events[open][1]._open &&\n // If the sizes are the same:\n events[index][1].end.offset - events[index][1].start.offset === events[open][1].end.offset - events[open][1].start.offset) {\n events[index][1].type = 'strikethroughSequence';\n events[open][1].type = 'strikethroughSequence';\n\n /** @type {Token} */\n const strikethrough = {\n type: 'strikethrough',\n start: Object.assign({}, events[open][1].start),\n end: Object.assign({}, events[index][1].end)\n };\n\n /** @type {Token} */\n const text = {\n type: 'strikethroughText',\n start: Object.assign({}, events[open][1].end),\n end: Object.assign({}, events[index][1].start)\n };\n\n // Opening.\n /** @type {Array<Event>} */\n const nextEvents = [['enter', strikethrough, context], ['enter', events[open][1], context], ['exit', events[open][1], context], ['enter', text, context]];\n const insideSpan = context.parser.constructs.insideSpan.null;\n if (insideSpan) {\n // Between.\n splice(nextEvents, nextEvents.length, 0, resolveAll(insideSpan, events.slice(open + 1, index), context));\n }\n\n // Closing.\n splice(nextEvents, nextEvents.length, 0, [['exit', text, context], ['enter', events[index][1], context], ['exit', events[index][1], context], ['exit', strikethrough, context]]);\n splice(events, open - 1, index - open + 3, nextEvents);\n index = open + nextEvents.length - 2;\n break;\n }\n }\n }\n }\n index = -1;\n while (++index < events.length) {\n if (events[index][1].type === 'strikethroughSequenceTemporary') {\n events[index][1].type = \"data\";\n }\n }\n return events;\n }\n\n /**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\n function tokenizeStrikethrough(effects, ok, nok) {\n const previous = this.previous;\n const events = this.events;\n let size = 0;\n return start;\n\n /** @type {State} */\n function start(code) {\n if (previous === 126 && events[events.length - 1][1].type !== \"characterEscape\") {\n return nok(code);\n }\n effects.enter('strikethroughSequenceTemporary');\n return more(code);\n }\n\n /** @type {State} */\n function more(code) {\n const before = classifyCharacter(previous);\n if (code === 126) {\n // If this is the third marker, exit.\n if (size > 1) return nok(code);\n effects.consume(code);\n size++;\n return more;\n }\n if (size < 2 && !single) return nok(code);\n const token = effects.exit('strikethroughSequenceTemporary');\n const after = classifyCharacter(code);\n token._open = !after || after === 2 && Boolean(before);\n token._close = !before || before === 2 && Boolean(after);\n return ok(code);\n }\n }\n}","/**\n * @import {Event, Extension, Point, Resolver, State, Token, TokenizeContext, Tokenizer} from 'micromark-util-types'\n */\n\n/**\n * @typedef {[number, number, number, number]} Range\n * Cell info.\n *\n * @typedef {0 | 1 | 2 | 3} RowKind\n * Where we are: `1` for head row, `2` for delimiter row, `3` for body row.\n */\n\nimport { factorySpace } from 'micromark-factory-space';\nimport { markdownLineEnding, markdownLineEndingOrSpace, markdownSpace } from 'micromark-util-character';\nimport { EditMap } from './edit-map.js';\nimport { gfmTableAlign } from './infer.js';\n\n/**\n * Create an HTML extension for `micromark` to support GitHub tables syntax.\n *\n * @returns {Extension}\n * Extension for `micromark` that can be passed in `extensions` to enable GFM\n * table syntax.\n */\nexport function gfmTable() {\n return {\n flow: {\n null: {\n name: 'table',\n tokenize: tokenizeTable,\n resolveAll: resolveTable\n }\n }\n };\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeTable(effects, ok, nok) {\n const self = this;\n let size = 0;\n let sizeB = 0;\n /** @type {boolean | undefined} */\n let seen;\n return start;\n\n /**\n * Start of a GFM table.\n *\n * If there is a valid table row or table head before, then we try to parse\n * another row.\n * Otherwise, we try to parse a head.\n *\n * ```markdown\n * > | | a |\n * ^\n * | | - |\n * > | | b |\n * ^\n * ```\n * @type {State}\n */\n function start(code) {\n let index = self.events.length - 1;\n while (index > -1) {\n const type = self.events[index][1].type;\n if (type === \"lineEnding\" ||\n // Note: markdown-rs uses `whitespace` instead of `linePrefix`\n type === \"linePrefix\") index--;else break;\n }\n const tail = index > -1 ? self.events[index][1].type : null;\n const next = tail === 'tableHead' || tail === 'tableRow' ? bodyRowStart : headRowBefore;\n\n // Don’t allow lazy body rows.\n if (next === bodyRowStart && self.parser.lazy[self.now().line]) {\n return nok(code);\n }\n return next(code);\n }\n\n /**\n * Before table head row.\n *\n * ```markdown\n * > | | a |\n * ^\n * | | - |\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headRowBefore(code) {\n effects.enter('tableHead');\n effects.enter('tableRow');\n return headRowStart(code);\n }\n\n /**\n * Before table head row, after whitespace.\n *\n * ```markdown\n * > | | a |\n * ^\n * | | - |\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headRowStart(code) {\n if (code === 124) {\n return headRowBreak(code);\n }\n\n // To do: micromark-js should let us parse our own whitespace in extensions,\n // like `markdown-rs`:\n //\n // ```js\n // // 4+ spaces.\n // if (markdownSpace(code)) {\n // return nok(code)\n // }\n // ```\n\n seen = true;\n // Count the first character, that isn’t a pipe, double.\n sizeB += 1;\n return headRowBreak(code);\n }\n\n /**\n * At break in table head row.\n *\n * ```markdown\n * > | | a |\n * ^\n * ^\n * ^\n * | | - |\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headRowBreak(code) {\n if (code === null) {\n // Note: in `markdown-rs`, we need to reset, in `micromark-js` we don‘t.\n return nok(code);\n }\n if (markdownLineEnding(code)) {\n // If anything other than one pipe (ignoring whitespace) was used, it’s fine.\n if (sizeB > 1) {\n sizeB = 0;\n // To do: check if this works.\n // Feel free to interrupt:\n self.interrupt = true;\n effects.exit('tableRow');\n effects.enter(\"lineEnding\");\n effects.consume(code);\n effects.exit(\"lineEnding\");\n return headDelimiterStart;\n }\n\n // Note: in `markdown-rs`, we need to reset, in `micromark-js` we don‘t.\n return nok(code);\n }\n if (markdownSpace(code)) {\n // To do: check if this is fine.\n // effects.attempt(State::Next(StateName::GfmTableHeadRowBreak), State::Nok)\n // State::Retry(space_or_tab(tokenizer))\n return factorySpace(effects, headRowBreak, \"whitespace\")(code);\n }\n sizeB += 1;\n if (seen) {\n seen = false;\n // Header cell count.\n size += 1;\n }\n if (code === 124) {\n effects.enter('tableCellDivider');\n effects.consume(code);\n effects.exit('tableCellDivider');\n // Whether a delimiter was seen.\n seen = true;\n return headRowBreak;\n }\n\n // Anything else is cell data.\n effects.enter(\"data\");\n return headRowData(code);\n }\n\n /**\n * In table head row data.\n *\n * ```markdown\n * > | | a |\n * ^\n * | | - |\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headRowData(code) {\n if (code === null || code === 124 || markdownLineEndingOrSpace(code)) {\n effects.exit(\"data\");\n return headRowBreak(code);\n }\n effects.consume(code);\n return code === 92 ? headRowEscape : headRowData;\n }\n\n /**\n * In table head row escape.\n *\n * ```markdown\n * > | | a\\-b |\n * ^\n * | | ---- |\n * | | c |\n * ```\n *\n * @type {State}\n */\n function headRowEscape(code) {\n if (code === 92 || code === 124) {\n effects.consume(code);\n return headRowData;\n }\n return headRowData(code);\n }\n\n /**\n * Before delimiter row.\n *\n * ```markdown\n * | | a |\n * > | | - |\n * ^\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headDelimiterStart(code) {\n // Reset `interrupt`.\n self.interrupt = false;\n\n // Note: in `markdown-rs`, we need to handle piercing here too.\n if (self.parser.lazy[self.now().line]) {\n return nok(code);\n }\n effects.enter('tableDelimiterRow');\n // Track if we’ve seen a `:` or `|`.\n seen = false;\n if (markdownSpace(code)) {\n return factorySpace(effects, headDelimiterBefore, \"linePrefix\", self.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4)(code);\n }\n return headDelimiterBefore(code);\n }\n\n /**\n * Before delimiter row, after optional whitespace.\n *\n * Reused when a `|` is found later, to parse another cell.\n *\n * ```markdown\n * | | a |\n * > | | - |\n * ^\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headDelimiterBefore(code) {\n if (code === 45 || code === 58) {\n return headDelimiterValueBefore(code);\n }\n if (code === 124) {\n seen = true;\n // If we start with a pipe, we open a cell marker.\n effects.enter('tableCellDivider');\n effects.consume(code);\n effects.exit('tableCellDivider');\n return headDelimiterCellBefore;\n }\n\n // More whitespace / empty row not allowed at start.\n return headDelimiterNok(code);\n }\n\n /**\n * After `|`, before delimiter cell.\n *\n * ```markdown\n * | | a |\n * > | | - |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterCellBefore(code) {\n if (markdownSpace(code)) {\n return factorySpace(effects, headDelimiterValueBefore, \"whitespace\")(code);\n }\n return headDelimiterValueBefore(code);\n }\n\n /**\n * Before delimiter cell value.\n *\n * ```markdown\n * | | a |\n * > | | - |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterValueBefore(code) {\n // Align: left.\n if (code === 58) {\n sizeB += 1;\n seen = true;\n effects.enter('tableDelimiterMarker');\n effects.consume(code);\n effects.exit('tableDelimiterMarker');\n return headDelimiterLeftAlignmentAfter;\n }\n\n // Align: none.\n if (code === 45) {\n sizeB += 1;\n // To do: seems weird that this *isn’t* left aligned, but that state is used?\n return headDelimiterLeftAlignmentAfter(code);\n }\n if (code === null || markdownLineEnding(code)) {\n return headDelimiterCellAfter(code);\n }\n return headDelimiterNok(code);\n }\n\n /**\n * After delimiter cell left alignment marker.\n *\n * ```markdown\n * | | a |\n * > | | :- |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterLeftAlignmentAfter(code) {\n if (code === 45) {\n effects.enter('tableDelimiterFiller');\n return headDelimiterFiller(code);\n }\n\n // Anything else is not ok after the left-align colon.\n return headDelimiterNok(code);\n }\n\n /**\n * In delimiter cell filler.\n *\n * ```markdown\n * | | a |\n * > | | - |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterFiller(code) {\n if (code === 45) {\n effects.consume(code);\n return headDelimiterFiller;\n }\n\n // Align is `center` if it was `left`, `right` otherwise.\n if (code === 58) {\n seen = true;\n effects.exit('tableDelimiterFiller');\n effects.enter('tableDelimiterMarker');\n effects.consume(code);\n effects.exit('tableDelimiterMarker');\n return headDelimiterRightAlignmentAfter;\n }\n effects.exit('tableDelimiterFiller');\n return headDelimiterRightAlignmentAfter(code);\n }\n\n /**\n * After delimiter cell right alignment marker.\n *\n * ```markdown\n * | | a |\n * > | | -: |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterRightAlignmentAfter(code) {\n if (markdownSpace(code)) {\n return factorySpace(effects, headDelimiterCellAfter, \"whitespace\")(code);\n }\n return headDelimiterCellAfter(code);\n }\n\n /**\n * After delimiter cell.\n *\n * ```markdown\n * | | a |\n * > | | -: |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterCellAfter(code) {\n if (code === 124) {\n return headDelimiterBefore(code);\n }\n if (code === null || markdownLineEnding(code)) {\n // Exit when:\n // * there was no `:` or `|` at all (it’s a thematic break or setext\n // underline instead)\n // * the header cell count is not the delimiter cell count\n if (!seen || size !== sizeB) {\n return headDelimiterNok(code);\n }\n\n // Note: in markdown-rs`, a reset is needed here.\n effects.exit('tableDelimiterRow');\n effects.exit('tableHead');\n // To do: in `markdown-rs`, resolvers need to be registered manually.\n // effects.register_resolver(ResolveName::GfmTable)\n return ok(code);\n }\n return headDelimiterNok(code);\n }\n\n /**\n * In delimiter row, at a disallowed byte.\n *\n * ```markdown\n * | | a |\n * > | | x |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterNok(code) {\n // Note: in `markdown-rs`, we need to reset, in `micromark-js` we don‘t.\n return nok(code);\n }\n\n /**\n * Before table body row.\n *\n * ```markdown\n * | | a |\n * | | - |\n * > | | b |\n * ^\n * ```\n *\n * @type {State}\n */\n function bodyRowStart(code) {\n // Note: in `markdown-rs` we need to manually take care of a prefix,\n // but in `micromark-js` that is done for us, so if we’re here, we’re\n // never at whitespace.\n effects.enter('tableRow');\n return bodyRowBreak(code);\n }\n\n /**\n * At break in table body row.\n *\n * ```markdown\n * | | a |\n * | | - |\n * > | | b |\n * ^\n * ^\n * ^\n * ```\n *\n * @type {State}\n */\n function bodyRowBreak(code) {\n if (code === 124) {\n effects.enter('tableCellDivider');\n effects.consume(code);\n effects.exit('tableCellDivider');\n return bodyRowBreak;\n }\n if (code === null || markdownLineEnding(code)) {\n effects.exit('tableRow');\n return ok(code);\n }\n if (markdownSpace(code)) {\n return factorySpace(effects, bodyRowBreak, \"whitespace\")(code);\n }\n\n // Anything else is cell content.\n effects.enter(\"data\");\n return bodyRowData(code);\n }\n\n /**\n * In table body row data.\n *\n * ```markdown\n * | | a |\n * | | - |\n * > | | b |\n * ^\n * ```\n *\n * @type {State}\n */\n function bodyRowData(code) {\n if (code === null || code === 124 || markdownLineEndingOrSpace(code)) {\n effects.exit(\"data\");\n return bodyRowBreak(code);\n }\n effects.consume(code);\n return code === 92 ? bodyRowEscape : bodyRowData;\n }\n\n /**\n * In table body row escape.\n *\n * ```markdown\n * | | a |\n * | | ---- |\n * > | | b\\-c |\n * ^\n * ```\n *\n * @type {State}\n */\n function bodyRowEscape(code) {\n if (code === 92 || code === 124) {\n effects.consume(code);\n return bodyRowData;\n }\n return bodyRowData(code);\n }\n}\n\n/** @type {Resolver} */\n\nfunction resolveTable(events, context) {\n let index = -1;\n let inFirstCellAwaitingPipe = true;\n /** @type {RowKind} */\n let rowKind = 0;\n /** @type {Range} */\n let lastCell = [0, 0, 0, 0];\n /** @type {Range} */\n let cell = [0, 0, 0, 0];\n let afterHeadAwaitingFirstBodyRow = false;\n let lastTableEnd = 0;\n /** @type {Token | undefined} */\n let currentTable;\n /** @type {Token | undefined} */\n let currentBody;\n /** @type {Token | undefined} */\n let currentCell;\n const map = new EditMap();\n while (++index < events.length) {\n const event = events[index];\n const token = event[1];\n if (event[0] === 'enter') {\n // Start of head.\n if (token.type === 'tableHead') {\n afterHeadAwaitingFirstBodyRow = false;\n\n // Inject previous (body end and) table end.\n if (lastTableEnd !== 0) {\n flushTableEnd(map, context, lastTableEnd, currentTable, currentBody);\n currentBody = undefined;\n lastTableEnd = 0;\n }\n\n // Inject table start.\n currentTable = {\n type: 'table',\n start: Object.assign({}, token.start),\n // Note: correct end is set later.\n end: Object.assign({}, token.end)\n };\n map.add(index, 0, [['enter', currentTable, context]]);\n } else if (token.type === 'tableRow' || token.type === 'tableDelimiterRow') {\n inFirstCellAwaitingPipe = true;\n currentCell = undefined;\n lastCell = [0, 0, 0, 0];\n cell = [0, index + 1, 0, 0];\n\n // Inject table body start.\n if (afterHeadAwaitingFirstBodyRow) {\n afterHeadAwaitingFirstBodyRow = false;\n currentBody = {\n type: 'tableBody',\n start: Object.assign({}, token.start),\n // Note: correct end is set later.\n end: Object.assign({}, token.end)\n };\n map.add(index, 0, [['enter', currentBody, context]]);\n }\n rowKind = token.type === 'tableDelimiterRow' ? 2 : currentBody ? 3 : 1;\n }\n // Cell data.\n else if (rowKind && (token.type === \"data\" || token.type === 'tableDelimiterMarker' || token.type === 'tableDelimiterFiller')) {\n inFirstCellAwaitingPipe = false;\n\n // First value in cell.\n if (cell[2] === 0) {\n if (lastCell[1] !== 0) {\n cell[0] = cell[1];\n currentCell = flushCell(map, context, lastCell, rowKind, undefined, currentCell);\n lastCell = [0, 0, 0, 0];\n }\n cell[2] = index;\n }\n } else if (token.type === 'tableCellDivider') {\n if (inFirstCellAwaitingPipe) {\n inFirstCellAwaitingPipe = false;\n } else {\n if (lastCell[1] !== 0) {\n cell[0] = cell[1];\n currentCell = flushCell(map, context, lastCell, rowKind, undefined, currentCell);\n }\n lastCell = cell;\n cell = [lastCell[1], index, 0, 0];\n }\n }\n }\n // Exit events.\n else if (token.type === 'tableHead') {\n afterHeadAwaitingFirstBodyRow = true;\n lastTableEnd = index;\n } else if (token.type === 'tableRow' || token.type === 'tableDelimiterRow') {\n lastTableEnd = index;\n if (lastCell[1] !== 0) {\n cell[0] = cell[1];\n currentCell = flushCell(map, context, lastCell, rowKind, index, currentCell);\n } else if (cell[1] !== 0) {\n currentCell = flushCell(map, context, cell, rowKind, index, currentCell);\n }\n rowKind = 0;\n } else if (rowKind && (token.type === \"data\" || token.type === 'tableDelimiterMarker' || token.type === 'tableDelimiterFiller')) {\n cell[3] = index;\n }\n }\n if (lastTableEnd !== 0) {\n flushTableEnd(map, context, lastTableEnd, currentTable, currentBody);\n }\n map.consume(context.events);\n\n // To do: move this into `html`, when events are exposed there.\n // That’s what `markdown-rs` does.\n // That needs updates to `mdast-util-gfm-table`.\n index = -1;\n while (++index < context.events.length) {\n const event = context.events[index];\n if (event[0] === 'enter' && event[1].type === 'table') {\n event[1]._align = gfmTableAlign(context.events, index);\n }\n }\n return events;\n}\n\n/**\n * Generate a cell.\n *\n * @param {EditMap} map\n * @param {Readonly<TokenizeContext>} context\n * @param {Readonly<Range>} range\n * @param {RowKind} rowKind\n * @param {number | undefined} rowEnd\n * @param {Token | undefined} previousCell\n * @returns {Token | undefined}\n */\n// eslint-disable-next-line max-params\nfunction flushCell(map, context, range, rowKind, rowEnd, previousCell) {\n // `markdown-rs` uses:\n // rowKind === 2 ? 'tableDelimiterCell' : 'tableCell'\n const groupName = rowKind === 1 ? 'tableHeader' : rowKind === 2 ? 'tableDelimiter' : 'tableData';\n // `markdown-rs` uses:\n // rowKind === 2 ? 'tableDelimiterCellValue' : 'tableCellText'\n const valueName = 'tableContent';\n\n // Insert an exit for the previous cell, if there is one.\n //\n // ```markdown\n // > | | aa | bb | cc |\n // ^-- exit\n // ^^^^-- this cell\n // ```\n if (range[0] !== 0) {\n previousCell.end = Object.assign({}, getPoint(context.events, range[0]));\n map.add(range[0], 0, [['exit', previousCell, context]]);\n }\n\n // Insert enter of this cell.\n //\n // ```markdown\n // > | | aa | bb | cc |\n // ^-- enter\n // ^^^^-- this cell\n // ```\n const now = getPoint(context.events, range[1]);\n previousCell = {\n type: groupName,\n start: Object.assign({}, now),\n // Note: correct end is set later.\n end: Object.assign({}, now)\n };\n map.add(range[1], 0, [['enter', previousCell, context]]);\n\n // Insert text start at first data start and end at last data end, and\n // remove events between.\n //\n // ```markdown\n // > | | aa | bb | cc |\n // ^-- enter\n // ^-- exit\n // ^^^^-- this cell\n // ```\n if (range[2] !== 0) {\n const relatedStart = getPoint(context.events, range[2]);\n const relatedEnd = getPoint(context.events, range[3]);\n /** @type {Token} */\n const valueToken = {\n type: valueName,\n start: Object.assign({}, relatedStart),\n end: Object.assign({}, relatedEnd)\n };\n map.add(range[2], 0, [['enter', valueToken, context]]);\n if (rowKind !== 2) {\n // Fix positional info on remaining events\n const start = context.events[range[2]];\n const end = context.events[range[3]];\n start[1].end = Object.assign({}, end[1].end);\n start[1].type = \"chunkText\";\n start[1].contentType = \"text\";\n\n // Remove if needed.\n if (range[3] > range[2] + 1) {\n const a = range[2] + 1;\n const b = range[3] - range[2] - 1;\n map.add(a, b, []);\n }\n }\n map.add(range[3] + 1, 0, [['exit', valueToken, context]]);\n }\n\n // Insert an exit for the last cell, if at the row end.\n //\n // ```markdown\n // > | | aa | bb | cc |\n // ^-- exit\n // ^^^^^^-- this cell (the last one contains two “between” parts)\n // ```\n if (rowEnd !== undefined) {\n previousCell.end = Object.assign({}, getPoint(context.events, rowEnd));\n map.add(rowEnd, 0, [['exit', previousCell, context]]);\n previousCell = undefined;\n }\n return previousCell;\n}\n\n/**\n * Generate table end (and table body end).\n *\n * @param {Readonly<EditMap>} map\n * @param {Readonly<TokenizeContext>} context\n * @param {number} index\n * @param {Token} table\n * @param {Token | undefined} tableBody\n */\n// eslint-disable-next-line max-params\nfunction flushTableEnd(map, context, index, table, tableBody) {\n /** @type {Array<Event>} */\n const exits = [];\n const related = getPoint(context.events, index);\n if (tableBody) {\n tableBody.end = Object.assign({}, related);\n exits.push(['exit', tableBody, context]);\n }\n table.end = Object.assign({}, related);\n exits.push(['exit', table, context]);\n map.add(index + 1, 0, exits);\n}\n\n/**\n * @param {Readonly<Array<Event>>} events\n * @param {number} index\n * @returns {Readonly<Point>}\n */\nfunction getPoint(events, index) {\n const event = events[index];\n const side = event[0] === 'enter' ? 'start' : 'end';\n return event[1][side];\n}","/**\n * @import {Event} from 'micromark-util-types'\n */\n\n// Port of `edit_map.rs` from `markdown-rs`.\n// This should move to `markdown-js` later.\n\n// Deal with several changes in events, batching them together.\n//\n// Preferably, changes should be kept to a minimum.\n// Sometimes, it’s needed to change the list of events, because parsing can be\n// messy, and it helps to expose a cleaner interface of events to the compiler\n// and other users.\n// It can also help to merge many adjacent similar events.\n// And, in other cases, it’s needed to parse subcontent: pass some events\n// through another tokenizer and inject the result.\n\n/**\n * @typedef {[number, number, Array<Event>]} Change\n * @typedef {[number, number, number]} Jump\n */\n\n/**\n * Tracks a bunch of edits.\n */\nexport class EditMap {\n /**\n * Create a new edit map.\n */\n constructor() {\n /**\n * Record of changes.\n *\n * @type {Array<Change>}\n */\n this.map = [];\n }\n\n /**\n * Create an edit: a remove and/or add at a certain place.\n *\n * @param {number} index\n * @param {number} remove\n * @param {Array<Event>} add\n * @returns {undefined}\n */\n add(index, remove, add) {\n addImplementation(this, index, remove, add);\n }\n\n // To do: add this when moving to `micromark`.\n // /**\n // * Create an edit: but insert `add` before existing additions.\n // *\n // * @param {number} index\n // * @param {number} remove\n // * @param {Array<Event>} add\n // * @returns {undefined}\n // */\n // addBefore(index, remove, add) {\n // addImplementation(this, index, remove, add, true)\n // }\n\n /**\n * Done, change the events.\n *\n * @param {Array<Event>} events\n * @returns {undefined}\n */\n consume(events) {\n this.map.sort(function (a, b) {\n return a[0] - b[0];\n });\n\n /* c8 ignore next 3 -- `resolve` is never called without tables, so without edits. */\n if (this.map.length === 0) {\n return;\n }\n\n // To do: if links are added in events, like they are in `markdown-rs`,\n // this is needed.\n // // Calculate jumps: where items in the current list move to.\n // /** @type {Array<Jump>} */\n // const jumps = []\n // let index = 0\n // let addAcc = 0\n // let removeAcc = 0\n // while (index < this.map.length) {\n // const [at, remove, add] = this.map[index]\n // removeAcc += remove\n // addAcc += add.length\n // jumps.push([at, removeAcc, addAcc])\n // index += 1\n // }\n //\n // . shiftLinks(events, jumps)\n\n let index = this.map.length;\n /** @type {Array<Array<Event>>} */\n const vecs = [];\n while (index > 0) {\n index -= 1;\n vecs.push(events.slice(this.map[index][0] + this.map[index][1]), this.map[index][2]);\n\n // Truncate rest.\n events.length = this.map[index][0];\n }\n vecs.push(events.slice());\n events.length = 0;\n let slice = vecs.pop();\n while (slice) {\n for (const element of slice) {\n events.push(element);\n }\n slice = vecs.pop();\n }\n\n // Truncate everything.\n this.map.length = 0;\n }\n}\n\n/**\n * Create an edit.\n *\n * @param {EditMap} editMap\n * @param {number} at\n * @param {number} remove\n * @param {Array<Event>} add\n * @returns {undefined}\n */\nfunction addImplementation(editMap, at, remove, add) {\n let index = 0;\n\n /* c8 ignore next 3 -- `resolve` is never called without tables, so without edits. */\n if (remove === 0 && add.length === 0) {\n return;\n }\n while (index < editMap.map.length) {\n if (editMap.map[index][0] === at) {\n editMap.map[index][1] += remove;\n\n // To do: before not used by tables, use when moving to micromark.\n // if (before) {\n // add.push(...editMap.map[index][2])\n // editMap.map[index][2] = add\n // } else {\n editMap.map[index][2].push(...add);\n // }\n\n return;\n }\n index += 1;\n }\n editMap.map.push([at, remove, add]);\n}\n\n// /**\n// * Shift `previous` and `next` links according to `jumps`.\n// *\n// * This fixes links in case there are events removed or added between them.\n// *\n// * @param {Array<Event>} events\n// * @param {Array<Jump>} jumps\n// */\n// function shiftLinks(events, jumps) {\n// let jumpIndex = 0\n// let index = 0\n// let add = 0\n// let rm = 0\n\n// while (index < events.length) {\n// const rmCurr = rm\n\n// while (jumpIndex < jumps.length && jumps[jumpIndex][0] <= index) {\n// add = jumps[jumpIndex][2]\n// rm = jumps[jumpIndex][1]\n// jumpIndex += 1\n// }\n\n// // Ignore items that will be removed.\n// if (rm > rmCurr) {\n// index += rm - rmCurr\n// } else {\n// // ?\n// // if let Some(link) = &events[index].link {\n// // if let Some(next) = link.next {\n// // events[next].link.as_mut().unwrap().previous = Some(index + add - rm);\n// // while jumpIndex < jumps.len() && jumps[jumpIndex].0 <= next {\n// // add = jumps[jumpIndex].2;\n// // rm = jumps[jumpIndex].1;\n// // jumpIndex += 1;\n// // }\n// // events[index].link.as_mut().unwrap().next = Some(next + add - rm);\n// // index = next;\n// // continue;\n// // }\n// // }\n// index += 1\n// }\n// }\n// }","/**\n * @import {Event} from 'micromark-util-types'\n */\n\n/**\n * @typedef {'center' | 'left' | 'none' | 'right'} Align\n */\n\n/**\n * Figure out the alignment of a GFM table.\n *\n * @param {Readonly<Array<Event>>} events\n * List of events.\n * @param {number} index\n * Table enter event.\n * @returns {Array<Align>}\n * List of aligns.\n */\nexport function gfmTableAlign(events, index) {\n let inDelimiterRow = false;\n /** @type {Array<Align>} */\n const align = [];\n while (index < events.length) {\n const event = events[index];\n if (inDelimiterRow) {\n if (event[0] === 'enter') {\n // Start of alignment value: set a new column.\n // To do: `markdown-rs` uses `tableDelimiterCellValue`.\n if (event[1].type === 'tableContent') {\n align.push(events[index + 1][1].type === 'tableDelimiterMarker' ? 'left' : 'none');\n }\n }\n // Exits:\n // End of alignment value: change the column.\n // To do: `markdown-rs` uses `tableDelimiterCellValue`.\n else if (event[1].type === 'tableContent') {\n if (events[index - 1][1].type === 'tableDelimiterMarker') {\n const alignIndex = align.length - 1;\n align[alignIndex] = align[alignIndex] === 'left' ? 'center' : 'right';\n }\n }\n // Done!\n else if (event[1].type === 'tableDelimiterRow') {\n break;\n }\n } else if (event[0] === 'enter' && event[1].type === 'tableDelimiterRow') {\n inDelimiterRow = true;\n }\n index += 1;\n }\n return align;\n}","/**\n * @import {Extension, State, TokenizeContext, Tokenizer} from 'micromark-util-types'\n */\n\nimport { factorySpace } from 'micromark-factory-space';\nimport { markdownLineEnding, markdownLineEndingOrSpace, markdownSpace } from 'micromark-util-character';\nconst tasklistCheck = {\n name: 'tasklistCheck',\n tokenize: tokenizeTasklistCheck\n};\n\n/**\n * Create an HTML extension for `micromark` to support GFM task list items\n * syntax.\n *\n * @returns {Extension}\n * Extension for `micromark` that can be passed in `htmlExtensions` to\n * support GFM task list items when serializing to HTML.\n */\nexport function gfmTaskListItem() {\n return {\n text: {\n [91]: tasklistCheck\n }\n };\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeTasklistCheck(effects, ok, nok) {\n const self = this;\n return open;\n\n /**\n * At start of task list item check.\n *\n * ```markdown\n * > | * [x] y.\n * ^\n * ```\n *\n * @type {State}\n */\n function open(code) {\n if (\n // Exit if there’s stuff before.\n self.previous !== null ||\n // Exit if not in the first content that is the first child of a list\n // item.\n !self._gfmTasklistFirstContentOfListItem) {\n return nok(code);\n }\n effects.enter('taskListCheck');\n effects.enter('taskListCheckMarker');\n effects.consume(code);\n effects.exit('taskListCheckMarker');\n return inside;\n }\n\n /**\n * In task list item check.\n *\n * ```markdown\n * > | * [x] y.\n * ^\n * ```\n *\n * @type {State}\n */\n function inside(code) {\n // Currently we match how GH works in files.\n // To match how GH works in comments, use `markdownSpace` (`[\\t ]`) instead\n // of `markdownLineEndingOrSpace` (`[\\t\\n\\r ]`).\n if (markdownLineEndingOrSpace(code)) {\n effects.enter('taskListCheckValueUnchecked');\n effects.consume(code);\n effects.exit('taskListCheckValueUnchecked');\n return close;\n }\n if (code === 88 || code === 120) {\n effects.enter('taskListCheckValueChecked');\n effects.consume(code);\n effects.exit('taskListCheckValueChecked');\n return close;\n }\n return nok(code);\n }\n\n /**\n * At close of task list item check.\n *\n * ```markdown\n * > | * [x] y.\n * ^\n * ```\n *\n * @type {State}\n */\n function close(code) {\n if (code === 93) {\n effects.enter('taskListCheckMarker');\n effects.consume(code);\n effects.exit('taskListCheckMarker');\n effects.exit('taskListCheck');\n return after;\n }\n return nok(code);\n }\n\n /**\n * @type {State}\n */\n function after(code) {\n // EOL in paragraph means there must be something else after it.\n if (markdownLineEnding(code)) {\n return ok(code);\n }\n\n // Space or tab?\n // Check what comes after.\n if (markdownSpace(code)) {\n return effects.check({\n tokenize: spaceThenNonSpace\n }, ok, nok)(code);\n }\n\n // EOF, or non-whitespace, both wrong.\n return nok(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction spaceThenNonSpace(effects, ok, nok) {\n return factorySpace(effects, after, \"whitespace\");\n\n /**\n * After whitespace, after task list item check.\n *\n * ```markdown\n * > | * [x] y.\n * ^\n * ```\n *\n * @type {State}\n */\n function after(code) {\n // EOF means there was nothing, so bad.\n // EOL means there’s content after it, so good.\n // Impossible to have more spaces.\n // Anything else is good.\n return code === null ? nok(code) : ok(code);\n }\n}","/**\n * mdast transform plugin for Jinja if/elif/else/endif blocks.\n *\n * Three passes:\n * Pass 1 — Extract Jinja tags absorbed into list item text (Case B)\n * Pass 2 — Group standalone Jinja-tag paragraphs into jinjaIfBlockMdast nodes (Case A)\n * Pass 3 — Structure inline Jinja tags into jinjaIfInlineMdast nodes\n */\n\nconst MAX_DEPTH = 128;\n\n// Regex for a standalone Jinja tag paragraph (entire paragraph is one tag)\nconst JINJA_BLOCK_RE = /^\\s*\\{%\\s*(if|elif|else|endif)\\s*([^%]*?)\\s*%\\}\\s*$/;\n\n// Regex for Jinja tags at line boundaries inside list item text\nconst JINJA_LINE_END_RE = /\\n\\s*(\\{%\\s*(?:if|elif|else|endif)\\s*[^%]*?\\s*%\\})\\s*$/;\nconst JINJA_LINE_START_RE = /^(\\{%\\s*(?:if|elif|else|endif)\\s*[^%]*?\\s*%\\})\\s*\\n/;\n\n// Regex for inline Jinja tags (non-greedy, captures tag type and condition)\nconst JINJA_INLINE_RE = /\\{%\\s*(if|elif|else|endif)\\s*([^%]*?)\\s*%\\}/g;\n\ntype BranchType = 'if' | 'elif' | 'else';\n\nexport interface JinjaBranchMdast {\n branchType: BranchType;\n condition?: string;\n content: unknown[];\n}\n\nexport interface JinjaIfBlockMdastNode {\n type: 'jinjaIfBlockMdast';\n branches: JinjaBranchMdast[];\n}\n\nexport interface JinjaIfInlineMdastNode {\n type: 'jinjaIfInlineMdast';\n branches: JinjaBranchMdast[];\n}\n\ndeclare module 'mdast' {\n interface BlockContentMap {\n jinjaIfBlockMdast: JinjaIfBlockMdastNode;\n }\n interface PhrasingContentMap {\n jinjaIfInlineMdast: JinjaIfInlineMdastNode;\n }\n interface RootContentMap {\n jinjaIfBlockMdast: JinjaIfBlockMdastNode;\n }\n}\n\nfunction parseTag(text: string): { type: 'if' | 'elif' | 'else' | 'endif'; condition?: string } | null {\n const m = text.match(/^\\s*\\{%\\s*(if|elif|else|endif)\\s*([^%]*?)\\s*%\\}\\s*$/);\n if (!m) return null;\n const type = m[1] as 'if' | 'elif' | 'else' | 'endif';\n const condition = m[2]?.trim() || undefined;\n return { type, condition };\n}\n\nfunction isTextOnlyParagraph(node: { type: string; children?: unknown[] }): string | null {\n if (node.type !== 'paragraph') return null;\n if (!node.children || node.children.length !== 1) return null;\n const child = node.children[0] as { type: string; value?: string };\n if (child.type !== 'text') return null;\n return child.value ?? null;\n}\n\n/**\n * Pass 1: Extract Jinja tags absorbed into list item text.\n * When there's no blank line between a Jinja tag and a list, mdast absorbs\n * the tag into the list item's text. We split these out.\n */\nfunction pass1ExtractFromLists(node: { type: string; children?: unknown[] }, depth: number): void {\n if (depth > MAX_DEPTH || !node.children) return;\n\n // Recurse first\n for (const child of node.children) {\n pass1ExtractFromLists(child as { type: string; children?: unknown[] }, depth + 1);\n }\n\n // Only process list nodes\n if (node.type !== 'list') return;\n\n const list = node as { type: string; ordered?: boolean; start?: number; spread?: boolean; children: unknown[] };\n const items = list.children as Array<{ type: string; children: Array<{ type: string; children?: Array<{ type: string; value?: string }> }> }>;\n\n // Scan list items for Jinja tags at text boundaries\n type ExtractedPiece =\n | { kind: 'item'; item: unknown }\n | { kind: 'tag'; raw: string };\n\n const extracted: ExtractedPiece[] = [];\n let hadSplit = false;\n\n for (const item of items) {\n if (item.type !== 'listItem' || !item.children || item.children.length === 0) {\n extracted.push({ kind: 'item', item });\n continue;\n }\n\n // Check first paragraph for leading Jinja tag\n const firstChild = item.children[0];\n if (firstChild.type === 'paragraph' && firstChild.children && firstChild.children.length === 1 && firstChild.children[0].type === 'text') {\n const text = firstChild.children[0].value ?? '';\n const startMatch = text.match(JINJA_LINE_START_RE);\n if (startMatch) {\n hadSplit = true;\n extracted.push({ kind: 'tag', raw: startMatch[1] });\n const remainder = text.slice(startMatch[0].length);\n if (remainder.trim()) {\n firstChild.children[0] = { ...firstChild.children[0], value: remainder };\n extracted.push({ kind: 'item', item });\n } else if (item.children.length > 1) {\n item.children = item.children.slice(1);\n extracted.push({ kind: 'item', item });\n }\n continue;\n }\n }\n\n // Check last paragraph for trailing Jinja tag\n const lastChild = item.children[item.children.length - 1];\n if (lastChild.type === 'paragraph' && lastChild.children && lastChild.children.length === 1 && lastChild.children[0].type === 'text') {\n const text = lastChild.children[0].value ?? '';\n const endMatch = text.match(JINJA_LINE_END_RE);\n if (endMatch) {\n hadSplit = true;\n const remainder = text.slice(0, text.length - endMatch[0].length);\n if (remainder.trim()) {\n lastChild.children[0] = { ...lastChild.children[0], value: remainder };\n extracted.push({ kind: 'item', item });\n } else if (item.children.length > 1) {\n item.children = item.children.slice(0, -1);\n extracted.push({ kind: 'item', item });\n }\n extracted.push({ kind: 'tag', raw: endMatch[1] });\n continue;\n }\n }\n\n extracted.push({ kind: 'item', item });\n }\n\n if (!hadSplit) return;\n\n // Rebuild: replace parent's list node with a sequence of lists and tag paragraphs\n // We need to modify the parent's children. Since we're in the list node itself,\n // we'll reconstruct the list into segments.\n const parent = node as { type: string; children: unknown[] };\n\n // Actually, we need to replace this list node in its parent.\n // Instead, we mark the list with a special property to be expanded later.\n // Let's use a different approach: collect consecutive items into sub-lists,\n // interleaved with tag paragraphs.\n\n const result: unknown[] = [];\n let currentItems: unknown[] = [];\n let itemIndex = 0;\n\n function flushItems(): void {\n if (currentItems.length === 0) return;\n const startNum = list.ordered ? (list.start ?? 1) + itemIndex - currentItems.length : undefined;\n const subList = {\n type: 'list',\n ordered: list.ordered ?? false,\n spread: list.spread ?? false,\n ...(list.ordered ? { start: startNum } : {}),\n children: currentItems,\n };\n result.push(subList);\n currentItems = [];\n }\n\n for (const piece of extracted) {\n if (piece.kind === 'item') {\n currentItems.push(piece.item);\n itemIndex++;\n } else {\n flushItems();\n result.push({\n type: 'paragraph',\n children: [{ type: 'text', value: piece.raw }],\n });\n }\n }\n flushItems();\n\n // Mark this node for expansion in parent\n (node as { _jinjaExpanded?: unknown[] })._jinjaExpanded = result;\n}\n\n/**\n * After pass1, expand any list nodes that were marked with _jinjaExpanded.\n */\nfunction expandMarkedLists(node: { type: string; children?: unknown[] }, depth: number): void {\n if (depth > MAX_DEPTH || !node.children) return;\n\n // Process children first (bottom-up)\n for (const child of node.children) {\n expandMarkedLists(child as { type: string; children?: unknown[] }, depth + 1);\n }\n\n const newChildren: unknown[] = [];\n let changed = false;\n for (const child of node.children) {\n const c = child as { _jinjaExpanded?: unknown[] };\n if (c._jinjaExpanded) {\n newChildren.push(...c._jinjaExpanded);\n changed = true;\n } else {\n newChildren.push(child);\n }\n }\n if (changed) {\n node.children = newChildren;\n }\n}\n\n/**\n * Pass 2: Group standalone Jinja-tag paragraphs into jinjaIfBlockMdast nodes.\n * Works on children of root, blockquote, and listItem.\n */\nfunction pass2GroupBlocks(node: { type: string; children?: unknown[] }, depth: number): void {\n if (depth > MAX_DEPTH || !node.children) return;\n\n // Recurse into children first\n for (const child of node.children) {\n pass2GroupBlocks(child as { type: string; children?: unknown[] }, depth + 1);\n }\n\n // Only process container nodes\n const containerTypes = new Set(['root', 'blockquote', 'listItem']);\n if (!containerTypes.has(node.type)) return;\n\n const children = node.children as Array<{ type: string; children?: unknown[] }>;\n const result: unknown[] = [];\n let i = 0;\n\n while (i < children.length) {\n const child = children[i];\n const text = isTextOnlyParagraph(child);\n const tag = text ? parseTag(text) : null;\n\n if (!tag || tag.type !== 'if') {\n result.push(child);\n i++;\n continue;\n }\n\n // Found {% if %} - use stack to find matching {% endif %}\n const ifParagraph = child; // save for position\n const branches: JinjaBranchMdast[] = [];\n let currentBranch: JinjaBranchMdast = {\n branchType: 'if',\n condition: tag.condition,\n content: [],\n };\n branches.push(currentBranch);\n\n let nestDepth = 1;\n i++; // skip the {% if %} paragraph\n\n let matched = false;\n let endifParagraph: { type: string; children?: unknown[]; position?: unknown } | null = null;\n while (i < children.length && nestDepth > 0) {\n const innerChild = children[i];\n const innerText = isTextOnlyParagraph(innerChild);\n const innerTag = innerText ? parseTag(innerText) : null;\n\n if (innerTag) {\n if (innerTag.type === 'if') {\n nestDepth++;\n if (nestDepth > 1) {\n currentBranch.content.push(innerChild);\n }\n } else if (innerTag.type === 'endif') {\n nestDepth--;\n if (nestDepth === 0) {\n matched = true;\n endifParagraph = innerChild;\n } else {\n currentBranch.content.push(innerChild);\n }\n } else if ((innerTag.type === 'elif' || innerTag.type === 'else') && nestDepth === 1) {\n currentBranch = {\n branchType: innerTag.type as BranchType,\n ...(innerTag.condition ? { condition: innerTag.condition } : {}),\n content: [],\n };\n branches.push(currentBranch);\n } else {\n currentBranch.content.push(innerChild);\n }\n } else {\n currentBranch.content.push(innerChild);\n }\n i++;\n }\n\n if (matched) {\n // Recursively process branch contents\n for (const branch of branches) {\n const wrapper = { type: node.type, children: branch.content };\n pass2GroupBlocks(wrapper, depth + 1);\n branch.content = wrapper.children as unknown[];\n }\n // Propagate position from {% if %} to {% endif %} for blank-line calculation\n const startPos = (ifParagraph as { position?: { start?: unknown } }).position?.start;\n const endPos = (endifParagraph as { position?: { end?: unknown } } | null)?.position?.end;\n const pos = startPos && endPos ? { position: { start: startPos, end: endPos } } : {};\n result.push({ type: 'jinjaIfBlockMdast', branches, ...pos });\n } else {\n // Unmatched {% if %} — restore as plain paragraph\n result.push({ type: 'paragraph', children: [{ type: 'text', value: text }] });\n // Rewind: the content we consumed needs to go back\n // Actually, we already advanced i, and the branches contain the consumed children.\n // We need to flatten them back.\n for (const branch of branches) {\n if (branch !== branches[0]) {\n // Re-emit the branch tag\n const tagText = branch.branchType === 'else'\n ? '{% else %}'\n : `{% ${branch.branchType} ${branch.condition ?? ''} %}`.trim();\n result.push({ type: 'paragraph', children: [{ type: 'text', value: tagText }] });\n }\n result.push(...branch.content);\n }\n }\n }\n\n node.children = result;\n}\n\n/**\n * Pass 3: Structure inline Jinja tags within paragraph/heading text nodes.\n * Only processes direct text children (not inside marks like strong/emphasis).\n */\nfunction pass3InlineJinja(node: { type: string; children?: unknown[] }, depth: number): void {\n if (depth > MAX_DEPTH || !node.children) return;\n\n // Recurse into block-level children\n for (const child of node.children) {\n pass3InlineJinja(child as { type: string; children?: unknown[] }, depth + 1);\n }\n\n // Only process paragraph and heading\n if (node.type !== 'paragraph' && node.type !== 'heading') return;\n\n const children = node.children as Array<{ type: string; value?: string }>;\n\n // Check if any text child contains Jinja tags\n let hasJinja = false;\n for (const child of children) {\n if (child.type === 'text' && child.value) {\n JINJA_INLINE_RE.lastIndex = 0;\n if (JINJA_INLINE_RE.test(child.value)) {\n hasJinja = true;\n break;\n }\n }\n }\n if (!hasJinja) return;\n\n // Split text nodes on Jinja tags, then structure with stack\n const flatParts: Array<{ kind: 'node'; node: unknown } | { kind: 'tag'; tagType: 'if' | 'elif' | 'else' | 'endif'; condition?: string }> = [];\n\n for (const child of children) {\n if (child.type !== 'text' || !child.value) {\n flatParts.push({ kind: 'node', node: child });\n continue;\n }\n\n const text = child.value;\n JINJA_INLINE_RE.lastIndex = 0;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = JINJA_INLINE_RE.exec(text)) !== null) {\n if (match.index > lastIndex) {\n flatParts.push({ kind: 'node', node: { type: 'text', value: text.slice(lastIndex, match.index) } });\n }\n flatParts.push({\n kind: 'tag',\n tagType: match[1] as 'if' | 'elif' | 'else' | 'endif',\n condition: match[2]?.trim() || undefined,\n });\n lastIndex = match.index + match[0].length;\n }\n\n if (lastIndex < text.length) {\n flatParts.push({ kind: 'node', node: { type: 'text', value: text.slice(lastIndex) } });\n }\n }\n\n // Stack-based structuring\n const result = structureInlineParts(flatParts);\n if (result) {\n node.children = result;\n }\n}\n\nfunction structureInlineParts(\n parts: Array<{ kind: 'node'; node: unknown } | { kind: 'tag'; tagType: 'if' | 'elif' | 'else' | 'endif'; condition?: string }>,\n): unknown[] | null {\n const output: unknown[] = [];\n let i = 0;\n\n while (i < parts.length) {\n const part = parts[i];\n if (part.kind === 'node') {\n output.push(part.node);\n i++;\n } else if (part.kind === 'tag' && part.tagType === 'if') {\n // Collect branches until matching endif\n const branches: JinjaBranchMdast[] = [];\n let currentBranch: JinjaBranchMdast = {\n branchType: 'if',\n condition: part.condition,\n content: [],\n };\n branches.push(currentBranch);\n i++;\n\n let nestDepth = 1;\n let matched = false;\n\n while (i < parts.length && nestDepth > 0) {\n const inner = parts[i];\n if (inner.kind === 'tag') {\n if (inner.tagType === 'if') {\n nestDepth++;\n if (nestDepth > 1) {\n // Nested if — emit as text for now\n currentBranch.content.push({ type: 'text', value: `{% if ${inner.condition ?? ''} %}`.trim() });\n }\n } else if (inner.tagType === 'endif') {\n nestDepth--;\n if (nestDepth === 0) {\n matched = true;\n } else {\n currentBranch.content.push({ type: 'text', value: '{% endif %}' });\n }\n } else if ((inner.tagType === 'elif' || inner.tagType === 'else') && nestDepth === 1) {\n currentBranch = {\n branchType: inner.tagType as BranchType,\n ...(inner.condition ? { condition: inner.condition } : {}),\n content: [],\n };\n branches.push(currentBranch);\n } else {\n // Nested elif/else\n const tagText = inner.tagType === 'else'\n ? '{% else %}'\n : `{% ${inner.tagType} ${inner.condition ?? ''} %}`.trim();\n currentBranch.content.push({ type: 'text', value: tagText });\n }\n } else {\n currentBranch.content.push(inner.node);\n }\n i++;\n }\n\n if (matched) {\n output.push({ type: 'jinjaIfInlineMdast', branches });\n } else {\n // Unmatched — restore as text\n output.push({ type: 'text', value: `{% if ${branches[0].condition ?? ''} %}`.trim() });\n for (const branch of branches) {\n if (branch !== branches[0]) {\n const tagText = branch.branchType === 'else'\n ? '{% else %}'\n : `{% ${branch.branchType} ${branch.condition ?? ''} %}`.trim();\n output.push({ type: 'text', value: tagText });\n }\n output.push(...branch.content);\n }\n }\n } else {\n // Stray elif/else/endif — keep as text\n const p = part as { tagType: string; condition?: string };\n const tagText = p.tagType === 'else'\n ? '{% else %}'\n : p.tagType === 'endif'\n ? '{% endif %}'\n : `{% ${p.tagType} ${p.condition ?? ''} %}`.trim();\n output.push({ type: 'text', value: tagText });\n i++;\n }\n }\n\n return output;\n}\n\n/**\n * Main transform: apply all three passes to an mdast tree.\n */\nexport function jinjaBlockTransform(tree: { type: string; children?: unknown[] }): void {\n // Pass 1: Extract Jinja tags from list item text\n pass1ExtractFromLists(tree, 0);\n expandMarkedLists(tree, 0);\n\n // Pass 2: Group block-level Jinja structures\n pass2GroupBlocks(tree, 0);\n\n // Pass 3: Structure inline Jinja\n pass3InlineJinja(tree, 0);\n}\n","import { parseMarkdown } from './parser';\nimport { serializeToMarkdown } from './serializer';\nimport type { AstNode, BlockNode, InlineNode, DocumentNode } from '../ast/types';\n\n/**\n * Serialize a list of AST nodes to markdown string (for clipboard).\n */\nexport function serializeFragment(nodes: AstNode[]): string {\n if (nodes.length === 0) return '';\n\n // Wrap in a doc for serialization\n const blocks: BlockNode[] = nodes.map((node) => {\n if (node.type === 'text' || node.type === 'resourceTag' || node.type === 'jumpPoint' || node.type === 'hardBreak') {\n return { type: 'paragraph', content: [node] };\n }\n if (node.type === 'doc') {\n // Flatten doc children\n return node.content;\n }\n return node as BlockNode;\n }).flat() as BlockNode[];\n\n const wrapper: DocumentNode = { type: 'doc', content: blocks };\n return serializeToMarkdown(wrapper);\n}\n\n/**\n * Parse a markdown string into a fragment (for clipboard paste).\n * Returns block nodes by default; if the markdown is a single paragraph,\n * returns its inline children.\n */\nexport function parseFragment(markdown: string): InlineNode[] | BlockNode[] {\n const doc = parseMarkdown(markdown);\n\n // If single paragraph, return inline content\n if (doc.content.length === 1 && doc.content[0].type === 'paragraph') {\n return doc.content[0].content as InlineNode[];\n }\n\n return doc.content as BlockNode[];\n}\n","/**\n * Pure text-based Jinja block scanner (no ProseMirror dependency).\n */\nimport type { JinjaBlock } from './types';\n\nconst JINJA_PATTERN = /\\{%\\s*(if|elif|else|endif)\\s*([^%]*?)\\s*%\\}/g;\n\n/**\n * Scan all Jinja blocks from plain text.\n *\n * @param text - Plain text content\n * @returns All Jinja blocks sorted by position\n */\nexport function scanJinjaBlocks(text: string): JinjaBlock[] {\n const blocks: JinjaBlock[] = [];\n\n JINJA_PATTERN.lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = JINJA_PATTERN.exec(text)) !== null) {\n const type = match[1] as JinjaBlock['type'];\n const conditionRaw = match[2].trim();\n const condition = type === 'if' || type === 'elif' ? conditionRaw : undefined;\n\n // Include trailing spaces after tag\n let endIndex = match.index + match[0].length;\n while (endIndex < text.length && text[endIndex] === ' ') {\n endIndex++;\n }\n\n blocks.push({\n type,\n condition,\n startIndex: match.index,\n endIndex,\n raw: match[0],\n });\n }\n\n return blocks.sort((a, b) => a.startIndex - b.startIndex);\n}\n","import type { JinjaBlock, JinjaIfStructure } from './types';\n\nfunction buildStructure(\n partial: { ifBlock: JinjaBlock; elifBlocks: JinjaBlock[]; elseBlock?: JinjaBlock },\n endifBlock: JinjaBlock,\n): JinjaIfStructure {\n const { ifBlock, elifBlocks, elseBlock } = partial;\n const contentRanges: JinjaIfStructure['contentRanges'] = [];\n\n // if branch content\n const ifContentEnd = elifBlocks[0]?.startIndex ?? elseBlock?.startIndex ?? endifBlock.startIndex;\n contentRanges.push({\n type: 'if',\n condition: ifBlock.condition!,\n startIndex: ifBlock.endIndex,\n endIndex: ifContentEnd,\n });\n\n // elif branches\n elifBlocks.forEach((elifBlock, idx) => {\n const nextBlock = elifBlocks[idx + 1] ?? elseBlock ?? endifBlock;\n contentRanges.push({\n type: 'elif',\n condition: elifBlock.condition!,\n startIndex: elifBlock.endIndex,\n endIndex: nextBlock.startIndex,\n });\n });\n\n // else branch\n if (elseBlock) {\n contentRanges.push({\n type: 'else',\n startIndex: elseBlock.endIndex,\n endIndex: endifBlock.startIndex,\n });\n }\n\n return {\n id: `jinja-${ifBlock.startIndex}-${endifBlock.endIndex}`,\n ifBlock,\n elifBlocks,\n elseBlock,\n endifBlock,\n contentRanges,\n };\n}\n\n/**\n * Structure scanned blocks into if~endif structures using stack-based approach.\n */\nexport function structureJinjaBlocks(blocks: JinjaBlock[]): JinjaIfStructure[] {\n const structures: JinjaIfStructure[] = [];\n const stack: Array<{\n ifBlock: JinjaBlock;\n elifBlocks: JinjaBlock[];\n elseBlock?: JinjaBlock;\n }> = [];\n\n for (const block of blocks) {\n switch (block.type) {\n case 'if':\n stack.push({ ifBlock: block, elifBlocks: [] });\n break;\n case 'elif':\n if (stack.length > 0) {\n stack[stack.length - 1].elifBlocks.push(block);\n }\n break;\n case 'else':\n if (stack.length > 0) {\n stack[stack.length - 1].elseBlock = block;\n }\n break;\n case 'endif': {\n const current = stack.pop();\n if (current) {\n structures.push(buildStructure(current, block));\n }\n break;\n }\n }\n }\n\n return structures;\n}\n","import type { DocumentNode } from '../ast/types';\nimport { textContent } from '../ast/traverse';\nimport { scanJinjaBlocks } from './scanner';\nimport { structureJinjaBlocks } from './structurer';\n\nexport interface JinjaVisualBranch {\n type: 'if' | 'elif' | 'else';\n condition?: string;\n blockStartIndex: number;\n blockEndIndex: number;\n tagBlockIndex: number;\n}\n\nexport interface JinjaVisualStructure {\n id: string;\n branches: JinjaVisualBranch[];\n ifTagBlockIndex: number;\n endifTagBlockIndex: number;\n}\n\n/**\n * Single pass: builds cumulative block-end offsets AND the full document text.\n * offsets[i] = exclusive end char index of block i.\n * Avoids calling textContent() twice (once for offsets, once for fullText).\n */\nfunction buildOffsetsAndText(doc: DocumentNode): { offsets: number[]; fullText: string } {\n const offsets: number[] = [];\n const parts: string[] = [];\n let cursor = 0;\n for (const block of doc.content) {\n const t = textContent(block);\n parts.push(t);\n cursor += t.length;\n offsets.push(cursor);\n }\n return { offsets, fullText: parts.join('') };\n}\n\n/**\n * Binary search: returns the block index that contains charIndex.\n * offsets[i] is the exclusive end of block i.\n */\nfunction charIndexToBlockIndex(offsets: number[], charIndex: number): number {\n if (offsets.length === 0) return 0;\n let lo = 0;\n let hi = offsets.length - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (offsets[mid] <= charIndex) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\n/**\n * Analyze a DocumentNode for Jinja if/elif/else/endif structures\n * and map them to block-level indices.\n */\nexport function analyzeJinjaBlocks(doc: DocumentNode): JinjaVisualStructure[] {\n if (doc.content.length === 0) return [];\n\n const { offsets, fullText } = buildOffsetsAndText(doc);\n\n const scanned = scanJinjaBlocks(fullText);\n if (scanned.length === 0) return [];\n\n const structures = structureJinjaBlocks(scanned);\n\n return structures.map((structure) => {\n const ifTagBlockIdx = charIndexToBlockIndex(offsets, structure.ifBlock.startIndex);\n const endifTagBlockIdx = charIndexToBlockIndex(offsets, structure.endifBlock.startIndex);\n\n const branches: JinjaVisualBranch[] = structure.contentRanges.map((range) => {\n // Find the tag block index for this branch\n let tagCharIndex: number;\n if (range.type === 'if') {\n tagCharIndex = structure.ifBlock.startIndex;\n } else if (range.type === 'elif') {\n const elifBlock = structure.elifBlocks.find((b) => b.condition === range.condition);\n tagCharIndex = elifBlock ? elifBlock.startIndex : range.startIndex;\n } else {\n tagCharIndex = structure.elseBlock!.startIndex;\n }\n\n const tagBlockIdx = charIndexToBlockIndex(offsets, tagCharIndex);\n\n // Content block range: from the block containing the content start\n // to the block containing the content end (exclusive)\n let contentStartBlock: number;\n let contentEndBlock: number;\n\n if (range.startIndex >= range.endIndex) {\n // Empty content range\n contentStartBlock = tagBlockIdx;\n contentEndBlock = tagBlockIdx;\n } else {\n contentStartBlock = charIndexToBlockIndex(offsets, range.startIndex);\n // If the content starts in the same block as the tag, the actual content blocks start after\n // But we keep the start as-is since the tag and content may share a block\n const lastContentChar = range.endIndex - 1;\n contentEndBlock = charIndexToBlockIndex(offsets, lastContentChar) + 1;\n }\n\n return {\n type: range.type,\n condition: range.condition,\n blockStartIndex: contentStartBlock,\n blockEndIndex: contentEndBlock,\n tagBlockIndex: tagBlockIdx,\n };\n });\n\n return {\n id: structure.id,\n branches,\n ifTagBlockIndex: ifTagBlockIdx,\n endifTagBlockIndex: endifTagBlockIdx,\n };\n });\n}\n","/**\n * Jump-point adjacent decoration + edit plugins.\n *\n * Adjacent plugin: marks jumpPoint nodes near the cursor with a decoration\n * so the NodeView can show `^id^` raw syntax when the cursor is beside them.\n *\n * Edit plugin: tracks a \"raw range\" after ArrowLeft explodes a jumpPoint atom\n * to `^aa^` text. When the cursor moves outside that range the plugin\n * auto-reconverts the text back to a jumpPoint node (if it still matches\n * `^validId^` and the id has no duplicates elsewhere in the doc).\n *\n * Keymap:\n * Backspace — explode atom to `^aa` (closing `^` consumed), cursor at end\n * ArrowLeft — explode atom to `^aa^`, cursor before closing `^`\n */\nimport { Plugin, PluginKey, TextSelection } from 'prosemirror-state';\nimport type { EditorState, Transaction } from 'prosemirror-state';\nimport { Decoration, DecorationSet } from 'prosemirror-view';\nimport type { ActionbookPlugin } from './types';\n\n// ── Adjacent decoration plugin ────────────────────────────\n\nconst adjacentKey = new PluginKey<DecorationSet>('jumpPointAdjacent');\n\n/** Decoration spec set on a jumpPoint node when the cursor is adjacent. */\nexport const JUMP_POINT_ADJACENT_SPEC = { jumpPointAdjacent: true } as const;\n\nfunction buildDecorations(state: EditorState): DecorationSet {\n const { selection } = state;\n if (!selection.empty) return DecorationSet.empty;\n\n const cursorPos = selection.$from.pos;\n const decorations: Decoration[] = [];\n\n state.doc.descendants((node, pos) => {\n if (node.type.name !== 'jumpPoint') return;\n const nodeEnd = pos + node.nodeSize;\n if (cursorPos === pos || cursorPos === nodeEnd) {\n decorations.push(Decoration.node(pos, nodeEnd, {}, JUMP_POINT_ADJACENT_SPEC));\n }\n });\n\n return DecorationSet.create(state.doc, decorations);\n}\n\n// ── Edit plugin (raw-range tracking + auto-reconvert) ─────\n\ninterface JumpPointEditState {\n rawRange: { from: number; to: number } | null;\n}\n\nexport const jumpPointEditKey = new PluginKey<JumpPointEditState>('jumpPointEdit');\n\n/** Matches the full `^validId^` pattern (letters / underscores only). */\nconst JUMP_POINT_FULL_RE = /^\\^([A-Za-z_][A-Za-z0-9_]*)\\^$/;\n\nfunction createJumpPointEditPlugin(): Plugin<JumpPointEditState> {\n return new Plugin<JumpPointEditState>({\n key: jumpPointEditKey,\n\n state: {\n init: (): JumpPointEditState => ({ rawRange: null }),\n\n apply(tr, prev): JumpPointEditState {\n const meta = tr.getMeta(jumpPointEditKey) as\n | { from: number; to: number }\n | null\n | undefined;\n\n if (meta !== undefined) return { rawRange: meta };\n\n if (prev.rawRange) {\n // Use assoc=-1 for `from` so it stays at the range start when text\n // is inserted/replaced from that position (forward assoc would push\n // it to from+addLen, collapsing the range).\n const from = tr.mapping.map(prev.rawRange.from, -1);\n const to = tr.mapping.map(prev.rawRange.to, 1);\n if (from >= to) return { rawRange: null };\n return { rawRange: { from, to } };\n }\n\n return prev;\n },\n },\n\n appendTransaction(_, __, newState) {\n const pluginState = jumpPointEditKey.getState(newState);\n if (!pluginState?.rawRange) return null;\n\n const { from, to } = pluginState.rawRange;\n const cursor = newState.selection.anchor;\n\n // Still inside the raw region — nothing to do.\n // Use strict `< to` so cursor AT the end of `^aa^` is already \"outside\",\n // meaning a single ArrowRight press from `^aa|^` triggers reconversion.\n if (cursor >= from && cursor < to) return null;\n\n const docSize = newState.doc.content.size;\n const safeFrom = Math.min(from, docSize);\n const safeTo = Math.min(to, docSize);\n\n const reconvertTr = newState.tr;\n reconvertTr.setMeta(jumpPointEditKey, null); // always clear tracking\n\n if (safeFrom < safeTo) {\n const text = newState.doc.textBetween(safeFrom, safeTo);\n const match = JUMP_POINT_FULL_RE.exec(text);\n\n if (match) {\n const [, id] = match;\n const jumpPointType = newState.schema.nodes.jumpPoint;\n\n if (jumpPointType) {\n // Reject duplicate IDs that exist outside the current raw range\n let duplicate = false;\n newState.doc.descendants((node, pos) => {\n if (node.type === jumpPointType && node.attrs.id === id) {\n if (pos < safeFrom || pos >= safeTo) duplicate = true;\n }\n });\n\n if (!duplicate) {\n reconvertTr.replaceWith(safeFrom, safeTo, jumpPointType.create({ id }));\n }\n }\n }\n }\n\n return reconvertTr;\n },\n });\n}\n\n// ── Shared helpers ────────────────────────────────────────\n\n/** Find the jumpPoint atom immediately before the cursor. */\nfunction jumpPointBefore(\n state: EditorState,\n): { id: string; nodeStart: number; nodeEnd: number } | null {\n const { selection } = state;\n if (!selection.empty) return null;\n const { $from } = selection;\n const nodeBefore = $from.nodeBefore;\n if (!nodeBefore || nodeBefore.type.name !== 'jumpPoint') return null;\n const nodeEnd = $from.pos;\n const nodeStart = nodeEnd - nodeBefore.nodeSize;\n return { id: nodeBefore.attrs.id as string, nodeStart, nodeEnd };\n}\n\n/**\n * Backspace on a jumpPoint atom → explode to `^aa` (no closing `^`).\n * Cursor lands at end: `^aa|`\n */\nfunction explodeOnBackspace(state: EditorState): Transaction | null {\n const info = jumpPointBefore(state);\n if (!info) return null;\n const { id, nodeStart, nodeEnd } = info;\n const rawText = `^${id}`;\n const tr = state.tr.replaceWith(nodeStart, nodeEnd, state.schema.text(rawText));\n const cursorPos = Math.min(nodeStart + rawText.length, tr.doc.content.size);\n tr.setSelection(TextSelection.near(tr.doc.resolve(cursorPos)));\n return tr;\n}\n\n/**\n * ArrowLeft on a jumpPoint atom → explode to `^aa^`, cursor before closing `^`.\n * Sets jumpPointEditKey meta so auto-reconvert kicks in when cursor leaves.\n * Result: `^aa|^`\n */\nfunction explodeOnArrowLeft(state: EditorState): Transaction | null {\n const info = jumpPointBefore(state);\n if (!info) return null;\n const { id, nodeStart, nodeEnd } = info;\n const rawText = `^${id}^`;\n const tr = state.tr.replaceWith(nodeStart, nodeEnd, state.schema.text(rawText));\n // cursor before closing `^`\n const cursorPos = Math.min(nodeStart + 1 + id.length, tr.doc.content.size);\n tr.setSelection(TextSelection.near(tr.doc.resolve(cursorPos)));\n // Track range so appendTransaction can reconvert on cursor-leave\n tr.setMeta(jumpPointEditKey, { from: nodeStart, to: nodeStart + rawText.length });\n return tr;\n}\n\n// ── Public factory ────────────────────────────────────────\n\nexport function createJumpPointAdjacentPlugin(): ActionbookPlugin {\n return {\n name: 'jumpPointAdjacent',\n keymap: () => ({\n Backspace: (state, dispatch) => {\n const tr = explodeOnBackspace(state);\n if (!tr) return false;\n if (dispatch) dispatch(tr);\n return true;\n },\n ArrowLeft: (state, dispatch) => {\n const tr = explodeOnArrowLeft(state);\n if (!tr) return false;\n if (dispatch) dispatch(tr);\n return true;\n },\n }),\n plugins: () => [\n createJumpPointEditPlugin(),\n new Plugin({\n key: adjacentKey,\n state: {\n init(_, state) {\n return buildDecorations(state);\n },\n apply(tr, old, _oldState, newState) {\n if (tr.selectionSet || tr.docChanged) {\n return buildDecorations(newState);\n }\n return old.map(tr.mapping, tr.doc);\n },\n },\n props: {\n decorations(state) {\n return adjacentKey.getState(state);\n },\n },\n }),\n ],\n };\n}\n","/**\n * React NodeView plugin for the `jumpPoint` node.\n *\n * Normal state: styled badge (anchor icon + id, yellow background) — matches ActionbookRenderer.\n * Adjacent state: shows `^id^` raw syntax when cursor is immediately before or after the node.\n *\n * Adjacency is communicated via node decorations from `createJumpPointAdjacentPlugin()`.\n */\nimport React from 'react';\nimport { createReactNodeView } from '../nodeView/ReactNodeView';\nimport type { ReactNodeViewProps } from '../nodeView/ReactNodeView';\nimport type { ActionbookPlugin } from './types';\nimport { IconAnchor } from '../components/icons';\n\nconst JUMP_POINT_STYLE: React.CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n backgroundColor: '#FFF2B6',\n border: '1px solid #FFC233',\n color: '#AA5D04',\n borderRadius: '4px',\n padding: '0 0.3em',\n fontSize: '0.85em',\n lineHeight: 1.6,\n userSelect: 'none',\n cursor: 'default',\n boxSizing: 'border-box',\n};\n\nconst JUMP_POINT_ADJACENT_STYLE: React.CSSProperties = {\n ...JUMP_POINT_STYLE,\n backgroundColor: '#FFE680',\n borderColor: '#FF9500',\n};\n\nfunction JumpPointNodeViewComponent({ node, decorations }: ReactNodeViewProps) {\n const id = node.attrs.id as string;\n const isAdjacent = decorations?.some((d) => (d as any).spec?.jumpPointAdjacent === true) ?? false;\n\n if (isAdjacent) {\n return (\n <span style={JUMP_POINT_ADJACENT_STYLE} id={`jp-${id}`}>\n <IconAnchor size={12} fill=\"#AA5D04\" style={{ marginRight: 'max(0.15em, 2px)', flexShrink: 0 }} />\n {`^${id}^`}\n </span>\n );\n }\n\n return (\n <span style={JUMP_POINT_STYLE} id={`jp-${id}`}>\n <IconAnchor size={12} fill=\"#AA5D04\" style={{ marginRight: 'max(0.15em, 2px)', flexShrink: 0 }} />\n {id}\n </span>\n );\n}\n\nexport function createJumpPointNodeViewPlugin(): ActionbookPlugin {\n return {\n name: 'jumpPointNodeView',\n nodeViews: () => ({\n jumpPoint: createReactNodeView({ component: JumpPointNodeViewComponent, inline: true }),\n }),\n };\n}\n","/**\n * React NodeView plugin for the `inlineToolTag` node.\n *\n * Renders a styled badge matching ActionbookRenderer's resourceTag output:\n * colored icon block + colored text label with border.\n */\nimport React from 'react';\nimport { createReactNodeView } from '../nodeView/ReactNodeView';\nimport type { ReactNodeViewProps } from '../nodeView/ReactNodeView';\nimport type { ActionbookPlugin } from './types';\nimport {\n IconTool,\n IconManual,\n IconMessageTemplate,\n IconHandoff,\n IconTimeDiff,\n} from '../components/icons';\n\nconst RESOURCE_TAG_COLORS: Record<string, string> = {\n tool: '#027D69',\n manual: '#5959D3',\n agent_message_template: '#8012B3',\n handoff: '#D25309',\n time_diff: '#FB6B6B',\n};\nconst DEFAULT_COLOR = '#027D69';\n\ntype IconComponent = React.ComponentType<{ size?: number; fill?: string; style?: React.CSSProperties }>;\n\nconst RESOURCE_TAG_ICONS: Record<string, IconComponent> = {\n tool: IconTool,\n manual: IconManual,\n agent_message_template: IconMessageTemplate,\n handoff: IconHandoff,\n time_diff: IconTimeDiff,\n};\nconst DEFAULT_ICON = IconTool;\n\nconst OUTER_STYLE: React.CSSProperties = {\n display: 'inline-flex',\n padding: '1px',\n border: '1px solid #CCCCCC',\n borderRadius: '2px',\n alignItems: 'center',\n backgroundColor: 'white',\n userSelect: 'none',\n cursor: 'default',\n boxSizing: 'border-box',\n};\n\nconst ICON_BLOCK_BASE: React.CSSProperties = {\n display: 'inline-flex',\n justifyContent: 'center',\n alignItems: 'center',\n width: '16px',\n height: '16px',\n borderRadius: '2px',\n flexShrink: 0,\n};\n\nconst LABEL_BASE: React.CSSProperties = {\n padding: '0 4px',\n fontSize: '11px',\n lineHeight: 1,\n userSelect: 'none',\n};\n\nfunction InlineToolTagNodeViewComponent({ node }: ReactNodeViewProps) {\n const type = node.attrs.type as string;\n const text = node.attrs.text as string;\n const color = RESOURCE_TAG_COLORS[type] ?? DEFAULT_COLOR;\n const Icon = RESOURCE_TAG_ICONS[type] ?? DEFAULT_ICON;\n\n return (\n <span style={OUTER_STYLE} data-type={type} data-resource-id={node.attrs.resourceId as string}>\n <span style={{ ...ICON_BLOCK_BASE, backgroundColor: color }}>\n <Icon size={9} fill=\"white\" />\n </span>\n <span style={{ ...LABEL_BASE, color }}>{text}</span>\n </span>\n );\n}\n\nexport function createInlineToolTagNodeViewPlugin(): ActionbookPlugin {\n return {\n name: 'inlineToolTagNodeView',\n nodeViews: () => ({\n inlineToolTag: createReactNodeView({ component: InlineToolTagNodeViewComponent, inline: true }),\n }),\n };\n}\n","import { Plugin, PluginKey } from 'prosemirror-state';\nimport { Decoration, DecorationSet } from 'prosemirror-view';\nimport type { Node as PMNode } from 'prosemirror-model';\nimport { fromProseMirrorJSON, type JSONContent } from '../../compat/prosemirror';\nimport { analyzeJinjaBlocks } from '../../jinja/analyzer';\nimport type { ActionbookPlugin } from './types';\n\nconst jinjaPluginKey = new PluginKey('jinjaDecoration');\n\nconst JINJA_TAG_RE = /\\{%\\s*(if|elif|else|endif)\\s*([^%]*?)\\s*%\\}/g;\n\ninterface BlockPosInfo {\n index: number;\n from: number;\n to: number;\n}\n\nfunction getBlockPositions(doc: PMNode): BlockPosInfo[] {\n const blocks: BlockPosInfo[] = [];\n let index = 0;\n doc.forEach((node, offset) => {\n blocks.push({ index, from: offset, to: offset + node.nodeSize });\n index++;\n });\n return blocks;\n}\n\nfunction addInlineChipDecorations(doc: PMNode, decorations: Decoration[]) {\n doc.descendants((node, pos) => {\n if (!node.isText) return;\n const text = node.text!;\n JINJA_TAG_RE.lastIndex = 0;\n let match;\n while ((match = JINJA_TAG_RE.exec(text)) !== null) {\n const from = pos + match.index;\n const to = from + match[0].length;\n const keyword = match[1]; // if | elif | else | endif\n decorations.push(\n Decoration.inline(from, to, {\n class: `jinja-chip jinja-chip-${keyword}`,\n }),\n );\n }\n });\n}\n\nfunction addStructureBorderDecorations(\n doc: PMNode,\n blocks: BlockPosInfo[],\n decorations: Decoration[],\n) {\n const json = doc.toJSON() as JSONContent;\n let ast;\n try {\n ast = fromProseMirrorJSON(json);\n } catch {\n return;\n }\n\n const structures = analyzeJinjaBlocks(ast);\n\n for (const structure of structures) {\n // Build a map: blockIndex → branch type for every block in this structure\n // Tag lines (if/elif/else/endif) get the type of the branch they start\n // Content blocks get the type of their enclosing branch\n const blockBranchType = new Map<number, 'if' | 'elif' | 'else'>();\n\n for (const branch of structure.branches) {\n // The tag line itself\n blockBranchType.set(branch.tagBlockIndex, branch.type);\n // Content blocks under this branch\n for (let i = branch.blockStartIndex; i < branch.blockEndIndex; i++) {\n // Don't overwrite tag lines of subsequent branches\n if (!blockBranchType.has(i)) {\n blockBranchType.set(i, branch.type);\n }\n }\n }\n // endif tag line: use the last branch's type\n const lastBranch = structure.branches[structure.branches.length - 1];\n if (lastBranch && !blockBranchType.has(structure.endifTagBlockIndex)) {\n blockBranchType.set(structure.endifTagBlockIndex, lastBranch.type);\n }\n\n // Now emit decorations per contiguous run of same branch type\n const first = structure.ifTagBlockIndex;\n const last = structure.endifTagBlockIndex;\n\n for (let i = first; i <= last; i++) {\n const block = blocks[i];\n if (!block) continue;\n\n const branchType = blockBranchType.get(i) || 'if';\n const prevType = i > first ? blockBranchType.get(i - 1) : undefined;\n const nextType = i < last ? blockBranchType.get(i + 1) : undefined;\n\n const classes = ['jinja-bar', `jinja-bar-${branchType}`];\n // Segment boundaries: start/end of a contiguous same-color run\n if (i === first || prevType !== branchType) classes.push('jinja-bar-first');\n if (i === last || nextType !== branchType) classes.push('jinja-bar-last');\n\n decorations.push(Decoration.node(block.from, block.to, { class: classes.join(' ') }));\n }\n }\n}\n\nfunction buildDecorations(doc: PMNode): DecorationSet {\n const blocks = getBlockPositions(doc);\n const decorations: Decoration[] = [];\n\n addInlineChipDecorations(doc, decorations);\n addStructureBorderDecorations(doc, blocks, decorations);\n\n if (decorations.length === 0) return DecorationSet.empty;\n return DecorationSet.create(doc, decorations);\n}\n\nexport function createJinjaDecorationPlugin(): ActionbookPlugin {\n return {\n name: 'jinjaDecoration',\n plugins: () => [\n new Plugin({\n key: jinjaPluginKey,\n state: {\n init(_, state) {\n return buildDecorations(state.doc);\n },\n apply(tr, oldDecos) {\n if (!tr.docChanged) return oldDecos;\n return buildDecorations(tr.doc);\n },\n },\n props: {\n decorations(state) {\n return jinjaPluginKey.getState(state) as DecorationSet;\n },\n },\n }),\n ],\n };\n}\n","/**\n * Link editing plugin for the Actionbook editor.\n *\n * UX flow:\n * 1. `[aa](#aa)` is rendered as a clickable \"aa\" link mark.\n * 2. Pressing Backspace while cursor is inside or just after the link\n * \"explodes\" it to raw markdown `[aa](#aa)` for editing.\n * 3. While the cursor stays inside the raw text, normal editing applies.\n * 4. When the cursor leaves the raw region:\n * - If the text still matches `[label](href)` → reconverts to link mark.\n * - Otherwise → stays as plain text (user intentionally broke the link).\n * 5. Completing the markdown syntax by typing `)` triggers the input rule\n * and immediately converts to a link mark.\n */\n\nimport { InputRule, inputRules } from 'prosemirror-inputrules';\nimport { Plugin, PluginKey, TextSelection } from 'prosemirror-state';\nimport type { EditorState, Transaction } from 'prosemirror-state';\nimport type { Mark, MarkType, ResolvedPos } from 'prosemirror-model';\nimport type { ActionbookPlugin } from './types';\n\n// ── Regexes ──────────────────────────────────────────────────────────────────\n\n/** Matches a fully typed `[label](href)` or `[label](href \"title\")` at end of input. */\nconst LINK_INPUT_RE = /\\[([^\\]]*)\\]\\(([^)\\s]*?)(?:\\s+\"([^\"]*)\")?\\)$/;\n\n/**\n * Matches raw link text that spans the entire string.\n * Used to validate/reconvert after cursor leaves the raw editing region.\n */\nconst LINK_FULL_RE = /^\\[([^\\]]*)\\]\\(([^)\\s]*?)(?:\\s+\"([^\"]*)\")?\\)$/;\n\n// ── Plugin state ──────────────────────────────────────────────────────────────\n\ninterface LinkEditState {\n /** Absolute positions of the raw `[label](href)` text currently being edited. */\n rawRange: { from: number; to: number } | null;\n}\n\nconst linkEditKey = new PluginKey<LinkEditState>('linkEdit');\n\n// ── Utilities ─────────────────────────────────────────────────────────────────\n\n/**\n * Find the contiguous extent of a mark type around a resolved position.\n *\n * Handles `inclusive: false` marks (like `link`) correctly: when cursor is\n * placed just AFTER the mark text, the last node of the mark span is found\n * via `childBefore` and the full range is returned.\n */\nfunction getMarkRange(\n $pos: ResolvedPos,\n type: MarkType,\n): { from: number; to: number; mark: Mark } | null {\n const { parentOffset } = $pos;\n\n let child = $pos.parent.childAfter(parentOffset);\n\n // When cursor is exactly at a node boundary, also try the node ending here.\n if (parentOffset === child.offset && child.offset !== 0) {\n child = $pos.parent.childBefore(parentOffset);\n }\n\n if (!child.node) return null;\n\n const mark = child.node.marks.find((m) => m.type === type);\n if (!mark) return null;\n\n const parentStart = $pos.start();\n let { index: startIndex } = child;\n let startPos = parentStart + child.offset;\n let endIndex = startIndex + 1;\n let endPos = startPos + child.node.nodeSize;\n\n while (startIndex > 0 && mark.isInSet($pos.parent.child(startIndex - 1).marks)) {\n startIndex -= 1;\n startPos -= $pos.parent.child(startIndex).nodeSize;\n }\n\n while (\n endIndex < $pos.parent.childCount &&\n mark.isInSet($pos.parent.child(endIndex).marks)\n ) {\n endPos += $pos.parent.child(endIndex).nodeSize;\n endIndex += 1;\n }\n\n return { from: startPos, to: endPos, mark };\n}\n\n/**\n * Replace a link mark span with its raw markdown text `[label](href)`.\n *\n * Cursor placement after explosion: maps the cursor offset within the link\n * label to the same relative position in the raw text (adding 1 for the\n * leading `[`). For cursor at the end of the label, this positions just\n * before `]`, which is natural for continued editing.\n *\n * Returns `null` when the cursor is not at/inside a link mark.\n */\nfunction explodeLinkToRaw(state: EditorState): Transaction | null {\n const { selection, doc, schema } = state;\n if (!selection.empty) return null;\n\n const linkMarkType = schema.marks.link;\n if (!linkMarkType) return null;\n\n const $pos = doc.resolve(selection.from);\n const range = getMarkRange($pos, linkMarkType);\n if (!range) return null;\n\n const { from, to, mark } = range;\n const label = doc.textBetween(from, to);\n const { href, title } = mark.attrs as { href: string; title: string | null };\n const titlePart = title ? ` \"${title}\"` : '';\n const rawText = `[${label}](${href}${titlePart})`;\n\n // +1 for the leading `[`, clamped to label length\n const cursorOffset = Math.min(selection.from - from, label.length);\n const rawCursorOffset = cursorOffset + 1;\n\n const tr = state.tr;\n tr.replaceWith(from, to, schema.text(rawText));\n\n const newPos = Math.min(from + rawCursorOffset, tr.doc.content.size);\n tr.setSelection(TextSelection.near(tr.doc.resolve(newPos)));\n tr.setMeta(linkEditKey, { from, to: from + rawText.length });\n\n return tr;\n}\n\n// ── Auto-reconvert plugin ─────────────────────────────────────────────────────\n\n/**\n * Tracks the raw editing region after a link explosion and reconverts it back\n * to a link mark when the cursor moves outside that region.\n */\nfunction createLinkEditPlugin(): Plugin<LinkEditState> {\n return new Plugin<LinkEditState>({\n key: linkEditKey,\n\n state: {\n init: (): LinkEditState => ({ rawRange: null }),\n\n apply(tr, prev): LinkEditState {\n const meta = tr.getMeta(linkEditKey) as\n | { from: number; to: number }\n | null\n | undefined;\n\n if (meta !== undefined) return { rawRange: meta };\n\n if (prev.rawRange) {\n const from = tr.mapping.map(prev.rawRange.from);\n const to = tr.mapping.map(prev.rawRange.to);\n if (from >= to) return { rawRange: null };\n return { rawRange: { from, to } };\n }\n\n return prev;\n },\n },\n\n appendTransaction(_, __, newState) {\n const pluginState = linkEditKey.getState(newState);\n if (!pluginState?.rawRange) return null;\n\n const { from, to } = pluginState.rawRange;\n\n // Still inside — nothing to do\n if (newState.selection.anchor >= from && newState.selection.anchor <= to) {\n return null;\n }\n\n const docSize = newState.doc.content.size;\n const safeFrom = Math.min(from, docSize);\n const safeTo = Math.min(to, docSize);\n\n const reconvertTr = newState.tr;\n reconvertTr.setMeta(linkEditKey, null);\n\n if (safeFrom < safeTo) {\n const text = newState.doc.textBetween(safeFrom, safeTo);\n const match = LINK_FULL_RE.exec(text);\n\n if (match) {\n const [, label, href, title] = match;\n const linkMarkType = newState.schema.marks.link;\n\n if (linkMarkType && href) {\n const attrs = title ? { href, title: title.trim() } : { href };\n reconvertTr.delete(safeFrom, safeTo);\n if (label.length > 0) {\n reconvertTr.insertText(label, safeFrom);\n reconvertTr.addMark(\n safeFrom,\n safeFrom + label.length,\n linkMarkType.create(attrs),\n );\n }\n }\n }\n }\n\n return reconvertTr;\n },\n });\n}\n\n// ── Input rule ────────────────────────────────────────────────────────────────\n\n/**\n * When the user completes `[label](href)` by typing `)`, immediately convert\n * the matched text to a link mark. Works both for fresh typing and for\n * finalising an edited raw-exploded link.\n */\nfunction createLinkInputRule(): InputRule {\n return new InputRule(\n LINK_INPUT_RE,\n (state, match, start, end) => {\n const [, label, href, title] = match;\n const linkMarkType = state.schema.marks.link;\n if (!linkMarkType || !href) return null;\n\n const displayText = label || href;\n const attrs = title ? { href, title: title.trim() } : { href };\n const { tr } = state;\n\n tr.replaceWith(start, end, state.schema.text(displayText));\n tr.addMark(start, start + displayText.length, linkMarkType.create(attrs));\n tr.setMeta(linkEditKey, null);\n\n return tr;\n },\n );\n}\n\n// ── Click handler (anchor navigation) ────────────────────────────────────────\n\nfunction createLinkClickPlugin(): Plugin {\n return new Plugin({\n key: new PluginKey('linkClick'),\n props: {\n handleDOMEvents: {\n click: (_view, event) => {\n const target = event.target as HTMLElement;\n if (target.tagName !== 'A') return false;\n\n const href = (target as HTMLAnchorElement).getAttribute('href');\n if (!href) return false;\n\n // Internal jump-point links (#section) — scroll instead of navigate\n if (href.startsWith('#')) {\n event.preventDefault();\n const targetId = `jp-${href.slice(1)}`;\n const el = document.getElementById(targetId);\n if (el) {\n el.scrollIntoView({ block: 'end' });\n el.focus();\n if (el.parentElement) {\n el.parentElement.style.outline = '2px solid #6213cc';\n setTimeout(() => {\n (el.parentElement as HTMLElement).style.outline = 'none';\n }, 500);\n }\n }\n return true;\n }\n\n return false;\n },\n },\n },\n });\n}\n\n// ── Public factory ────────────────────────────────────────────────────────────\n\n/**\n * Creates the link editing `ActionbookPlugin`.\n *\n * Bundles:\n * - Backspace → explode to raw markdown\n * - `appendTransaction` auto-reconvert on cursor leave\n * - Input rule for `[label](href)` → link mark\n * - Click handler for internal `#anchor` links\n */\nexport function createLinkPlugin(): ActionbookPlugin {\n return {\n name: 'link',\n plugins: () => [\n createLinkEditPlugin(),\n createLinkClickPlugin(),\n inputRules({ rules: [createLinkInputRule()] }),\n ],\n keymap: () => ({\n Backspace: (state, dispatch) => {\n if (!state.selection.empty) return false;\n\n // Already in raw-edit mode — let normal Backspace through\n if (linkEditKey.getState(state)?.rawRange) return false;\n\n const tr = explodeLinkToRaw(state);\n if (!tr) return false;\n\n if (dispatch) dispatch(tr);\n return true;\n },\n }),\n };\n}\n","/**\n * Drag handle plugin v2 — enterprise-grade block reordering.\n *\n * Key improvements over v1:\n * - Diff-based handle updates (no full DOM rebuild per transaction)\n * - Pointer Events API (unified mouse/touch/pen)\n * - Auto-scroll during drag\n * - Keyboard accessibility (Alt+Arrow, ARIA)\n * - CSS custom properties for theming\n * - Proper style cleanup via adopted stylesheets / ref-count\n * - Class-based state management for testability\n */\nimport { Plugin, PluginKey } from 'prosemirror-state';\nimport type { EditorView } from 'prosemirror-view';\nimport type { Node as PMNode, ResolvedPos } from 'prosemirror-model';\nimport type { Transaction, EditorState, Command } from 'prosemirror-state';\nimport type { ActionbookPlugin } from './types';\n\n// ────────────────────────────────────────────────────────────\n// Constants\n// ────────────────────────────────────────────────────────────\n\nconst PLUGIN_KEY = new PluginKey('dragHandle');\n\nconst GRIP_SVG = `<svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"currentColor\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"4\" cy=\"2.5\" r=\"1.2\"/><circle cx=\"8\" cy=\"2.5\" r=\"1.2\"/>\n <circle cx=\"4\" cy=\"6\" r=\"1.2\"/><circle cx=\"8\" cy=\"6\" r=\"1.2\"/>\n <circle cx=\"4\" cy=\"9.5\" r=\"1.2\"/><circle cx=\"8\" cy=\"9.5\" r=\"1.2\"/>\n</svg>`;\n\nconst AUTO_SCROLL_ZONE = 40;\nconst AUTO_SCROLL_MAX_SPEED = 8;\nconst HANDLE_GAP = 4;\nexport const DRAG_THRESHOLD = 5;\n\n// ────────────────────────────────────────────────────────────\n// Styles (CSS custom properties for theming)\n// ────────────────────────────────────────────────────────────\n\nconst STYLES = /* css */ `\n.ab-drag-handle-layer {\n --ab-dh-color-idle: transparent;\n --ab-dh-color-hover: #c4c4c4;\n --ab-dh-color-visible: #8b8b8b;\n --ab-dh-color-accent: #6366f1;\n --ab-dh-bg-hover: rgba(0,0,0,0.04);\n --ab-dh-bg-active: rgba(99,102,241,0.08);\n --ab-dh-dragging-opacity: 0.4;\n --ab-dh-handle-size: 22px;\n --ab-dh-handle-radius: 4px;\n --ab-dh-transition-duration: 0.15s;\n\n position: absolute;\n top: 0; left: 0; right: 0; bottom: 0;\n pointer-events: none;\n overflow: visible;\n}\n.ab-drag-handle {\n position: absolute;\n width: var(--ab-dh-handle-size);\n height: var(--ab-dh-handle-size);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: grab;\n color: var(--ab-dh-color-idle);\n border-radius: var(--ab-dh-handle-radius);\n transition: color var(--ab-dh-transition-duration), background var(--ab-dh-transition-duration);\n user-select: none;\n pointer-events: auto;\n touch-action: none;\n}\n.ab-drag-handle-layer[data-hover] .ab-drag-handle {\n color: var(--ab-dh-color-hover);\n}\n.ab-drag-handle:hover {\n color: var(--ab-dh-color-visible) !important;\n background: var(--ab-dh-bg-hover);\n}\n.ab-drag-handle:active, .ab-drag-handle.dragging {\n cursor: grabbing;\n color: var(--ab-dh-color-accent) !important;\n background: var(--ab-dh-bg-active);\n}\n.ab-drop-indicator {\n position: absolute;\n left: 0; right: 0;\n height: 2px;\n background: var(--ab-dh-color-accent, #6366f1);\n border-radius: 1px;\n pointer-events: none;\n z-index: 20;\n transition: top 60ms ease-out;\n}\n.ab-block-dragging {\n opacity: var(--ab-dh-dragging-opacity, 0.4);\n}\n@keyframes ab-block-flash {\n from { background: rgba(99,102,241,0.12); }\n to { background: transparent; }\n}\n.ab-block-just-moved {\n animation: ab-block-flash 0.4s ease-out;\n}\n.ab-sr-only {\n position: absolute;\n width: 1px; height: 1px;\n padding: 0; margin: -1px;\n overflow: hidden;\n clip: rect(0,0,0,0);\n white-space: nowrap;\n border: 0;\n}\n`;\n\n// ────────────────────────────────────────────────────────────\n// Style Manager (ref-counted, leak-free)\n// ────────────────────────────────────────────────────────────\n\nclass StyleManager {\n private static refCount = 0;\n private static sheet: CSSStyleSheet | null = null;\n private static styleEl: HTMLStyleElement | null = null;\n\n static acquire(): void {\n if (this.refCount++ > 0) return;\n\n if (typeof CSSStyleSheet !== 'undefined' && 'replaceSync' in CSSStyleSheet.prototype) {\n this.sheet = new CSSStyleSheet();\n this.sheet.replaceSync(STYLES);\n document.adoptedStyleSheets = [...document.adoptedStyleSheets, this.sheet];\n } else {\n // Fallback for older browsers\n this.styleEl = document.createElement('style');\n this.styleEl.id = 'ab-drag-handle-styles';\n this.styleEl.textContent = STYLES;\n document.head.appendChild(this.styleEl);\n }\n }\n\n static release(): void {\n if (--this.refCount > 0) return;\n\n if (this.sheet) {\n document.adoptedStyleSheets = document.adoptedStyleSheets.filter(s => s !== this.sheet);\n this.sheet = null;\n }\n if (this.styleEl) {\n this.styleEl.remove();\n this.styleEl = null;\n }\n }\n}\n\n// ────────────────────────────────────────────────────────────\n// Types\n// ────────────────────────────────────────────────────────────\n\ninterface BlockInfo {\n offset: number;\n nodeSize: number;\n dom: HTMLElement;\n}\n\ninterface HandleEntry {\n el: HTMLElement;\n block: BlockInfo;\n topPx: number;\n listenerCleanup: () => void;\n}\n\ninterface DragState {\n fromIndex: number;\n handle: HTMLElement;\n blockDom: HTMLElement;\n dropTargetIndex: number;\n pointerY: number;\n pointerId: number;\n startX: number;\n startY: number;\n activated: boolean;\n}\n\n// ────────────────────────────────────────────────────────────\n// Pure helpers (exported for testing)\n// ────────────────────────────────────────────────────────────\n\n/**\n * Build a PM transaction that moves the top-level block at `fromIndex`\n * to `toIndex` (insert-before semantics: toIndex is counted in the\n * original ordering).\n *\n * Returns null if the move is a no-op or out of bounds.\n */\nexport function buildMoveTransaction(\n state: EditorState,\n fromIndex: number,\n toIndex: number,\n): Transaction | null {\n const { doc } = state;\n if (fromIndex === toIndex || fromIndex + 1 === toIndex) return null;\n if (fromIndex < 0 || fromIndex >= doc.childCount) return null;\n if (toIndex < 0 || toIndex > doc.childCount) return null;\n\n const node = doc.child(fromIndex);\n\n // Collect offsets of each top-level block\n const offsets: number[] = [];\n doc.forEach((_child, offset) => { offsets.push(offset); });\n\n const nodeStart = offsets[fromIndex];\n const nodeEnd = nodeStart + node.nodeSize;\n\n let tr = state.tr;\n\n if (toIndex > fromIndex) {\n // Moving down: insert first, then delete (keeps positions valid)\n const targetEnd = offsets[toIndex - 1] + doc.child(toIndex - 1).nodeSize;\n tr = tr.insert(targetEnd, node);\n tr = tr.delete(tr.mapping.map(nodeStart), tr.mapping.map(nodeEnd));\n } else {\n // Moving up: delete first, then insert\n const insertPos = offsets[toIndex];\n tr = tr.delete(nodeStart, nodeEnd);\n tr = tr.insert(tr.mapping.map(insertPos), node);\n }\n\n return tr;\n}\n\n/**\n * Given a list of block bounding rects (top/bottom relative to container),\n * determine which gap the pointer is closest to.\n * Returns an index in [0, blocks.length] (insert-before semantics).\n */\nexport function findDropTarget(\n blockRects: Array<{ top: number; bottom: number }>,\n pointerY: number,\n): number {\n if (blockRects.length === 0) return 0;\n\n let bestIndex = 0;\n let bestDist = Infinity;\n\n for (let i = 0; i <= blockRects.length; i++) {\n let gapY: number;\n if (i === 0) {\n gapY = blockRects[0].top;\n } else if (i === blockRects.length) {\n gapY = blockRects[blockRects.length - 1].bottom;\n } else {\n gapY = (blockRects[i - 1].bottom + blockRects[i].top) / 2;\n }\n const dist = Math.abs(pointerY - gapY);\n if (dist < bestDist) {\n bestDist = dist;\n bestIndex = i;\n }\n }\n\n return bestIndex;\n}\n\n/**\n * Compute auto-scroll speed based on pointer proximity to container edges.\n * Returns pixels-per-frame (negative = up, positive = down, 0 = no scroll).\n */\nexport function computeAutoScrollSpeed(\n pointerY: number,\n containerTop: number,\n containerBottom: number,\n): number {\n if (pointerY < containerTop + AUTO_SCROLL_ZONE) {\n const ratio = Math.max(0, (pointerY - containerTop) / AUTO_SCROLL_ZONE);\n return -AUTO_SCROLL_MAX_SPEED * (1 - ratio);\n }\n if (pointerY > containerBottom - AUTO_SCROLL_ZONE) {\n const ratio = Math.max(0, (containerBottom - pointerY) / AUTO_SCROLL_ZONE);\n return AUTO_SCROLL_MAX_SPEED * (1 - ratio);\n }\n return 0;\n}\n\n/**\n * Compare two block lists and return which indices need create/remove/reposition.\n * A block is \"same\" if its offset and nodeSize match.\n */\nexport function diffBlockList(\n prev: Array<{ offset: number; nodeSize: number }>,\n next: Array<{ offset: number; nodeSize: number }>,\n): { added: number[]; removed: number[]; kept: Array<{ prevIdx: number; nextIdx: number }> } {\n const prevMap = new Map<string, number>();\n prev.forEach((b, i) => prevMap.set(`${b.offset}:${b.nodeSize}`, i));\n\n const added: number[] = [];\n const kept: Array<{ prevIdx: number; nextIdx: number }> = [];\n const usedPrev = new Set<number>();\n\n next.forEach((b, i) => {\n const key = `${b.offset}:${b.nodeSize}`;\n const prevIdx = prevMap.get(key);\n if (prevIdx !== undefined && !usedPrev.has(prevIdx)) {\n kept.push({ prevIdx, nextIdx: i });\n usedPrev.add(prevIdx);\n } else {\n added.push(i);\n }\n });\n\n const removed: number[] = [];\n prev.forEach((_, i) => {\n if (!usedPrev.has(i)) removed.push(i);\n });\n\n return { added, removed, kept };\n}\n\n// ────────────────────────────────────────────────────────────\n// DragHandleController\n// ────────────────────────────────────────────────────────────\n\nclass DragHandleController {\n private view: EditorView;\n private layer: HTMLElement;\n private liveRegion: HTMLElement;\n private handles: HandleEntry[] = [];\n private prevBlocks: BlockInfo[] = [];\n private drag: DragState | null = null;\n private dropIndicator: HTMLElement | null = null;\n private scrollRAF: number | null = null;\n private updateRAF: number | null = null;\n private pendingUpdate = false;\n private scrollContainer: HTMLElement;\n private scrollSyncRAF: number | null = null;\n private resizeObserver: ResizeObserver | null = null;\n\n // Hover state\n private hoverBound: { enter: () => void; leave: () => void } | null = null;\n\n // Global fallback handlers active during drag\n private globalCleanup: (() => void) | null = null;\n\n constructor(view: EditorView) {\n this.view = view;\n StyleManager.acquire();\n\n const parent = view.dom.parentNode as HTMLElement;\n const pos = getComputedStyle(parent).position;\n if (pos === 'static' || pos === '') parent.style.position = 'relative';\n\n // Create overlay layer\n this.layer = document.createElement('div');\n this.layer.className = 'ab-drag-handle-layer';\n parent.insertBefore(this.layer, view.dom.nextSibling);\n\n // ARIA live region for announcements\n this.liveRegion = document.createElement('div');\n this.liveRegion.className = 'ab-sr-only';\n this.liveRegion.setAttribute('aria-live', 'assertive');\n this.liveRegion.setAttribute('aria-atomic', 'true');\n parent.appendChild(this.liveRegion);\n\n // Hover behavior: show handles on editor hover\n const onEnter = () => { this.layer.dataset.hover = '1'; };\n const onLeave = () => { if (!this.drag) delete this.layer.dataset.hover; };\n parent.addEventListener('mouseenter', onEnter);\n parent.addEventListener('mouseleave', onLeave);\n this.hoverBound = { enter: onEnter, leave: onLeave };\n\n // Find scroll container\n this.scrollContainer = this.findScrollContainer(view.dom);\n\n // Scroll listener — reposition handles when container scrolls\n this.scrollContainer.addEventListener('scroll', this.onScroll, { passive: true });\n\n // Resize observer — recompute when editor dimensions change\n this.resizeObserver = new ResizeObserver(() => this.scheduleUpdate());\n this.resizeObserver.observe(view.dom);\n\n // Initial render\n this.rebuildHandles();\n }\n\n update(view: EditorView, prevState: EditorState): void {\n this.view = view;\n\n // Skip updates during drag — flush when drag ends\n if (this.drag) {\n this.pendingUpdate = true;\n return;\n }\n\n // Only recompute when doc structure changes\n if (!view.state.doc.eq(prevState.doc)) {\n this.scheduleUpdate();\n }\n }\n\n destroy(): void {\n this.cancelDrag();\n\n if (this.updateRAF !== null) cancelAnimationFrame(this.updateRAF);\n if (this.scrollSyncRAF !== null) cancelAnimationFrame(this.scrollSyncRAF);\n this.scrollContainer.removeEventListener('scroll', this.onScroll);\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n\n // Remove handles and their listeners\n for (const h of this.handles) {\n h.listenerCleanup();\n h.el.remove();\n }\n this.handles = [];\n\n // Remove hover listeners\n if (this.hoverBound) {\n const parent = this.view.dom.parentNode as HTMLElement | null;\n if (parent) {\n parent.removeEventListener('mouseenter', this.hoverBound.enter);\n parent.removeEventListener('mouseleave', this.hoverBound.leave);\n }\n }\n\n this.liveRegion.remove();\n this.layer.remove();\n StyleManager.release();\n }\n\n // ── Private: update pipeline ──\n\n private scheduleUpdate(): void {\n if (this.updateRAF !== null) return;\n this.updateRAF = requestAnimationFrame(() => {\n this.updateRAF = null;\n this.rebuildHandles();\n });\n }\n\n private onScroll = (): void => {\n if (this.scrollSyncRAF !== null) return;\n this.scrollSyncRAF = requestAnimationFrame(() => {\n this.scrollSyncRAF = null;\n if (!this.drag) this.syncHandlePositions();\n });\n };\n\n private collectBlocks(): BlockInfo[] {\n const blocks: BlockInfo[] = [];\n\n this.view.state.doc.forEach((node, offset) => {\n // nodeDOM returns the outermost DOM node for the block at this offset.\n // This is more reliable than domAtPos(offset + 1) which can resolve to\n // the wrong element for leaf blocks (e.g. horizontalRule with nodeSize=1).\n const dom = this.view.nodeDOM(offset);\n if (dom instanceof HTMLElement) {\n blocks.push({ offset, nodeSize: node.nodeSize, dom });\n }\n });\n\n return blocks;\n }\n\n private rebuildHandles(): void {\n const newBlocks = this.collectBlocks();\n const diff = diffBlockList(\n this.prevBlocks.map(b => ({ offset: b.offset, nodeSize: b.nodeSize })),\n newBlocks.map(b => ({ offset: b.offset, nodeSize: b.nodeSize })),\n );\n\n const parent = this.view.dom.parentNode as HTMLElement;\n const parentRect = parent.getBoundingClientRect();\n const editorRect = this.view.dom.getBoundingClientRect();\n const handleSize = parseInt(getComputedStyle(this.layer).getPropertyValue('--ab-dh-handle-size') || '22', 10);\n const handleLeft = editorRect.left - parentRect.left - handleSize - HANDLE_GAP;\n\n // Build new handles array preserving kept entries\n const newHandles: HandleEntry[] = new Array(newBlocks.length);\n\n // Reuse kept handles (reposition if needed)\n for (const { prevIdx, nextIdx } of diff.kept) {\n const entry = this.handles[prevIdx];\n entry.block = newBlocks[nextIdx];\n const blockRect = entry.block.dom.getBoundingClientRect();\n const lineHeight = parseFloat(getComputedStyle(entry.block.dom).lineHeight) || 24;\n const verticalOffset = Math.max(0, (lineHeight - handleSize) / 2);\n const topPx = blockRect.top - parentRect.top + parent.scrollTop + verticalOffset;\n entry.topPx = topPx;\n entry.el.style.top = `${topPx}px`;\n entry.el.style.left = `${handleLeft}px`;\n // Update the index in the pointerdown closure\n this.rebindHandleIndex(entry, nextIdx);\n newHandles[nextIdx] = entry;\n }\n\n // Remove obsolete handles\n for (const idx of diff.removed) {\n const entry = this.handles[idx];\n entry.listenerCleanup();\n entry.el.remove();\n }\n\n // Create new handles\n for (const idx of diff.added) {\n const block = newBlocks[idx];\n const blockRect = block.dom.getBoundingClientRect();\n const lineHeight = parseFloat(getComputedStyle(block.dom).lineHeight) || 24;\n const verticalOffset = Math.max(0, (lineHeight - handleSize) / 2);\n const topPx = blockRect.top - parentRect.top + parent.scrollTop + verticalOffset;\n\n const el = document.createElement('div');\n el.className = 'ab-drag-handle';\n el.setAttribute('data-ab-float', '');\n el.setAttribute('role', 'button');\n el.setAttribute('aria-roledescription', 'drag handle');\n el.setAttribute('aria-label', `블록 ${idx + 1} 이동`);\n el.setAttribute('tabindex', '-1');\n el.innerHTML = GRIP_SVG;\n el.style.left = `${handleLeft}px`;\n el.style.top = `${topPx}px`;\n this.layer.appendChild(el);\n\n const cleanup = this.bindHandleEvents(el, idx);\n newHandles[idx] = { el, block, topPx, listenerCleanup: cleanup };\n }\n\n this.handles = newHandles;\n this.prevBlocks = newBlocks;\n }\n\n private bindHandleEvents(el: HTMLElement, index: number): () => void {\n let currentIndex = index;\n const onPointerDown = (e: PointerEvent) => {\n e.preventDefault();\n if (!this.view.editable) return;\n el.setPointerCapture(e.pointerId);\n // Re-collect block positions at drag start for accuracy\n this.prevBlocks = this.collectBlocks();\n this.syncHandlePositions();\n this.startDrag(currentIndex, el, e);\n };\n const onPointerMove = (e: PointerEvent) => this.onPointerMove(e);\n const onPointerUp = (e: PointerEvent) => this.onPointerUp(e);\n const onLostCapture = () => this.cancelDrag();\n\n const onPointerCancel = () => this.cancelDrag();\n\n el.addEventListener('pointerdown', onPointerDown);\n el.addEventListener('pointermove', onPointerMove);\n el.addEventListener('pointerup', onPointerUp);\n el.addEventListener('pointercancel', onPointerCancel);\n el.addEventListener('lostpointercapture', onLostCapture);\n\n const cleanup = () => {\n el.removeEventListener('pointerdown', onPointerDown);\n el.removeEventListener('pointermove', onPointerMove);\n el.removeEventListener('pointerup', onPointerUp);\n el.removeEventListener('pointercancel', onPointerCancel);\n el.removeEventListener('lostpointercapture', onLostCapture);\n };\n\n // Expose a way to update the captured index\n (el as any).__abUpdateIndex = (newIdx: number) => { currentIndex = newIdx; };\n\n return cleanup;\n }\n\n private rebindHandleIndex(entry: HandleEntry, newIndex: number): void {\n const fn = (entry.el as any).__abUpdateIndex;\n if (fn) fn(newIndex);\n entry.el.setAttribute('aria-label', `블록 ${newIndex + 1} 이동`);\n }\n\n private syncHandlePositions(): void {\n const parent = this.view.dom.parentNode as HTMLElement;\n const parentRect = parent.getBoundingClientRect();\n const editorRect = this.view.dom.getBoundingClientRect();\n const handleSize = parseInt(getComputedStyle(this.layer).getPropertyValue('--ab-dh-handle-size') || '22', 10);\n const handleLeft = editorRect.left - parentRect.left - handleSize - HANDLE_GAP;\n\n for (const entry of this.handles) {\n if (!entry) continue;\n const blockRect = entry.block.dom.getBoundingClientRect();\n const lineHeight = parseFloat(getComputedStyle(entry.block.dom).lineHeight) || 24;\n const verticalOffset = Math.max(0, (lineHeight - handleSize) / 2);\n const topPx = blockRect.top - parentRect.top + parent.scrollTop + verticalOffset;\n entry.topPx = topPx;\n entry.el.style.top = `${topPx}px`;\n entry.el.style.left = `${handleLeft}px`;\n }\n }\n\n // ── Private: drag lifecycle ──\n\n private startDrag(index: number, handle: HTMLElement, e: PointerEvent): void {\n const block = this.prevBlocks[index];\n if (!block) return;\n\n // Guard: clean up any existing drag first (e.g. multi-touch edge case)\n if (this.drag) {\n this.cleanupDragState();\n }\n\n this.drag = {\n fromIndex: index,\n handle,\n blockDom: block.dom,\n dropTargetIndex: index,\n pointerY: e.clientY,\n pointerId: e.pointerId,\n startX: e.clientX,\n startY: e.clientY,\n activated: false,\n };\n\n // Global fallback handlers: catch pointerup/pointercancel even when\n // pointer capture is lost or events don't reach the handle element\n this.addGlobalDragListeners(e.pointerId);\n }\n\n private activateDrag(): void {\n if (!this.drag) return;\n\n this.drag.activated = true;\n this.drag.handle.classList.add('dragging');\n this.drag.blockDom.classList.add('ab-block-dragging');\n\n // Create drop indicator\n const parent = this.view.dom.parentNode as HTMLElement;\n this.dropIndicator = document.createElement('div');\n this.dropIndicator.className = 'ab-drop-indicator';\n this.dropIndicator.style.display = 'none';\n parent.appendChild(this.dropIndicator);\n\n // Start auto-scroll loop\n this.tickAutoScroll();\n }\n\n private addGlobalDragListeners(pointerId: number): void {\n const onDocPointerUp = (e: PointerEvent) => {\n if (e.pointerId === pointerId) this.onPointerUp(e);\n };\n const onDocPointerCancel = (e: PointerEvent) => {\n if (e.pointerId === pointerId) this.cancelDrag();\n };\n const onVisibilityChange = () => {\n if (document.visibilityState === 'hidden') this.cancelDrag();\n };\n\n document.addEventListener('pointerup', onDocPointerUp);\n document.addEventListener('pointercancel', onDocPointerCancel);\n document.addEventListener('visibilitychange', onVisibilityChange);\n\n this.globalCleanup = () => {\n document.removeEventListener('pointerup', onDocPointerUp);\n document.removeEventListener('pointercancel', onDocPointerCancel);\n document.removeEventListener('visibilitychange', onVisibilityChange);\n };\n }\n\n private onPointerMove(e: PointerEvent): void {\n if (!this.drag || e.pointerId !== this.drag.pointerId) return;\n if (!this.view.editable) { this.cancelDrag(); return; }\n\n // Threshold check — only activate drag after moving 5px\n if (!this.drag.activated) {\n const dx = e.clientX - this.drag.startX;\n const dy = e.clientY - this.drag.startY;\n if (dx * dx + dy * dy < DRAG_THRESHOLD * DRAG_THRESHOLD) return;\n this.activateDrag();\n }\n\n this.drag.pointerY = e.clientY;\n this.updateDropTarget();\n }\n\n private updateDropTarget(): void {\n if (!this.drag || !this.dropIndicator) return;\n\n const parent = this.view.dom.parentNode as HTMLElement;\n const parentRect = parent.getBoundingClientRect();\n const editorRect = this.view.dom.getBoundingClientRect();\n\n // Build block rects relative to viewport\n const blockRects = this.prevBlocks.map(b => {\n const r = b.dom.getBoundingClientRect();\n return { top: r.top, bottom: r.bottom };\n });\n\n const targetIndex = findDropTarget(blockRects, this.drag.pointerY);\n this.drag.dropTargetIndex = targetIndex;\n\n // Compute indicator position\n let indicatorY: number;\n if (targetIndex === 0) {\n indicatorY = (blockRects[0]?.top ?? parentRect.top) - parentRect.top + parent.scrollTop - 1;\n } else if (targetIndex >= blockRects.length) {\n const last = blockRects[blockRects.length - 1];\n indicatorY = (last?.bottom ?? parentRect.bottom) - parentRect.top + parent.scrollTop + 1;\n } else {\n const above = blockRects[targetIndex - 1].bottom;\n const below = blockRects[targetIndex].top;\n indicatorY = ((above + below) / 2) - parentRect.top + parent.scrollTop;\n }\n\n // Hide when drop position equals source (no-op)\n const isSamePos = targetIndex === this.drag.fromIndex || targetIndex === this.drag.fromIndex + 1;\n this.dropIndicator.style.display = isSamePos ? 'none' : '';\n this.dropIndicator.style.top = `${indicatorY}px`;\n this.dropIndicator.style.left = `${editorRect.left - parentRect.left}px`;\n this.dropIndicator.style.width = `${editorRect.width}px`;\n }\n\n private onPointerUp(e: PointerEvent): void {\n if (!this.drag || e.pointerId !== this.drag.pointerId) return;\n\n // If threshold was never met, cancel without moving\n if (!this.drag.activated) {\n this.cleanupDragState();\n if (this.pendingUpdate) {\n this.pendingUpdate = false;\n this.scheduleUpdate();\n }\n return;\n }\n\n const fromIndex = this.drag.fromIndex;\n const toIndex = this.drag.dropTargetIndex;\n\n this.cleanupDragState();\n\n // Execute the move\n if (fromIndex !== toIndex && fromIndex + 1 !== toIndex) {\n const tr = buildMoveTransaction(this.view.state, fromIndex, toIndex);\n if (tr) {\n this.view.dispatch(tr.scrollIntoView());\n this.view.focus();\n this.flashMovedBlock(toIndex > fromIndex ? toIndex - 1 : toIndex);\n this.announce(`블록이 위치 ${(toIndex > fromIndex ? toIndex : toIndex + 1)}(으)로 이동됨`);\n }\n }\n\n // Flush pending update\n if (this.pendingUpdate) {\n this.pendingUpdate = false;\n this.scheduleUpdate();\n }\n }\n\n cancelDrag(): void {\n if (!this.drag) return;\n this.cleanupDragState();\n\n if (this.pendingUpdate) {\n this.pendingUpdate = false;\n this.scheduleUpdate();\n }\n }\n\n private cleaningUp = false;\n\n private cleanupDragState(): void {\n if (!this.drag || this.cleaningUp) return;\n this.cleaningUp = true;\n\n this.drag.handle.classList.remove('dragging');\n this.drag.blockDom.classList.remove('ab-block-dragging');\n\n // Try to release pointer capture (may already be released).\n // releasePointerCapture can fire lostpointercapture synchronously,\n // so the cleaningUp guard prevents re-entrant calls.\n try {\n this.drag.handle.releasePointerCapture(this.drag.pointerId);\n } catch { /* already released */ }\n\n this.dropIndicator?.remove();\n this.dropIndicator = null;\n\n // Remove global fallback listeners\n if (this.globalCleanup) {\n this.globalCleanup();\n this.globalCleanup = null;\n }\n\n if (this.scrollRAF !== null) {\n cancelAnimationFrame(this.scrollRAF);\n this.scrollRAF = null;\n }\n\n this.drag = null;\n this.cleaningUp = false;\n // Restore hover state based on actual pointer position\n delete this.layer.dataset.hover;\n }\n\n // ── Private: auto-scroll ──\n\n private tickAutoScroll(): void {\n if (!this.drag) return;\n\n const rect = this.scrollContainer.getBoundingClientRect();\n const speed = computeAutoScrollSpeed(this.drag.pointerY, rect.top, rect.bottom);\n\n if (speed !== 0) {\n this.scrollContainer.scrollBy(0, speed);\n this.syncHandlePositions();\n this.updateDropTarget();\n }\n\n this.scrollRAF = requestAnimationFrame(() => this.tickAutoScroll());\n }\n\n private findScrollContainer(el: HTMLElement): HTMLElement {\n let current = el.parentElement;\n while (current) {\n const overflow = getComputedStyle(current).overflowY;\n if (overflow === 'auto' || overflow === 'scroll') return current;\n current = current.parentElement;\n }\n return el.parentElement ?? el;\n }\n\n // ── Private: feedback ──\n\n private flashMovedBlock(blockIndex: number): void {\n // Re-collect after transaction so we get the new DOM\n requestAnimationFrame(() => {\n const blocks = this.collectBlocks();\n const block = blocks[blockIndex];\n if (!block) return;\n block.dom.classList.add('ab-block-just-moved');\n const onEnd = () => {\n block.dom.classList.remove('ab-block-just-moved');\n block.dom.removeEventListener('animationend', onEnd);\n };\n block.dom.addEventListener('animationend', onEnd);\n });\n }\n\n private announce(message: string): void {\n this.liveRegion.textContent = '';\n // Force screen reader to re-read by clearing then setting\n requestAnimationFrame(() => {\n this.liveRegion.textContent = message;\n });\n }\n}\n\n// ────────────────────────────────────────────────────────────\n// Keyboard commands\n// ────────────────────────────────────────────────────────────\n\nfunction moveBlockCommand(direction: -1 | 1): Command {\n return (state, dispatch) => {\n const $from = state.selection.$from;\n // Resolve to top-level block\n const blockIndex = $from.index(0);\n const toIndex = direction === -1 ? blockIndex - 1 : blockIndex + 2;\n\n if (toIndex < 0 || toIndex > state.doc.childCount) return false;\n\n if (dispatch) {\n const tr = buildMoveTransaction(state, blockIndex, toIndex);\n if (tr) {\n dispatch(tr.scrollIntoView());\n } else {\n return false;\n }\n }\n return true;\n };\n}\n\n// ────────────────────────────────────────────────────────────\n// Plugin factory (public API — unchanged signature)\n// ────────────────────────────────────────────────────────────\n\nexport function createDragHandlePlugin(): ActionbookPlugin {\n return {\n name: 'dragHandle',\n\n plugins: () => {\n let controller: DragHandleController | null = null;\n\n return [\n new Plugin({\n key: PLUGIN_KEY,\n view(editorView) {\n controller = new DragHandleController(editorView);\n return {\n update(view, prevState) {\n controller?.update(view, prevState);\n },\n destroy() {\n controller?.destroy();\n controller = null;\n },\n };\n },\n }),\n ];\n },\n\n keymap: () => ({\n 'Alt-ArrowUp': moveBlockCommand(-1),\n 'Alt-ArrowDown': moveBlockCommand(1),\n }),\n };\n}\n","/**\n * NodeView plugin for todo/checkbox list items.\n * Renders a clickable checkbox when listItem.attrs.checked !== null.\n */\nimport React from 'react';\nimport type { NodeView, EditorView } from 'prosemirror-view';\nimport type { Node as PMNode } from 'prosemirror-model';\nimport type { ActionbookPlugin, NodeViewFactory } from './types';\n\nfunction createCheckboxDOM(checked: boolean): HTMLElement {\n const el = document.createElement('span');\n el.contentEditable = 'false';\n el.style.cssText = `\n display: inline-flex; align-items: center; justify-content: center;\n width: 18px; height: 18px; margin-right: 6px;\n cursor: pointer; border-radius: 4px;\n user-select: none; flex-shrink: 0; vertical-align: middle;\n position: relative; top: -1px; font-size: 12px; font-weight: 700;\n ${checked\n ? 'background: #6366f1; color: #fff; border: none;'\n : 'background: transparent; color: transparent; border: 2px solid #d1d5db;'\n }\n `;\n el.textContent = checked ? '✓' : '';\n return el;\n}\n\nclass TodoListItemView implements NodeView {\n dom: HTMLElement;\n contentDOM: HTMLElement;\n private checkbox: HTMLElement;\n\n constructor(\n private node: PMNode,\n private view: EditorView,\n private getPos: () => number | undefined,\n ) {\n const checked = node.attrs.checked as boolean;\n\n this.dom = document.createElement('li');\n this.dom.className = 'todo-item';\n this.dom.dataset.checked = String(checked);\n this.dom.style.display = 'flex';\n this.dom.style.alignItems = 'flex-start';\n\n this.checkbox = createCheckboxDOM(checked);\n this.checkbox.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n const pos = this.getPos();\n if (pos == null) return;\n this.view.dispatch(\n this.view.state.tr.setNodeMarkup(pos, undefined, {\n ...this.node.attrs,\n checked: !this.node.attrs.checked,\n }),\n );\n });\n\n this.contentDOM = document.createElement('div');\n this.contentDOM.style.flex = '1';\n if (checked) {\n this.contentDOM.style.textDecoration = 'line-through';\n this.contentDOM.style.opacity = '0.6';\n }\n\n this.dom.appendChild(this.checkbox);\n this.dom.appendChild(this.contentDOM);\n }\n\n update(node: PMNode): boolean {\n if (node.type !== this.node.type) return false;\n // If checked changed from/to null, refuse update (different rendering)\n if ((node.attrs.checked == null) !== (this.node.attrs.checked == null)) return false;\n if (node.attrs.checked == null) return false;\n\n this.node = node;\n const checked = node.attrs.checked as boolean;\n this.dom.dataset.checked = String(checked);\n\n // Update checkbox\n const newCb = createCheckboxDOM(checked);\n newCb.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n const pos = this.getPos();\n if (pos == null) return;\n this.view.dispatch(\n this.view.state.tr.setNodeMarkup(pos, undefined, {\n ...this.node.attrs,\n checked: !this.node.attrs.checked,\n }),\n );\n });\n this.dom.replaceChild(newCb, this.checkbox);\n this.checkbox = newCb;\n\n // Update content styling\n if (checked) {\n this.contentDOM.style.textDecoration = 'line-through';\n this.contentDOM.style.opacity = '0.6';\n } else {\n this.contentDOM.style.textDecoration = '';\n this.contentDOM.style.opacity = '';\n }\n\n return true;\n }\n}\n\nexport function createTodoNodeViewPlugin(): ActionbookPlugin {\n return {\n name: 'todoNodeView',\n nodeViews: () => ({\n listItem: ((node: PMNode, view: EditorView, getPos: () => number | undefined): NodeView => {\n // Only use custom node view for todo items (checked !== null)\n if (node.attrs.checked == null) {\n // Return default node view\n const li = document.createElement('li');\n return { dom: li, contentDOM: li };\n }\n return new TodoListItemView(node, view, getPos);\n }) as NodeViewFactory,\n }),\n };\n}\n","/**\n * Slash-command trigger plugin.\n *\n * Tracks whether the cursor is inside a `/query` pattern and exposes the\n * active range + query string via `slashCommandKey` so that the\n * `SlashCommandMenu` React component can read it and render the popup.\n *\n * The plugin also handles:\n * - Escape → dismisses the menu (sets dismissed state so the same `/`\n * position doesn't re-trigger until the user moves away and types `/` again)\n * - ArrowUp / ArrowDown / Enter → consumed by the React component through\n * a capture-phase keydown listener; the plugin just marks them as handled\n * when the menu is active so ProseMirror doesn't move the cursor.\n */\n\nimport { Plugin, PluginKey } from 'prosemirror-state';\nimport type { EditorState, Transaction } from 'prosemirror-state';\nimport type { ActionbookPlugin } from './types';\n\n// ── Public types ──────────────────────────────────────────\n\nexport interface SlashCommandState {\n /** Whether a slash trigger is currently active. */\n active: boolean;\n /** Document positions of the full `/query` text (inclusive). */\n range: { from: number; to: number } | null;\n /** Text typed after `/`, not including the slash itself. */\n query: string;\n}\n\n// ── Plugin key (exported so SlashCommandMenu can read state) ──\n\nexport const slashCommandKey = new PluginKey<SlashCommandState>('slashCommand');\n\n// ── Internal helpers ──────────────────────────────────────\n\n/**\n * Regex matching `/` followed by zero-or-more non-whitespace chars at the\n * end of the current paragraph text up to the cursor.\n *\n * Allows the trigger at the very start of the line or after whitespace,\n * but not inside a word (e.g. `foo/bar` should NOT trigger).\n */\nconst TRIGGER_RE = /(?:^|\\s)(\\/[^\\s]*)$/;\n\n/** Derive slash-command state purely from editor state + dismissed position. */\nfunction deriveState(\n state: EditorState,\n dismissedFrom: number | null,\n): SlashCommandState {\n const { selection } = state;\n if (!selection.empty) return { active: false, range: null, query: '' };\n\n const { $from } = selection;\n // Only trigger in paragraph-like blocks (not headings etc.)\n const parentType = $from.parent.type.name;\n if (parentType === 'heading') return { active: false, range: null, query: '' };\n\n const textBefore = $from.parent.textBetween(0, $from.parentOffset, '\\n', '\\0');\n const match = TRIGGER_RE.exec(textBefore);\n if (!match) return { active: false, range: null, query: '' };\n\n const slashText = match[1]; // e.g. '/foo'\n const slashStartInParent = textBefore.lastIndexOf(slashText);\n const from = $from.start() + slashStartInParent;\n const to = $from.pos;\n\n // If the user dismissed at this exact slash position, stay inactive\n if (dismissedFrom === from) return { active: false, range: null, query: '' };\n\n return {\n active: true,\n range: { from, to },\n query: slashText.slice(1),\n };\n}\n\n// ── Meta shape ────────────────────────────────────────────\n\ninterface SlashMeta {\n /** Position of the slash that was dismissed (Escape key). */\n dismiss?: number;\n}\n\n// ── Internal plugin state (extends public state with dismiss tracking) ──\n\ninterface InternalState extends SlashCommandState {\n _dismissedFrom: number | null;\n}\n\n// ── Factory ───────────────────────────────────────────────\n\nexport function createSlashCommandPlugin(): ActionbookPlugin {\n const plugin = new Plugin<InternalState>({\n key: slashCommandKey as unknown as PluginKey<InternalState>,\n\n state: {\n init(_, state): InternalState {\n const derived = deriveState(state, null);\n return { ...derived, _dismissedFrom: null };\n },\n\n apply(tr: Transaction, prev: InternalState, _old, newState: EditorState): InternalState {\n const meta = tr.getMeta(slashCommandKey) as SlashMeta | undefined;\n\n let dismissedFrom = prev._dismissedFrom;\n\n if (meta?.dismiss !== undefined) {\n dismissedFrom = meta.dismiss;\n } else if (dismissedFrom !== null) {\n // Clear dismiss if the user typed a new `/` somewhere else\n const derived = deriveState(newState, null);\n if (derived.active && derived.range && derived.range.from !== dismissedFrom) {\n dismissedFrom = null;\n }\n }\n\n const derived = deriveState(newState, dismissedFrom);\n return { ...derived, _dismissedFrom: dismissedFrom };\n },\n },\n\n // Expose only the public fields via the key\n // (InternalState is a superset of SlashCommandState so reads work fine)\n });\n\n return {\n name: 'slashCommand',\n plugins: () => [plugin],\n\n keymap: () => ({\n Escape: (state, dispatch) => {\n const s = slashCommandKey.getState(state) as InternalState | undefined;\n if (!s?.active || !s.range) return false;\n\n // Dismiss: store the slash position so it won't re-trigger\n if (dispatch) {\n const tr = state.tr;\n tr.setMeta(slashCommandKey, { dismiss: s.range.from } satisfies SlashMeta);\n dispatch(tr);\n }\n return true;\n },\n }),\n };\n}\n","/**\n * SlashCommandMenu — injectable floating slash-command picker.\n *\n * Usage:\n * ```tsx\n * // Define items (inject from outside)\n * const items: SlashCommandItem[] = [\n * {\n * id: 'heading1',\n * title: 'Heading 1',\n * description: 'Large section heading',\n * icon: <span>H1</span>,\n * command({ view, range }) {\n * const { state, dispatch } = view;\n * const tr = state.tr.delete(range.from, range.to);\n * setBlockType(heading, { level: 1 })(\n * state.apply(tr),\n * (newTr) => dispatch(tr.steps.length ? tr : newTr),\n * );\n * },\n * },\n * ];\n *\n * // In your editor component:\n * const [editorState, setEditorState] = useState<EditorState | null>(null);\n * const handle = useEditorView({ ..., onTransaction: setEditorState });\n *\n * return (\n * <>\n * <EditorShell ref={handle.viewRef} />\n * <SlashCommandMenu\n * view={handle.view}\n * editorState={editorState}\n * items={items}\n * />\n * </>\n * );\n * ```\n *\n * The `command` callback receives the editor view and the range of the\n * `/query` trigger text. It is responsible for deleting the trigger and\n * inserting whatever content it wants.\n */\n\nimport React, { useEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport type { EditorView } from 'prosemirror-view';\nimport type { EditorState } from 'prosemirror-state';\nimport { slashCommandKey } from '../plugin/slashCommandPlugin';\nimport type { SlashCommandState } from '../plugin/slashCommandPlugin';\n\n// ── Public types ──────────────────────────────────────────\n\nexport interface SlashCommandItem {\n /** Unique key; falls back to `title` if omitted. */\n id?: string;\n title: string;\n description?: string;\n /** Optional icon node rendered to the left of the title. */\n icon?: React.ReactNode;\n /**\n * Execute this command.\n *\n * @param view - Live EditorView; use `view.state` / `view.dispatch`.\n * @param range - Positions of the full `/query` text in the document.\n * Delete this range before inserting your content.\n */\n command: (props: { view: EditorView; range: { from: number; to: number } }) => void;\n}\n\nexport interface SlashCommandMenuProps {\n view: EditorView | null;\n editorState: EditorState | null;\n /** Full item list. Filtered by the current query automatically. */\n items: SlashCommandItem[];\n}\n\n// ── Filtering ─────────────────────────────────────────────\n\nfunction filterItems(items: SlashCommandItem[], query: string): SlashCommandItem[] {\n if (!query) return items;\n const q = query.toLowerCase();\n return items.filter(\n ({ title, description }) =>\n title.toLowerCase().includes(q) ||\n (description?.toLowerCase().includes(q) ?? false),\n );\n}\n\n// ── Shared styles ─────────────────────────────────────────\n\nconst POPUP_SHADOW =\n '0 0 0 1px rgba(0,0,0,0.07), 0 4px 20px rgba(0,0,0,0.11), 0 1px 4px rgba(0,0,0,0.05)';\n\nconst BTN_RESET: React.CSSProperties = {\n border: 'none',\n padding: 0,\n margin: 0,\n background: 'transparent',\n fontFamily: 'inherit',\n cursor: 'pointer',\n lineHeight: 1,\n textAlign: 'left',\n width: '100%',\n};\n\nconst VPORT_MARGIN = 8;\nconst MENU_WIDTH = 280;\nconst MAX_MENU_H = 320;\n\n// ── Menu component ────────────────────────────────────────\n\nexport function SlashCommandMenu({ view, editorState, items }: SlashCommandMenuProps) {\n const [selectedIndex, setSelectedIndex] = useState(0);\n const listRef = useRef<HTMLDivElement>(null);\n\n // Read plugin state\n const pluginState = editorState\n ? (slashCommandKey.getState(editorState) as SlashCommandState | undefined)\n : undefined;\n\n const active = pluginState?.active ?? false;\n const range = pluginState?.range ?? null;\n const query = pluginState?.query ?? '';\n\n const filtered = filterItems(items, query);\n\n // Reset selection when query or active state changes\n useEffect(() => {\n setSelectedIndex(0);\n }, [query, active]);\n\n // Scroll selected item into view\n useEffect(() => {\n const list = listRef.current;\n if (!list) return;\n const item = list.children[selectedIndex] as HTMLElement | undefined;\n item?.scrollIntoView({ block: 'nearest' });\n }, [selectedIndex]);\n\n // Keyboard handler — captures Arrow/Enter before ProseMirror sees them\n useEffect(() => {\n if (!active || !view) return;\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n e.stopPropagation();\n setSelectedIndex((i) => Math.min(i + 1, filtered.length - 1));\n return;\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n e.stopPropagation();\n setSelectedIndex((i) => Math.max(i - 1, 0));\n return;\n }\n if (e.key === 'Enter') {\n e.preventDefault();\n e.stopPropagation();\n if (filtered[selectedIndex] && range) {\n filtered[selectedIndex].command({ view, range });\n view.focus();\n }\n }\n };\n\n document.addEventListener('keydown', onKeyDown, true);\n return () => document.removeEventListener('keydown', onKeyDown, true);\n }, [active, view, filtered, selectedIndex, range]);\n\n if (!active || !view || !range) return null;\n\n // Position below the slash trigger character\n const coords = view.coordsAtPos(range.from);\n let top = coords.bottom + 4;\n let left = coords.left;\n\n // Clamp to viewport\n left = Math.max(VPORT_MARGIN, Math.min(left, window.innerWidth - MENU_WIDTH - VPORT_MARGIN));\n if (top + MAX_MENU_H > window.innerHeight - VPORT_MARGIN) {\n top = coords.top - MAX_MENU_H - 4;\n }\n\n return createPortal(\n <div\n style={{\n position: 'fixed',\n top,\n left,\n width: MENU_WIDTH,\n maxHeight: MAX_MENU_H,\n overflowY: 'auto',\n background: '#fff',\n borderRadius: 10,\n boxShadow: POPUP_SHADOW,\n padding: 6,\n zIndex: 1100,\n animation: 'ab-float-in 0.12s ease',\n }}\n >\n <div ref={listRef}>\n {filtered.length === 0 ? (\n <div\n style={{\n padding: '8px 12px',\n fontSize: 13,\n color: '#9ca3af',\n }}\n >\n No results\n </div>\n ) : (\n filtered.map((item, i) => (\n <SlashMenuItem\n key={item.id ?? item.title}\n item={item}\n selected={i === selectedIndex}\n onMouseEnter={() => setSelectedIndex(i)}\n onMouseDown={(e) => {\n e.preventDefault();\n if (range) {\n item.command({ view, range });\n view.focus();\n }\n }}\n />\n ))\n )}\n </div>\n </div>,\n document.body,\n );\n}\n\n// ── SlashMenuItem ─────────────────────────────────────────\n\ninterface SlashMenuItemProps {\n item: SlashCommandItem;\n selected: boolean;\n onMouseEnter: () => void;\n onMouseDown: (e: React.MouseEvent) => void;\n}\n\nfunction SlashMenuItem({ item, selected, onMouseEnter, onMouseDown }: SlashMenuItemProps) {\n return (\n <button\n style={{\n ...BTN_RESET,\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n padding: '7px 10px',\n borderRadius: 7,\n background: selected ? 'rgba(99,102,241,0.07)' : 'transparent',\n transition: 'background 0.08s',\n }}\n onMouseEnter={onMouseEnter}\n onMouseDown={onMouseDown}\n >\n {/* Icon */}\n {item.icon !== undefined && (\n <span\n style={{\n width: 28,\n height: 28,\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 6,\n background: 'rgba(0,0,0,0.04)',\n fontSize: 13,\n fontWeight: 700,\n color: '#6366f1',\n fontFamily: 'monospace',\n }}\n >\n {item.icon}\n </span>\n )}\n\n {/* Text */}\n <span style={{ display: 'flex', flexDirection: 'column', gap: 1, minWidth: 0 }}>\n <span\n style={{\n fontSize: 13,\n fontWeight: 500,\n color: '#171717',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {item.title}\n </span>\n {item.description && (\n <span\n style={{\n fontSize: 11,\n color: '#9ca3af',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {item.description}\n </span>\n )}\n </span>\n </button>\n );\n}\n","import React, { useState, type ReactElement } from 'react';\nimport type { DocumentNode } from '../../ast/types';\nimport { textContent } from '../../ast/traverse';\nimport { analyzeJinjaBlocks, type JinjaVisualStructure, type JinjaVisualBranch } from '../../jinja/analyzer';\n\nexport interface JinjaTreeViewProps {\n doc: DocumentNode;\n className?: string;\n}\n\nconst BRANCH_COLORS: Record<string, string> = {\n if: '#6366f1',\n elif: '#f59e0b',\n else: '#8b5cf6',\n};\n\nfunction getBlockPreview(doc: DocumentNode, startIdx: number, endIdx: number): string {\n const blocks = doc.content.slice(startIdx, endIdx);\n const text = blocks.map((b) => textContent(b)).join(' ').trim();\n return text.length > 40 ? text.slice(0, 40) + '...' : text;\n}\n\nfunction BranchNode({\n branch,\n doc,\n isLast,\n}: {\n branch: JinjaVisualBranch;\n doc: DocumentNode;\n isLast: boolean;\n}): ReactElement {\n const color = BRANCH_COLORS[branch.type] || '#6366f1';\n const blockCount = branch.blockEndIndex - branch.blockStartIndex;\n const preview = getBlockPreview(doc, branch.blockStartIndex, branch.blockEndIndex);\n const connector = isLast ? '\\u2514\\u2500' : '\\u251C\\u2500';\n\n return (\n <div className=\"jinja-tree-branch\">\n <span className=\"jinja-tree-connector\">{connector} </span>\n <span className=\"jinja-tree-badge\" style={{ color, borderColor: color }}>\n [{branch.type}]\n </span>\n {branch.condition && (\n <span className=\"jinja-tree-condition\"> {branch.condition}</span>\n )}\n <span className=\"jinja-tree-meta\">\n {' '}{blockCount} block{blockCount !== 1 ? 's' : ''}\n {preview && `: \"${preview}\"`}\n </span>\n </div>\n );\n}\n\nfunction StructureNode({ structure, doc }: { structure: JinjaVisualStructure; doc: DocumentNode }): ReactElement {\n const [expanded, setExpanded] = useState(true);\n const firstBranch = structure.branches[0];\n const label = firstBranch?.condition ? `if ${firstBranch.condition}` : 'if';\n\n return (\n <div className=\"jinja-tree-structure\">\n <button\n className=\"jinja-tree-toggle\"\n onClick={() => setExpanded(!expanded)}\n type=\"button\"\n >\n <span className=\"jinja-tree-arrow\">{expanded ? '\\u25BC' : '\\u25B6'}</span>\n <span className=\"jinja-tree-label\">{label}</span>\n </button>\n {expanded && (\n <div className=\"jinja-tree-branches\">\n {structure.branches.map((branch, i) => (\n <BranchNode\n key={`${structure.id}-${i}`}\n branch={branch}\n doc={doc}\n isLast={i === structure.branches.length - 1}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nexport function JinjaTreeView({ doc, className }: JinjaTreeViewProps): ReactElement | null {\n const structures = analyzeJinjaBlocks(doc);\n if (structures.length === 0) return null;\n\n return (\n <div className={`jinja-tree ${className || ''}`}>\n {structures.map((structure) => (\n <StructureNode key={structure.id} structure={structure} doc={doc} />\n ))}\n </div>\n );\n}\n","/**\n * Floating UI for the Actionbook editor.\n *\n * Two interaction patterns:\n *\n * 1. SelectionToolbar — appears above a non-empty text selection.\n * Buttons: Bold · Italic · Underline · Strikethrough · Code · Link · ─ · Block type ▾\n *\n * 2. EmptyParaHandle — appears to the left of an empty paragraph/heading\n * after the cursor has dwelled there for DWELL_MS (600 ms).\n * A small \"+\" button opens a block-type picker menu.\n *\n * Both are rendered into document.body via React portals so they never\n * get clipped by overflow:hidden ancestors.\n */\n\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport type { EditorView } from 'prosemirror-view';\nimport type { EditorState } from 'prosemirror-state';\nimport { setBlockType, toggleMark, wrapIn } from 'prosemirror-commands';\nimport { wrapInList } from 'prosemirror-schema-list';\nimport { actionbookSchema } from '../schema';\n\n// ── Schema refs ───────────────────────────────────────────\n\nconst { paragraph, heading, bulletList, orderedList, blockquote } = actionbookSchema.nodes;\nconst {\n bold,\n italic,\n underline,\n strikethrough,\n code,\n link: linkMark,\n} = actionbookSchema.marks;\n\n// ── Constants ─────────────────────────────────────────────\n\nconst DWELL_MS = 600;\nconst TOOLBAR_H = 36;\nconst TOOLBAR_GAP = 8;\nconst VPORT_MARGIN = 8;\n// attribute used to detect clicks inside any floating element\nconst FLOAT_ATTR = 'data-ab-float';\n\n// ── Editor state helpers ──────────────────────────────────\n\nfunction hasMark(state: EditorState, type: typeof bold): boolean {\n const { from, to, empty } = state.selection;\n if (empty) return false;\n return state.doc.rangeHasMark(from, to, type);\n}\n\nfunction activeHeadingLevel(state: EditorState): number | null {\n const { $from } = state.selection;\n const node = $from.parent;\n if (node.type === heading) return node.attrs.level as number;\n return null;\n}\n\n/** Returns 'bullet' | 'ordered' | null depending on whether the cursor is inside a list. */\nfunction activeListType(state: EditorState): 'bullet' | 'ordered' | null {\n const { $from } = state.selection;\n for (let d = $from.depth; d > 0; d--) {\n const t = $from.node(d).type;\n if (t === bulletList) return 'bullet';\n if (t === orderedList) return 'ordered';\n }\n return null;\n}\n\n/** Convert the nearest ancestor list to `toType`. */\nfunction convertList(\n state: EditorState,\n dispatch: EditorView['dispatch'] | undefined,\n toType: typeof bulletList | typeof orderedList,\n): boolean {\n const { $from } = state.selection;\n for (let d = $from.depth; d > 0; d--) {\n const node = $from.node(d);\n if (node.type === bulletList || node.type === orderedList) {\n if (node.type === toType) return false;\n if (dispatch) {\n dispatch(state.tr.setNodeMarkup($from.before(d), toType, node.attrs));\n }\n return true;\n }\n }\n return false;\n}\n\nfunction currentBlockLabel(state: EditorState): string {\n const hl = activeHeadingLevel(state);\n if (hl) return `H${hl}`;\n const lt = activeListType(state);\n if (lt === 'bullet') return '• List';\n if (lt === 'ordered') return '1. List';\n const { $from } = state.selection;\n for (let d = $from.depth; d > 0; d--) {\n if ($from.node(d).type === blockquote) return 'Quote';\n }\n return 'Text';\n}\n\nfunction emptyBlockCursorPos(state: EditorState): number | null {\n const { selection } = state;\n if (!selection.empty) return null;\n const { $from } = selection;\n const parent = $from.parent;\n if (\n (parent.type === paragraph || parent.type === heading) &&\n parent.content.size === 0\n ) {\n return selection.from;\n }\n return null;\n}\n\n/** Get the bounding rect of the current DOM selection (viewport-relative). */\nfunction getSelectionDOMRect(): DOMRect | null {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0 || sel.isCollapsed) return null;\n const rect = sel.getRangeAt(0).getBoundingClientRect();\n if (rect.width === 0 && rect.height === 0) return null;\n return rect;\n}\n\n// ── Shared styles ─────────────────────────────────────────\n\nconst POPUP_SHADOW =\n '0 0 0 1px rgba(0,0,0,0.07), 0 4px 20px rgba(0,0,0,0.11), 0 1px 4px rgba(0,0,0,0.05)';\n\nconst BTN_RESET: React.CSSProperties = {\n border: 'none',\n padding: 0,\n background: 'transparent',\n fontFamily: 'inherit',\n cursor: 'pointer',\n lineHeight: 1,\n};\n\n// ── ToolbarButton ─────────────────────────────────────────\n\ninterface TBtnProps {\n children: React.ReactNode;\n active?: boolean;\n title?: string;\n onMouseDown: (e: React.MouseEvent) => void;\n style?: React.CSSProperties;\n}\n\nfunction TBtn({ children, active, title, onMouseDown, style }: TBtnProps) {\n const [hover, setHover] = useState(false);\n return (\n <button\n {...{ [FLOAT_ATTR]: '' }}\n title={title}\n onMouseDown={(e) => { e.preventDefault(); onMouseDown(e); }}\n onMouseEnter={() => setHover(true)}\n onMouseLeave={() => setHover(false)}\n style={{\n ...BTN_RESET,\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n width: 28, height: 28, borderRadius: 6,\n fontSize: 13, fontWeight: 600, color: active ? '#6366f1' : '#3f3f46',\n background: active\n ? 'rgba(99,102,241,0.1)'\n : hover ? 'rgba(0,0,0,0.05)' : 'transparent',\n transition: 'background 0.1s, color 0.1s',\n ...style,\n }}\n >\n {children}\n </button>\n );\n}\n\n// ── Divider ───────────────────────────────────────────────\n\nfunction Divider() {\n return (\n <div style={{ width: 1, height: 18, background: 'rgba(0,0,0,0.07)', margin: '0 2px', flexShrink: 0 }} />\n );\n}\n\n// ── BlockTypeDropdown ─────────────────────────────────────\n\ninterface BlockTypeDropdownProps {\n view: EditorView;\n state: EditorState;\n label: string;\n}\n\nfunction BlockTypeDropdown({ view, state, label }: BlockTypeDropdownProps) {\n const [open, setOpen] = useState(false);\n const btnRef = useRef<HTMLButtonElement>(null);\n const [hover, setHover] = useState(false);\n\n useEffect(() => {\n if (!open) return;\n const onDown = (e: MouseEvent) => {\n if (!(e.target as HTMLElement).closest(`[${FLOAT_ATTR}]`)) {\n setOpen(false);\n }\n };\n document.addEventListener('mousedown', onDown, true);\n return () => document.removeEventListener('mousedown', onDown, true);\n }, [open]);\n\n const headingLevel = activeHeadingLevel(state);\n const listType = activeListType(state);\n\n const items: { label: string; shortLabel: string; active: boolean; run: () => void }[] = [\n { label: 'Text', shortLabel: '¶', active: !headingLevel && !listType, run: () => { setBlockType(paragraph)(view.state, view.dispatch); view.focus(); } },\n { label: 'Heading 1', shortLabel: 'H1', active: headingLevel === 1, run: () => { setBlockType(heading, { level: 1 })(view.state, view.dispatch); view.focus(); } },\n { label: 'Heading 2', shortLabel: 'H2', active: headingLevel === 2, run: () => { setBlockType(heading, { level: 2 })(view.state, view.dispatch); view.focus(); } },\n { label: 'Heading 3', shortLabel: 'H3', active: headingLevel === 3, run: () => { setBlockType(heading, { level: 3 })(view.state, view.dispatch); view.focus(); } },\n { label: 'Bullet List', shortLabel: '•', active: listType === 'bullet', run: () => {\n if (listType === 'bullet') return;\n if (listType === 'ordered') { convertList(view.state, view.dispatch, bulletList); }\n else { wrapInList(bulletList)(view.state, view.dispatch); }\n view.focus();\n }},\n { label: 'Ordered List', shortLabel: '1.', active: listType === 'ordered', run: () => {\n if (listType === 'ordered') return;\n if (listType === 'bullet') { convertList(view.state, view.dispatch, orderedList); }\n else { wrapInList(orderedList)(view.state, view.dispatch); }\n view.focus();\n }},\n { label: 'Quote', shortLabel: '>', active: false, run: () => { wrapIn(blockquote)(view.state, view.dispatch); view.focus(); } },\n ];\n\n const btnRect = btnRef.current?.getBoundingClientRect();\n\n return (\n <>\n <button\n ref={btnRef}\n {...{ [FLOAT_ATTR]: '' }}\n onMouseDown={(e) => { e.preventDefault(); setOpen((v) => !v); }}\n onMouseEnter={() => setHover(true)}\n onMouseLeave={() => setHover(false)}\n style={{\n ...BTN_RESET,\n display: 'flex', alignItems: 'center', gap: 3,\n height: 28, padding: '0 6px', borderRadius: 6,\n fontSize: 11, fontWeight: 600, color: open ? '#6366f1' : '#3f3f46',\n background: open ? 'rgba(99,102,241,0.1)' : hover ? 'rgba(0,0,0,0.05)' : 'transparent',\n transition: 'background 0.1s, color 0.1s',\n whiteSpace: 'nowrap',\n }}\n >\n {label}\n <span style={{ fontSize: 8, opacity: 0.6 }}>▾</span>\n </button>\n {open && btnRect && createPortal(\n <div\n {...{ [FLOAT_ATTR]: '' }}\n style={{\n position: 'fixed', zIndex: 1001,\n left: btnRect.left, top: btnRect.bottom + 4,\n background: '#fff', borderRadius: 10, boxShadow: POPUP_SHADOW,\n padding: 6, minWidth: 168,\n animation: 'ab-float-in 0.12s ease',\n }}\n >\n {items.map((item) => (\n <DropdownItem key={item.label} item={item} onRun={() => setOpen(false)} />\n ))}\n </div>,\n document.body,\n )}\n </>\n );\n}\n\nfunction DropdownItem({ item, onRun }: { item: { label: string; shortLabel: string; active: boolean; run: () => void }; onRun: () => void }) {\n const [hover, setHover] = useState(false);\n return (\n <button\n {...{ [FLOAT_ATTR]: '' }}\n onMouseDown={(e) => { e.preventDefault(); item.run(); onRun(); }}\n onMouseEnter={() => setHover(true)}\n onMouseLeave={() => setHover(false)}\n style={{\n ...BTN_RESET,\n display: 'flex', alignItems: 'center', gap: 10,\n width: '100%', padding: '6px 8px',\n borderRadius: 6, textAlign: 'left',\n fontSize: 13, color: item.active ? '#6366f1' : '#3f3f46',\n fontWeight: item.active ? 600 : 400,\n background: hover ? 'rgba(0,0,0,0.04)' : 'transparent',\n transition: 'background 0.1s',\n }}\n >\n <span style={{ width: 24, flexShrink: 0, textAlign: 'center', fontWeight: 700, fontSize: 12, fontFamily: 'monospace', color: '#6366f1' }}>\n {item.shortLabel}\n </span>\n {item.label}\n </button>\n );\n}\n\n// ── SelectionToolbar ──────────────────────────────────────\n\ninterface SelectionToolbarProps {\n view: EditorView;\n state: EditorState;\n selectionRect: DOMRect;\n}\n\nfunction SelectionToolbar({ view, state, selectionRect }: SelectionToolbarProps) {\n const [linkMode, setLinkMode] = useState(false);\n const [linkHref, setLinkHref] = useState('');\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Derived state\n const isBold = hasMark(state, bold);\n const isItalic = hasMark(state, italic);\n const isUnderline = hasMark(state, underline);\n const isStrike = hasMark(state, strikethrough);\n const isCode = hasMark(state, code);\n const isLink = hasMark(state, linkMark);\n const blockLabel = currentBlockLabel(state);\n\n const toolbarW = linkMode ? 300 : 380;\n const toolbarH = TOOLBAR_H;\n\n let left = selectionRect.left + selectionRect.width / 2 - toolbarW / 2;\n let top = selectionRect.top - toolbarH - TOOLBAR_GAP;\n // Flip below selection when there's no space above\n if (top < VPORT_MARGIN) top = selectionRect.bottom + TOOLBAR_GAP;\n // Clamp to viewport\n left = Math.max(VPORT_MARGIN, Math.min(left, window.innerWidth - toolbarW - VPORT_MARGIN));\n top = Math.max(VPORT_MARGIN, Math.min(top, window.innerHeight - toolbarH - VPORT_MARGIN));\n\n const run = useCallback(\n (cmd: (s: EditorState, d?: typeof view.dispatch) => boolean) => {\n cmd(view.state, view.dispatch);\n view.focus();\n },\n [view],\n );\n\n const openLinkInput = () => {\n // Pre-fill with the first href found in the selection (if any)\n const { from, to } = view.state.selection;\n let existingHref = '';\n view.state.doc.nodesBetween(from, to, (node) => {\n if (!existingHref) {\n const lm = node.marks.find((m) => m.type === linkMark);\n if (lm) existingHref = lm.attrs.href as string;\n }\n });\n setLinkHref(existingHref);\n setLinkMode(true);\n setTimeout(() => inputRef.current?.focus(), 0);\n };\n\n const applyLink = () => {\n const href = linkHref.trim();\n if (href) {\n const finalHref =\n href.startsWith('#') || href.startsWith('/') || /^https?:\\/\\//i.test(href)\n ? href\n : `https://${href}`;\n const { from, to } = view.state.selection;\n const tr = view.state.tr.addMark(from, to, linkMark.create({ href: finalHref }));\n view.dispatch(tr);\n }\n view.focus();\n setLinkMode(false);\n setLinkHref('');\n };\n\n const removeLink = () => {\n const { from, to } = view.state.selection;\n view.dispatch(view.state.tr.removeMark(from, to, linkMark));\n view.focus();\n };\n\n return (\n <div\n {...{ [FLOAT_ATTR]: '' }}\n style={{\n position: 'fixed', left, top, width: toolbarW, height: toolbarH,\n zIndex: 1000,\n display: 'flex', alignItems: 'center', gap: 2, padding: '0 6px',\n background: '#fff', borderRadius: 10, boxShadow: POPUP_SHADOW,\n userSelect: 'none',\n animation: 'ab-float-in 0.12s ease',\n }}\n >\n {linkMode ? (\n /* ── Link input mode ── */\n <>\n <span style={{ fontSize: 13, color: '#9ca3af', paddingLeft: 4, flexShrink: 0 }}>↗</span>\n <input\n ref={inputRef}\n value={linkHref}\n onChange={(e) => setLinkHref(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') { e.preventDefault(); applyLink(); }\n if (e.key === 'Escape') { e.preventDefault(); setLinkMode(false); view.focus(); }\n }}\n placeholder=\"Paste link...\"\n style={{\n flex: 1, border: 'none', outline: 'none',\n fontSize: 13, fontFamily: 'inherit', color: '#171717',\n padding: '0 6px', background: 'transparent',\n minWidth: 0,\n }}\n />\n <TBtn\n title=\"Apply (Enter)\"\n onMouseDown={(e) => { e.preventDefault(); applyLink(); }}\n style={{ color: '#6366f1', width: 24, fontSize: 14 }}\n >↵</TBtn>\n <TBtn\n title=\"Cancel (Esc)\"\n onMouseDown={(e) => { e.preventDefault(); setLinkMode(false); view.focus(); }}\n style={{ color: '#9ca3af', width: 24, fontSize: 14 }}\n >✕</TBtn>\n </>\n ) : (\n /* ── Normal toolbar mode ── */\n <>\n {/* Marks */}\n <TBtn active={isBold} title=\"Bold (Cmd+B)\" onMouseDown={() => run(toggleMark(bold))}\n style={{ fontWeight: 700 }}>B</TBtn>\n <TBtn active={isItalic} title=\"Italic (Cmd+I)\" onMouseDown={() => run(toggleMark(italic))}\n style={{ fontStyle: 'italic' }}>I</TBtn>\n <TBtn active={isUnderline} title=\"Underline (Cmd+U)\" onMouseDown={() => run(toggleMark(underline))}\n style={{ textDecoration: 'underline' }}>U</TBtn>\n <TBtn active={isStrike} title=\"Strikethrough (Cmd+Shift+X)\" onMouseDown={() => run(toggleMark(strikethrough))}\n style={{ textDecoration: 'line-through' }}>S</TBtn>\n <TBtn active={isCode} title=\"Code (Cmd+E)\" onMouseDown={() => run(toggleMark(code))}\n style={{ fontFamily: 'monospace', fontSize: 11 }}>`·`</TBtn>\n <TBtn active={isLink} title={isLink ? 'Remove link' : 'Add link (Cmd+K)'}\n onMouseDown={() => isLink ? removeLink() : openLinkInput()}\n style={{ fontSize: 14 }}>↗</TBtn>\n\n <Divider />\n\n {/* Block type dropdown */}\n <BlockTypeDropdown view={view} state={state} label={blockLabel} />\n </>\n )}\n </div>\n );\n}\n\n// ── Block menu items ──────────────────────────────────────\n\ninterface BlockItem {\n shortLabel: string;\n label: string;\n run: (view: EditorView) => void;\n}\n\nconst BLOCK_ITEMS: BlockItem[] = [\n {\n shortLabel: '¶',\n label: 'Text',\n run: (v) => { setBlockType(paragraph)(v.state, v.dispatch); v.focus(); },\n },\n {\n shortLabel: 'H1',\n label: 'Heading 1',\n run: (v) => { setBlockType(heading, { level: 1 })(v.state, v.dispatch); v.focus(); },\n },\n {\n shortLabel: 'H2',\n label: 'Heading 2',\n run: (v) => { setBlockType(heading, { level: 2 })(v.state, v.dispatch); v.focus(); },\n },\n {\n shortLabel: 'H3',\n label: 'Heading 3',\n run: (v) => { setBlockType(heading, { level: 3 })(v.state, v.dispatch); v.focus(); },\n },\n {\n shortLabel: '•',\n label: 'Bullet List',\n run: (v) => { wrapInList(bulletList)(v.state, v.dispatch); v.focus(); },\n },\n {\n shortLabel: '1.',\n label: 'Ordered List',\n run: (v) => { wrapInList(orderedList)(v.state, v.dispatch); v.focus(); },\n },\n {\n shortLabel: '☐',\n label: 'Todo List',\n run: (v) => {\n const { listItem: liType, bulletList: blType, paragraph: pType } = actionbookSchema.nodes;\n const li = liType.create({ checked: false }, pType.create());\n const list = blType.create(null, li);\n v.dispatch(v.state.tr.replaceSelectionWith(list));\n v.focus();\n },\n },\n {\n shortLabel: '❝',\n label: 'Quote',\n run: (v) => { wrapIn(blockquote)(v.state, v.dispatch); v.focus(); },\n },\n {\n shortLabel: '▦',\n label: 'Table',\n run: (v) => {\n const { table: tblType, tableRow: trType, tableHeader: thType, tableCell: tdType } = actionbookSchema.nodes;\n const headerCells = [thType.create(), thType.create(), thType.create()];\n const bodyCells = [tdType.create(), tdType.create(), tdType.create()];\n const headerRow = trType.create(null, headerCells);\n const bodyRow = trType.create(null, bodyCells);\n const tbl = tblType.create(null, [headerRow, bodyRow]);\n v.dispatch(v.state.tr.replaceSelectionWith(tbl));\n v.focus();\n },\n },\n];\n\n// ── EmptyParaHandle ───────────────────────────────────────\n\ninterface EmptyParaHandleProps {\n view: EditorView;\n cursorPos: number;\n}\n\nfunction EmptyParaHandle({ view, cursorPos }: EmptyParaHandleProps) {\n const [menuOpen, setMenuOpen] = useState(false);\n\n const coords = view.coordsAtPos(cursorPos);\n const lineH = Math.max(coords.bottom - coords.top, 18);\n const btnSize = 22;\n const btnLeft = coords.left - btnSize - 32;\n const btnTop = coords.top + (lineH - btnSize) / 2;\n const menuLeft = Math.max(VPORT_MARGIN, btnLeft);\n const menuTop = btnTop + btnSize + 4;\n\n // Close block menu when clicking outside floating elements\n useEffect(() => {\n if (!menuOpen) return;\n const onDown = (e: MouseEvent) => {\n if (!(e.target as HTMLElement).closest(`[${FLOAT_ATTR}]`)) {\n setMenuOpen(false);\n }\n };\n document.addEventListener('mousedown', onDown, true);\n return () => document.removeEventListener('mousedown', onDown, true);\n }, [menuOpen]);\n\n return (\n <>\n {/* + button */}\n <button\n {...{ [FLOAT_ATTR]: '' }}\n title=\"Add block\"\n onMouseDown={(e) => { e.preventDefault(); setMenuOpen((v) => !v); }}\n style={{\n ...BTN_RESET,\n position: 'fixed', zIndex: 999,\n left: btnLeft < VPORT_MARGIN ? VPORT_MARGIN : btnLeft,\n top: btnTop,\n width: btnSize, height: btnSize,\n border: '1px solid rgba(0,0,0,0.1)',\n borderRadius: 5,\n background: menuOpen ? 'rgba(99,102,241,0.08)' : '#fff',\n boxShadow: '0 1px 3px rgba(0,0,0,0.06)',\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n color: menuOpen ? '#6366f1' : '#9ca3af',\n fontSize: 16,\n animation: 'ab-float-in 0.15s ease',\n transition: 'color 0.1s, background 0.1s, border-color 0.1s',\n }}\n >\n +\n </button>\n\n {/* Block picker menu */}\n {menuOpen && (\n <div\n {...{ [FLOAT_ATTR]: '' }}\n style={{\n position: 'fixed', zIndex: 1000,\n left: menuLeft, top: menuTop,\n background: '#fff',\n borderRadius: 10,\n boxShadow: POPUP_SHADOW,\n padding: 6,\n minWidth: 168,\n animation: 'ab-float-in 0.12s ease',\n }}\n >\n {BLOCK_ITEMS.map((item) => (\n <BlockMenuItem\n key={item.label}\n item={item}\n view={view}\n onRun={() => setMenuOpen(false)}\n />\n ))}\n </div>\n )}\n </>\n );\n}\n\nfunction BlockMenuItem({\n item,\n view,\n onRun,\n}: {\n item: BlockItem;\n view: EditorView;\n onRun: () => void;\n}) {\n const [hover, setHover] = useState(false);\n return (\n <button\n {...{ [FLOAT_ATTR]: '' }}\n onMouseDown={(e) => { e.preventDefault(); item.run(view); onRun(); }}\n onMouseEnter={() => setHover(true)}\n onMouseLeave={() => setHover(false)}\n style={{\n ...BTN_RESET,\n display: 'flex', alignItems: 'center', gap: 10,\n width: '100%', padding: '6px 8px',\n borderRadius: 6, textAlign: 'left',\n fontSize: 13, color: '#3f3f46',\n background: hover ? 'rgba(0,0,0,0.04)' : 'transparent',\n transition: 'background 0.1s',\n }}\n >\n <span\n style={{\n width: 24, flexShrink: 0, textAlign: 'center',\n fontWeight: 700, fontSize: 12,\n fontFamily: 'monospace',\n color: '#6366f1',\n }}\n >\n {item.shortLabel}\n </span>\n {item.label}\n </button>\n );\n}\n\n// ── FloatingMenu (root) ───────────────────────────────────\n\nexport interface FloatingMenuProps {\n view: EditorView | null;\n editorState: EditorState | null;\n}\n\nexport function FloatingMenu({ view, editorState }: FloatingMenuProps) {\n // ── Dwell timer for empty paragraph ──\n const [showEmptyHandle, setShowEmptyHandle] = useState(false);\n const dwellTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const lastEmptyPosRef = useRef<number | null>(null);\n\n // ── Re-render on editor container scroll (position recalculation) ──\n const [, setScrollTick] = useState(0);\n useEffect(() => {\n const editorDom = view?.dom;\n if (!editorDom) return;\n const container = editorDom.closest('.editor-shell') ?? editorDom.parentElement;\n if (!container) return;\n const onScroll = () => setScrollTick((n) => n + 1);\n container.addEventListener('scroll', onScroll, { passive: true });\n return () => container.removeEventListener('scroll', onScroll);\n }, [view]);\n\n // ── Inject keyframe animation once ──\n useEffect(() => {\n const id = 'ab-float-keyframes';\n if (document.getElementById(id)) return;\n const style = document.createElement('style');\n style.id = id;\n style.textContent = `\n @keyframes ab-float-in {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n }\n `;\n document.head.appendChild(style);\n }, []);\n\n if (!view || !editorState) return null;\n\n const emptyPos = emptyBlockCursorPos(editorState);\n const hasSelection = !editorState.selection.empty;\n\n // Manage dwell timer\n if (emptyPos !== lastEmptyPosRef.current) {\n lastEmptyPosRef.current = emptyPos;\n\n if (dwellTimerRef.current) {\n clearTimeout(dwellTimerRef.current);\n dwellTimerRef.current = null;\n }\n\n if (emptyPos !== null) {\n dwellTimerRef.current = setTimeout(() => setShowEmptyHandle(true), DWELL_MS);\n } else {\n setShowEmptyHandle(false);\n }\n }\n\n const selectionRect = hasSelection ? getSelectionDOMRect() : null;\n\n return createPortal(\n <>\n {/* Selection toolbar */}\n {hasSelection && selectionRect && (\n <SelectionToolbar\n view={view}\n state={editorState}\n selectionRect={selectionRect}\n />\n )}\n\n {/* Empty paragraph handle */}\n {!hasSelection && showEmptyHandle && emptyPos !== null && (\n <EmptyParaHandle view={view} cursorPos={emptyPos} />\n )}\n </>,\n document.body,\n );\n}\n","/**\n * Inline suggestion (ghost text) plugin.\n *\n * Debounces after the cursor stops moving, calls an LLM endpoint via a\n * user-supplied `InlineSuggestProvider`, then renders the response as gray\n * ghost text after the cursor using a ProseMirror widget decoration.\n *\n * Accepts:\n * Tab → insert the suggestion at the cursor\n * Escape → dismiss the suggestion\n *\n * Fully detachable: just omit `createInlineSuggestPlugin()` from the plugins\n * array to disable the feature entirely.\n */\n\nimport { Plugin, PluginKey } from 'prosemirror-state';\nimport type { EditorState } from 'prosemirror-state';\nimport { Decoration, DecorationSet } from 'prosemirror-view';\nimport type { EditorView } from 'prosemirror-view';\nimport type { ActionbookPlugin } from './types';\nimport type { LlmCompletionEndpoint } from '../../lint/types';\n\n// ── Public types ──────────────────────────────────────────\n\n/**\n * Cursor context passed to the provider's `buildPrompt`.\n */\nexport type InlineSuggestContext = {\n /** Text before the cursor — current paragraph plus up to 2 preceding paragraphs. */\n textBefore: string;\n /** Text in the current paragraph after the cursor (up to 100 chars). */\n textAfter: string;\n};\n\n/**\n * Extensible provider interface, analogous to `LlmLintRule`.\n *\n * Implement this to customize what gets sent to the LLM and how the\n * response is parsed into a suggestion string.\n */\nexport type InlineSuggestProvider = {\n /** Unique identifier for this provider. */\n id: string;\n /**\n * Build the prompt string sent to the LLM endpoint.\n * Return an empty string to suppress the request entirely.\n */\n buildPrompt: (ctx: InlineSuggestContext) => string;\n /**\n * Parse the raw LLM response into the text to insert at the cursor.\n * Return an empty string to suppress the decoration.\n * `ctx` is the same context that was passed to `buildPrompt`.\n */\n parseResponse: (response: string, ctx: InlineSuggestContext) => string;\n};\n\nexport interface InlineSuggestState {\n /** Ghost text currently shown, or null if nothing is active. */\n suggestion: string | null;\n /** Document position the suggestion is anchored to. */\n anchorPos: number | null;\n}\n\nexport const inlineSuggestKey = new PluginKey<InlineSuggestState>('inlineSuggest');\n\n// ── Constants ─────────────────────────────────────────────\n\nconst DEBOUNCE_MS = 600;\nconst CONTEXT_CHARS = 500;\n\n// ── Factory ───────────────────────────────────────────────\n\nexport function createInlineSuggestPlugin(\n provider: InlineSuggestProvider,\n endpoint: LlmCompletionEndpoint,\n options?: {\n /**\n * Called when the user accepts a suggestion (Tab) or the cursor moves to\n * a new context. Use this to pre-create a fresh completion session so it's\n * ready by the time the next debounce fires.\n */\n onContextChange?: () => void;\n },\n): ActionbookPlugin {\n const { onContextChange } = options ?? {};\n return {\n name: 'inlineSuggest',\n\n plugins: () => [\n new Plugin<InlineSuggestState>({\n key: inlineSuggestKey,\n\n state: {\n init: (): InlineSuggestState => ({ suggestion: null, anchorPos: null }),\n\n apply(tr, prev): InlineSuggestState {\n const meta = tr.getMeta(inlineSuggestKey) as InlineSuggestState | null | undefined;\n if (meta !== undefined) return meta ?? { suggestion: null, anchorPos: null };\n // Any document edit or cursor move clears the current ghost text\n if (tr.docChanged || tr.selectionSet) {\n return { suggestion: null, anchorPos: null };\n }\n return prev;\n },\n },\n\n props: {\n decorations(state: EditorState) {\n const ps = inlineSuggestKey.getState(state);\n if (!ps?.suggestion || !state.selection.empty) return DecorationSet.empty;\n\n const ghost = document.createElement('span');\n ghost.textContent = ps.suggestion;\n ghost.style.cssText =\n 'color: rgba(0,0,0,0.3); pointer-events: none; user-select: none;';\n ghost.setAttribute('aria-hidden', 'true');\n\n return DecorationSet.create(state.doc, [\n Decoration.widget(state.selection.from, ghost, {\n side: 1,\n key: 'inline-suggest',\n }),\n ]);\n },\n },\n\n view(editorView: EditorView) {\n // Capture Tab / Escape before the browser handles them (Tab moves\n // focus, Escape might bubble to parent dialogs).\n function onKeydown(event: KeyboardEvent) {\n if (event.key !== 'Tab' && event.key !== 'Escape') return;\n const ps = inlineSuggestKey.getState(editorView.state);\n console.debug('[inline-suggest] key pressed:', event.key, 'suggestion:', ps?.suggestion);\n if (!ps?.suggestion) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n if (event.key === 'Tab') {\n // Context changes after accept — pre-clone now so the next\n // fetch gets a fresh session without waiting for clone().\n onContextChange?.();\n const tr = editorView.state.tr.insertText(\n ps.suggestion,\n editorView.state.selection.from,\n );\n tr.setMeta(inlineSuggestKey, { suggestion: null, anchorPos: null });\n editorView.dispatch(tr);\n } else {\n const tr = editorView.state.tr;\n tr.setMeta(inlineSuggestKey, { suggestion: null, anchorPos: null });\n editorView.dispatch(tr);\n }\n }\n\n editorView.dom.addEventListener('keydown', onKeydown, { capture: true });\n\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n let abortController: AbortController | null = null;\n\n function cancel() {\n if (debounceTimer != null) {\n clearTimeout(debounceTimer);\n debounceTimer = null;\n }\n abortController?.abort();\n abortController = null;\n }\n\n function schedule(view: EditorView) {\n cancel();\n debounceTimer = setTimeout(() => {\n debounceTimer = null;\n void fetchSuggestion(view);\n }, DEBOUNCE_MS);\n }\n\n async function fetchSuggestion(view: EditorView) {\n const { state } = view;\n if (!state.selection.empty) return;\n\n const cursorPos = state.selection.from;\n const $from = state.doc.resolve(cursorPos);\n const paraStart = $from.start();\n const paraEnd = $from.end();\n\n // Collect up to 3 block nodes ending at the cursor's block.\n const nearbyStart = (() => {\n const $cursor = state.doc.resolve(cursorPos);\n const depth = $cursor.depth; // depth of the paragraph node\n let blockStart = $cursor.before(depth); // pos of current block's opening token\n let count = 1;\n while (count < 3 && blockStart > 0) {\n const $prev = state.doc.resolve(blockStart - 1);\n blockStart = $prev.before($prev.depth);\n count++;\n }\n return blockStart;\n })();\n\n const textBefore = state.doc.textBetween(nearbyStart, cursorPos, '\\n', '');\n const textAfter = state.doc.textBetween(\n cursorPos,\n Math.min(paraEnd, cursorPos + 100),\n '\\n',\n '',\n );\n\n if (!textBefore.trim()) return;\n\n const ctx = { textBefore, textAfter };\n const prompt = provider.buildPrompt(ctx);\n if (!prompt) return;\n\n console.debug(`[inline-suggest] fetching (provider=${provider.id}) prompt=`, prompt);\n\n abortController = new AbortController();\n try {\n const response = await endpoint(prompt, { signal: abortController.signal });\n console.debug(`[inline-suggest] response=`, response);\n\n const suggestion = provider.parseResponse(response, ctx).trimEnd();\n console.debug(`[inline-suggest] parsed suggestion=`, JSON.stringify(suggestion));\n\n if (!suggestion) {\n console.debug('[inline-suggest] empty suggestion — skipping');\n return;\n }\n\n // Discard if cursor moved while we were waiting\n if (!view.state.selection.empty) return;\n if (view.state.selection.from !== cursorPos) {\n console.debug('[inline-suggest] cursor moved — discarding');\n return;\n }\n\n const tr = view.state.tr;\n tr.setMeta(inlineSuggestKey, { suggestion, anchorPos: cursorPos });\n view.dispatch(tr);\n console.debug('[inline-suggest] suggestion applied');\n } catch (err) {\n if ((err as Error)?.name === 'AbortError') {\n console.debug('[inline-suggest] request aborted');\n } else {\n console.warn('[inline-suggest] endpoint error:', err);\n }\n }\n }\n\n return {\n update(view: EditorView, prevState: EditorState) {\n const docChanged = view.state.doc !== prevState.doc;\n const selChanged = view.state.selection !== prevState.selection;\n if (!docChanged && !selChanged) return;\n\n // A suggestion was just set (meta transaction) — don't reschedule\n const ps = inlineSuggestKey.getState(view.state);\n if (ps?.suggestion) return;\n\n if (!view.state.selection.empty) {\n cancel();\n return;\n }\n\n // Context changed — pre-clone before the debounce fires so the\n // session is fresh and ready when the fetch runs.\n onContextChange?.();\n schedule(view);\n },\n\n destroy() {\n cancel();\n editorView.dom.removeEventListener('keydown', onKeydown, { capture: true });\n },\n };\n },\n }),\n ],\n };\n}\n"],"mappings":"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","names":["key","jsx","jsxs","key","text","doc","jsx","EditorShell","blocks","defaultHandlers","exit","exit","table","row","sizes","columnIndex","code","exit","defaultHandlers","text","text","MAX_DEPTH","ALLOWED_URL_PROTOCOLS","linkMark","doc","defaultHandlers","doc","ALLOWED_URL_PROTOCOLS","convertInline","convertBlock","doc","doc","JUMP_POINT_RE","textContent","MAX_DEPTH","MAX_DEPTH","code","code","constructs","ok","code","markdownSpace","ok","code","markdownLineEndingOrSpace","ok","code","markdownLineEndingOrSpace","strikethrough","text","ok","code","markdownLineEnding","markdownLineEndingOrSpace","markdownSpace","ok","code","markdownLineEnding","markdownSpace","markdownLineEndingOrSpace","map","table","markdownLineEnding","markdownLineEndingOrSpace","markdownSpace","ok","code","MAX_DEPTH","text","MAX_DEPTH","MAX_DEPTH","doc","text","doc","text","doc","Plugin","PluginKey","text","jsx","jsxs","jsx","jsxs","RESOURCE_TAG_COLORS","RESOURCE_TAG_ICONS","text","Plugin","PluginKey","Decoration","DecorationSet","PluginKey","doc","text","Decoration","buildDecorations","DecorationSet","Plugin","InputRule","inputRules","Plugin","PluginKey","TextSelection","doc","text","Plugin","PluginKey","doc","key","Plugin","PluginKey","derived","useEffect","useRef","useState","jsx","jsxs","useState","useRef","useEffect","useState","jsx","jsxs","doc","text","useState","useCallback","useEffect","useRef","useState","createPortal","toggleMark","wrapInList","Fragment","jsx","jsxs","paragraph","heading","bulletList","orderedList","blockquote","bold","italic","underline","strikethrough","code","VPORT_MARGIN","POPUP_SHADOW","BTN_RESET","useState","useRef","useEffect","wrapInList","createPortal","useCallback","toggleMark","Plugin","PluginKey","Decoration","DecorationSet","Plugin","DecorationSet","Decoration"]}
1
+ {"version":3,"sources":["../../src/ui/schema.ts","../../src/ui/plugin/registry.ts","../../src/ui/components/ActionbookRenderer.tsx","../../src/ui/components/icons.tsx","../../src/ui/components/EditorShell.tsx","../../src/ui/nodeView/ReactNodeView.ts","../../src/ui/hooks/useEditorView.ts","../../src/compat/prosemirror.ts","../../src/markdown/serializer.ts","../../node_modules/devlop/lib/default.js","../../node_modules/micromark-util-normalize-identifier/index.js","../../node_modules/mdast-util-gfm-footnote/lib/index.js","../../node_modules/mdast-util-gfm-strikethrough/lib/index.js","../../node_modules/markdown-table/index.js","../../node_modules/mdast-util-gfm-table/lib/index.js","../../node_modules/mdast-util-gfm-task-list-item/lib/index.js","../../src/markdown/plugins/resourceTag.ts","../../src/markdown/plugins/jumpPoint.ts","../../src/markdown/mdastAdapter.ts","../../src/ui/bridge/toProseMirrorJSON.ts","../../src/ui/plugin/historyPlugin.ts","../../src/ui/plugin/inputRulesPlugin.ts","../../src/ui/plugin/keymapPlugin.ts","../../src/ui/plugin/markdownClipboard.ts","../../src/ast/traverse.ts","../../src/markdown/parser.ts","../../node_modules/micromark-util-chunked/index.js","../../node_modules/micromark-util-combine-extensions/index.js","../../node_modules/micromark-util-classify-character/index.js","../../node_modules/micromark-util-resolve-all/index.js","../../node_modules/micromark-factory-space/index.js","../../node_modules/micromark-core-commonmark/lib/blank-line.js","../../node_modules/micromark-extension-gfm-footnote/lib/syntax.js","../../node_modules/micromark-extension-gfm-strikethrough/lib/syntax.js","../../node_modules/micromark-extension-gfm-table/lib/syntax.js","../../node_modules/micromark-extension-gfm-table/lib/edit-map.js","../../node_modules/micromark-extension-gfm-table/lib/infer.js","../../node_modules/micromark-extension-gfm-task-list-item/lib/syntax.js","../../src/markdown/plugins/jinjaBlock.ts","../../src/markdown/fragment.ts","../../src/jinja/scanner.ts","../../src/jinja/structurer.ts","../../src/jinja/analyzer.ts","../../src/ui/plugin/jumpPointPlugin.ts","../../src/ui/plugin/jumpPointNodeViewPlugin.tsx","../../src/ui/plugin/jumpPointValidationPlugin.ts","../../src/ui/plugin/inlineToolTagNodeViewPlugin.tsx","../../src/ui/plugin/jinjaDecoration.ts","../../src/ui/plugin/jinjaIfBlockPlugin.tsx","../../src/jinja/conditionHighlighter.ts","../../src/ui/plugin/linkPlugin.ts","../../src/ui/plugin/dragHandlePlugin.ts","../../src/ui/plugin/todoNodeViewPlugin.tsx","../../src/ui/plugin/slashCommandPlugin.ts","../../src/ui/components/SlashCommandMenu.tsx","../../src/ui/components/JinjaTreeView.tsx","../../src/ui/components/FloatingMenu.tsx","../../src/ui/plugin/inlineSuggestPlugin.ts"],"sourcesContent":["import { Schema } from 'prosemirror-model';\n\n/**\n * ProseMirror Schema for Actionbook documents.\n */\nexport const actionbookSchema = new Schema({\n nodes: {\n doc: {\n content: 'block*',\n },\n\n paragraph: {\n content: 'inline*',\n group: 'block',\n parseDOM: [{ tag: 'p' }],\n toDOM() {\n return ['p', 0];\n },\n },\n\n heading: {\n content: 'inline*',\n group: 'block',\n attrs: { level: { default: 1 } },\n parseDOM: [\n { tag: 'h1', attrs: { level: 1 } },\n { tag: 'h2', attrs: { level: 2 } },\n { tag: 'h3', attrs: { level: 3 } },\n { tag: 'h4', attrs: { level: 4 } },\n { tag: 'h5', attrs: { level: 5 } },\n { tag: 'h6', attrs: { level: 6 } },\n ],\n toDOM(node) {\n return [`h${node.attrs.level}`, 0];\n },\n },\n\n bulletList: {\n content: 'listItem+',\n group: 'block',\n parseDOM: [\n { tag: 'div.ab-bullet-list' },\n { tag: 'ul' },\n ],\n toDOM() {\n return ['div', { class: 'ab-bullet-list', role: 'list' }, 0];\n },\n },\n\n orderedList: {\n content: 'listItem+',\n group: 'block',\n attrs: { start: { default: 1 } },\n parseDOM: [\n {\n tag: 'div.ab-ordered-list',\n getAttrs(dom) {\n return { start: Number((dom as HTMLElement).dataset.start) || 1 };\n },\n },\n {\n tag: 'ol',\n getAttrs(dom) {\n return { start: (dom as HTMLOListElement).start || 1 };\n },\n },\n ],\n toDOM(node) {\n const attrs: Record<string, string> = { class: 'ab-ordered-list', role: 'list' };\n if (node.attrs.start !== 1) attrs['data-start'] = String(node.attrs.start);\n return ['div', attrs, 0];\n },\n },\n\n listItem: {\n content: 'block+',\n attrs: { checked: { default: null } },\n parseDOM: [\n {\n tag: 'div.ab-list-item',\n getAttrs(dom) {\n const el = dom as HTMLElement;\n if (el.dataset.checked != null) {\n return { checked: el.dataset.checked === 'true' };\n }\n return { checked: null };\n },\n },\n {\n tag: 'li',\n getAttrs(dom) {\n const el = dom as HTMLLIElement;\n const checkbox = el.querySelector('input[type=\"checkbox\"]');\n if (checkbox) {\n return { checked: (checkbox as HTMLInputElement).checked };\n }\n if (el.dataset.checked != null) {\n return { checked: el.dataset.checked === 'true' };\n }\n return { checked: null };\n },\n },\n ],\n toDOM(node) {\n const attrs: Record<string, string> = { class: 'ab-list-item', role: 'listitem' };\n if (node.attrs.checked != null) {\n attrs.class = 'ab-list-item todo-item';\n attrs['data-checked'] = String(node.attrs.checked);\n }\n return ['div', attrs, 0];\n },\n defining: true,\n },\n\n blockquote: {\n content: 'block+',\n group: 'block',\n parseDOM: [{ tag: 'blockquote' }],\n toDOM() {\n return ['blockquote', 0];\n },\n defining: true,\n },\n\n codeBlock: {\n content: 'text*',\n group: 'block',\n code: true,\n defining: true,\n marks: '',\n attrs: { language: { default: null } },\n parseDOM: [\n {\n tag: 'pre',\n preserveWhitespace: 'full' as const,\n getAttrs(dom) {\n const code = (dom as HTMLElement).querySelector('code');\n return { language: code?.getAttribute('data-language') || null };\n },\n },\n ],\n toDOM(node) {\n const attrs: Record<string, string> = {};\n if (node.attrs.language) attrs['data-language'] = node.attrs.language;\n return ['pre', ['code', attrs, 0]];\n },\n },\n\n jinjaIfBlock: {\n content: 'jinjaIfBranch+',\n group: 'block',\n isolating: true,\n defining: true,\n parseDOM: [{ tag: 'div[data-jinja-if-block]' }],\n toDOM() {\n return ['div', { 'data-jinja-if-block': '', class: 'jinja-if-block' }, 0];\n },\n },\n\n jinjaIfBranch: {\n content: 'block+',\n isolating: true,\n defining: true,\n attrs: {\n branchType: { default: 'if' },\n condition: { default: '' },\n },\n parseDOM: [\n {\n tag: 'div[data-jinja-branch]',\n getAttrs(dom) {\n const el = dom as HTMLElement;\n return {\n branchType: el.getAttribute('data-branch-type') || 'if',\n condition: el.getAttribute('data-condition') || '',\n };\n },\n },\n ],\n toDOM(node) {\n return [\n 'div',\n {\n 'data-jinja-branch': '',\n 'data-branch-type': node.attrs.branchType,\n 'data-condition': node.attrs.condition,\n class: `jinja-branch jinja-branch-${node.attrs.branchType}`,\n },\n 0,\n ];\n },\n },\n\n horizontalRule: {\n group: 'block',\n parseDOM: [{ tag: 'hr' }],\n toDOM() {\n return ['hr'];\n },\n },\n\n // ── Table nodes ──\n\n table: {\n content: 'tableRow+',\n group: 'block',\n tableRole: 'table',\n isolating: true,\n parseDOM: [{ tag: 'table' }],\n toDOM() {\n return ['table', ['tbody', 0]];\n },\n },\n\n tableRow: {\n content: '(tableCell | tableHeader)+',\n tableRole: 'row',\n parseDOM: [{ tag: 'tr' }],\n toDOM() {\n return ['tr', 0];\n },\n },\n\n tableCell: {\n content: 'inline*',\n tableRole: 'cell',\n attrs: {\n colspan: { default: 1 },\n rowspan: { default: 1 },\n },\n isolating: true,\n parseDOM: [\n {\n tag: 'td',\n getAttrs(dom) {\n const el = dom as HTMLTableCellElement;\n return {\n colspan: el.colSpan || 1,\n rowspan: el.rowSpan || 1,\n };\n },\n },\n ],\n toDOM(node) {\n const attrs: Record<string, string | number> = {};\n if (node.attrs.colspan !== 1) attrs.colspan = node.attrs.colspan;\n if (node.attrs.rowspan !== 1) attrs.rowspan = node.attrs.rowspan;\n return ['td', attrs, 0];\n },\n },\n\n tableHeader: {\n content: 'inline*',\n tableRole: 'header_cell',\n attrs: {\n colspan: { default: 1 },\n rowspan: { default: 1 },\n },\n isolating: true,\n parseDOM: [\n {\n tag: 'th',\n getAttrs(dom) {\n const el = dom as HTMLTableCellElement;\n return {\n colspan: el.colSpan || 1,\n rowspan: el.rowSpan || 1,\n };\n },\n },\n ],\n toDOM(node) {\n const attrs: Record<string, string | number> = {};\n if (node.attrs.colspan !== 1) attrs.colspan = node.attrs.colspan;\n if (node.attrs.rowspan !== 1) attrs.rowspan = node.attrs.rowspan;\n return ['th', attrs, 0];\n },\n },\n\n text: {\n group: 'inline',\n },\n\n inlineToolTag: {\n group: 'inline',\n inline: true,\n atom: true,\n attrs: {\n type: { default: 'tool' },\n resourceId: { default: '' },\n text: { default: '' },\n },\n toDOM(node) {\n return [\n 'span',\n {\n class: 'inline-tool-tag',\n 'data-type': node.attrs.type,\n 'data-resource-id': node.attrs.resourceId,\n },\n node.attrs.text,\n ];\n },\n parseDOM: [\n {\n tag: 'span.inline-tool-tag',\n getAttrs(dom) {\n const el = dom as HTMLElement;\n return {\n type: el.getAttribute('data-type') || 'tool',\n resourceId: el.getAttribute('data-resource-id') || '',\n text: el.textContent || '',\n };\n },\n },\n ],\n },\n\n jumpPoint: {\n group: 'inline',\n inline: true,\n atom: true,\n attrs: {\n id: { default: '' },\n },\n toDOM(node) {\n return [\n 'span',\n {\n class: 'jump-point',\n 'data-jump-point-id': node.attrs.id,\n },\n `^${node.attrs.id}^`,\n ];\n },\n parseDOM: [\n {\n tag: 'span.jump-point',\n getAttrs(dom) {\n return {\n id: (dom as HTMLElement).getAttribute('data-jump-point-id') || '',\n };\n },\n },\n ],\n },\n\n hardBreak: {\n group: 'inline',\n inline: true,\n selectable: false,\n parseDOM: [{ tag: 'br' }],\n toDOM() {\n return ['br'];\n },\n },\n },\n\n marks: {\n bold: {\n parseDOM: [\n { tag: 'strong' },\n { tag: 'b', getAttrs: (node) => (node as HTMLElement).style.fontWeight !== 'normal' && null },\n {\n style: 'font-weight',\n getAttrs: (value) => /^(bold(er)?|[5-9]\\d{2,})$/.test(value as string) && null,\n },\n ],\n toDOM() {\n return ['strong', 0];\n },\n },\n\n italic: {\n parseDOM: [\n { tag: 'em' },\n { tag: 'i', getAttrs: (node) => (node as HTMLElement).style.fontStyle !== 'normal' && null },\n {\n style: 'font-style',\n getAttrs: (value) => (value as string) === 'italic' && null,\n },\n ],\n toDOM() {\n return ['em', 0];\n },\n },\n\n underline: {\n parseDOM: [\n { tag: 'u' },\n {\n style: 'text-decoration',\n getAttrs: (value) => (value as string).includes('underline') && null,\n },\n ],\n toDOM() {\n return ['u', 0];\n },\n },\n\n strikethrough: {\n parseDOM: [\n { tag: 's' },\n { tag: 'del' },\n { tag: 'strike' },\n {\n style: 'text-decoration',\n getAttrs: (value) => (value as string).includes('line-through') && null,\n },\n ],\n toDOM() {\n return ['s', 0];\n },\n },\n\n code: {\n parseDOM: [{ tag: 'code' }],\n toDOM() {\n return ['code', 0];\n },\n },\n\n link: {\n attrs: {\n href: { default: '' },\n title: { default: null },\n },\n inclusive: false,\n parseDOM: [\n {\n tag: 'a[href]',\n getAttrs(dom) {\n return {\n href: (dom as HTMLElement).getAttribute('href'),\n title: (dom as HTMLElement).getAttribute('title'),\n };\n },\n },\n ],\n toDOM(node) {\n const { href, title } = node.attrs;\n return ['a', { href, title, rel: 'noopener noreferrer nofollow' }, 0];\n },\n },\n\n diffMark: {\n attrs: {\n type: { default: 'added' },\n },\n parseDOM: [\n {\n tag: 'span[data-diff-type]',\n getAttrs(dom) {\n return { type: (dom as HTMLElement).getAttribute('data-diff-type') || 'added' };\n },\n },\n ],\n toDOM(node) {\n return ['span', { 'data-diff-type': node.attrs.type, class: `diff-${node.attrs.type}` }, 0];\n },\n },\n },\n});\n","import { Plugin } from 'prosemirror-state';\nimport { keymap } from 'prosemirror-keymap';\nimport { inputRules } from 'prosemirror-inputrules';\nimport type { ActionbookPlugin, NodeViewFactory } from './types';\n\n/**\n * Converts ActionbookPlugin[] into a flat array of PM Plugins.\n * Merges inputRules and keymaps from all plugins.\n *\n * Priority order (ProseMirror tries plugins in array order — first wins):\n * 1. Merged inputRules — highest priority for text-input transforms\n * 2. Merged keymap — custom handlers (e.g. splitListItem on Enter)\n * 3. Raw PM plugins — baseline behaviors (history, baseKeymap, etc.)\n *\n * Putting the merged keymap BEFORE raw plugins ensures that handlers like\n * `splitListItem` on Enter take priority over `baseKeymap`'s `splitBlock`.\n */\nexport function createPluginArray(plugins: ActionbookPlugin[]): {\n pmPlugins: Plugin[];\n nodeViews: Record<string, NodeViewFactory>;\n} {\n const rawPlugins: Plugin[] = [];\n const allNodeViews: Record<string, NodeViewFactory> = {};\n const allInputRules: import('prosemirror-inputrules').InputRule[] = [];\n const allKeymaps: Record<string, import('prosemirror-state').Command> = {};\n\n for (const plugin of plugins) {\n if (plugin.plugins) {\n rawPlugins.push(...plugin.plugins());\n }\n if (plugin.inputRules) {\n allInputRules.push(...plugin.inputRules());\n }\n if (plugin.keymap) {\n for (const [key, handler] of Object.entries(plugin.keymap())) {\n const prev = allKeymaps[key];\n // Chain: if an earlier plugin already claimed this key, run it first;\n // fall through to the new handler only if the earlier one returns false.\n allKeymaps[key] = prev\n ? (state, dispatch, view) => prev(state, dispatch, view) || handler(state, dispatch, view)\n : handler;\n }\n }\n if (plugin.nodeViews) {\n Object.assign(allNodeViews, plugin.nodeViews());\n }\n }\n\n const pmPlugins: Plugin[] = [];\n\n // 1. Input rules first (text-input events, no conflict with keydown)\n if (allInputRules.length > 0) {\n pmPlugins.push(inputRules({ rules: allInputRules }));\n }\n\n // 2. Merged keymap before raw plugins so custom handlers win on key conflicts\n if (Object.keys(allKeymaps).length > 0) {\n pmPlugins.push(keymap(allKeymaps));\n }\n\n // 3. Raw PM plugins (history, baseKeymap, etc.) as fallback\n pmPlugins.push(...rawPlugins);\n\n return { pmPlugins, nodeViews: allNodeViews };\n}\n","import React, { type ReactElement } from 'react';\nimport type {\n DocumentNode,\n BlockNode,\n InlineNode,\n AstNode,\n Mark,\n} from '../../ast/types';\nimport {\n IconAnchor,\n IconHandoff,\n IconManual,\n IconMessageTemplate,\n IconTimeDiff,\n IconTool,\n} from './icons';\n\nexport interface ActionbookRendererProps {\n doc: DocumentNode;\n className?: string;\n /** Custom node renderer for extension points */\n renderNode?: (node: AstNode, defaultRender: () => ReactElement) => ReactElement;\n}\n\n// Color values matching Feather design tokens used in sbdashboard.\nconst RESOURCE_TAG_COLORS: Record<string, string> = {\n tool: '#027D69', // green-6\n manual: '#5959D3', // blue-6\n agent_message_template: '#8012B3', // violet-6\n handoff: '#D25309', // orange-6\n time_diff: '#FB6B6B', // data-viz-4 (red-4)\n};\nconst DEFAULT_RESOURCE_TAG_COLOR = '#027D69';\n\ntype IconComponent = typeof IconTool;\nconst RESOURCE_TAG_ICONS: Record<string, IconComponent> = {\n tool: IconTool,\n manual: IconManual,\n agent_message_template: IconMessageTemplate,\n handoff: IconHandoff,\n time_diff: IconTimeDiff,\n};\nconst DEFAULT_RESOURCE_TAG_ICON = IconTool;\n\nfunction renderMark(mark: Mark, children: ReactElement, key: string): ReactElement {\n switch (mark.type) {\n case 'bold':\n return <strong key={key}>{children}</strong>;\n case 'italic':\n return <em key={key}>{children}</em>;\n case 'underline':\n return <u key={key}>{children}</u>;\n case 'strikethrough':\n return <s key={key}>{children}</s>;\n case 'code':\n return <code key={key}>{children}</code>;\n case 'link':\n return (\n <a key={key} href={mark.href} title={mark.title} rel=\"noopener noreferrer nofollow\">\n {children}\n </a>\n );\n }\n}\n\nfunction wrapWithMarks(text: string, marks: readonly Mark[] | undefined, key: string): ReactElement {\n let element: ReactElement = <React.Fragment key={key}>{text}</React.Fragment>;\n if (!marks || marks.length === 0) return element;\n for (let i = 0; i < marks.length; i++) {\n element = renderMark(marks[i], element, `${key}-m${i}`);\n }\n return element;\n}\n\nfunction renderInline(\n node: InlineNode,\n key: string,\n renderNode?: ActionbookRendererProps['renderNode'],\n): ReactElement {\n const defaultRender = (): ReactElement => {\n switch (node.type) {\n case 'text':\n return wrapWithMarks(node.text, node.marks, key);\n case 'resourceTag': {\n const color = RESOURCE_TAG_COLORS[node.tagType] ?? DEFAULT_RESOURCE_TAG_COLOR;\n const Icon = RESOURCE_TAG_ICONS[node.tagType] ?? DEFAULT_RESOURCE_TAG_ICON;\n return (\n <span\n key={key}\n className=\"inline-tool-tag\"\n data-type={node.tagType}\n data-resource-id={node.resourceId}\n style={{\n display: 'inline-flex',\n height: '20px',\n padding: '1px',\n border: '1px solid #CCCCCC',\n borderRadius: '2px',\n alignItems: 'center',\n backgroundColor: 'white',\n verticalAlign: 'middle',\n userSelect: 'none',\n }}\n >\n <span\n style={{\n display: 'inline-flex',\n justifyContent: 'center',\n alignItems: 'center',\n width: '16px',\n height: '16px',\n backgroundColor: color,\n borderRadius: '2px',\n flexShrink: 0,\n }}\n >\n <Icon size={9} fill=\"white\" />\n </span>\n <span\n style={{\n padding: '0 4px',\n color,\n fontSize: '11px',\n lineHeight: 1,\n userSelect: 'none',\n }}\n >\n {node.text}\n </span>\n </span>\n );\n }\n case 'jumpPoint':\n return (\n <span\n key={key}\n className=\"jump-point\"\n data-jump-point-id={node.id}\n id={`jp-${node.id}`}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n backgroundColor: '#FFF2B6',\n border: '1px solid #FFC233',\n color: '#AA5D04',\n borderRadius: '4px',\n height: 'max(20px, 1em)',\n padding: '0 max(0.3em, 2px)',\n fontSize: 'max(0.9em, 14px)',\n lineHeight: '0.9em',\n verticalAlign: 'middle',\n userSelect: 'none',\n }}\n >\n <IconAnchor\n size={12}\n fill=\"#AA5D04\"\n style={{ marginRight: 'max(0.15em, 2px)', flexShrink: 0 }}\n />\n {node.id}\n </span>\n );\n case 'hardBreak':\n return <br key={key} />;\n default:\n return <span key={key} />;\n }\n };\n\n if (renderNode) return renderNode(node, defaultRender);\n return defaultRender();\n}\n\nfunction renderInlineContent(\n content: readonly InlineNode[],\n keyPrefix: string,\n renderNode?: ActionbookRendererProps['renderNode'],\n): ReactElement[] {\n return content.map((node, i) => renderInline(node, `${keyPrefix}-${i}`, renderNode));\n}\n\nfunction renderBlock(\n node: BlockNode,\n key: string,\n renderNode?: ActionbookRendererProps['renderNode'],\n): ReactElement {\n const defaultRender = (): ReactElement => {\n switch (node.type) {\n case 'paragraph':\n return <p key={key}>{renderInlineContent(node.content, key, renderNode)}</p>;\n case 'heading': {\n const Tag = `h${node.level}` as keyof JSX.IntrinsicElements;\n return <Tag key={key}>{renderInlineContent(node.content, key, renderNode)}</Tag>;\n }\n case 'bulletList':\n return (\n <ul key={key}>\n {node.content.map((item, i) => renderBlock(item, `${key}-${i}`, renderNode))}\n </ul>\n );\n case 'orderedList':\n return (\n <ol key={key} start={node.start !== 1 ? node.start : undefined}>\n {node.content.map((item, i) => renderBlock(item, `${key}-${i}`, renderNode))}\n </ol>\n );\n case 'listItem':\n if (node.checked != null) {\n return (\n <li key={key} style={{ display: 'flex', alignItems: 'flex-start', listStyle: 'none' }}>\n <input\n type=\"checkbox\"\n checked={node.checked}\n readOnly\n style={{ marginRight: 6, marginTop: 4, flexShrink: 0 }}\n />\n <div style={node.checked ? { textDecoration: 'line-through', opacity: 0.6 } : undefined}>\n {node.content.map((child, i) => renderBlock(child, `${key}-${i}`, renderNode))}\n </div>\n </li>\n );\n }\n return (\n <li key={key}>\n {node.content.map((child, i) => renderBlock(child, `${key}-${i}`, renderNode))}\n </li>\n );\n case 'blockquote':\n return (\n <blockquote key={key}>\n {node.content.map((child, i) => renderBlock(child, `${key}-${i}`, renderNode))}\n </blockquote>\n );\n case 'horizontalRule':\n return <hr key={key} />;\n case 'table':\n return (\n <table key={key}>\n <tbody>\n {node.content.map((row, ri) => (\n <tr key={`${key}-r${ri}`}>\n {row.content.map((cell, ci) => {\n const CellTag = cell.header ? 'th' : 'td';\n return (\n <CellTag key={`${key}-r${ri}-c${ci}`}>\n {renderInlineContent(cell.content, `${key}-r${ri}-c${ci}`, renderNode)}\n </CellTag>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n );\n default:\n return <div key={key} />;\n }\n };\n\n if (renderNode) return renderNode(node, defaultRender);\n return defaultRender();\n}\n\nexport function ActionbookRenderer({ doc, className, renderNode }: ActionbookRendererProps): ReactElement {\n return (\n <div className={className}>\n {doc.content.map((node, i) => renderBlock(node, `ab-${i}`, renderNode))}\n </div>\n );\n}\n","/**\n * Inline SVG icons copied from sbdashboard/app/feather/components/icons/svg/.\n * Intentionally minimal — no external icon library required.\n */\nimport React from 'react';\n\ninterface IconProps {\n size?: number;\n fill?: string;\n style?: React.CSSProperties;\n}\n\n/** SBiDeveloperResources — used for \"tool\" resource tags */\nexport function IconTool({ size = 16, fill = 'currentColor', style }: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill={fill}\n style={style}\n >\n <path d=\"m14.064 3.649-6 16 1.873.702 6-16-1.873-.702ZM6.293 5.793.086 12l6.207 6.207 1.414-1.414L2.914 12l4.793-4.793-1.414-1.414ZM17.707 5.793 23.914 12l-6.207 6.207-1.414-1.414L21.086 12l-4.793-4.793 1.414-1.414Z\" />\n </svg>\n );\n}\n\n/** SBiDivide — used for \"manual\" resource tags */\nexport function IconManual({ size = 16, fill = 'currentColor', style }: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill={fill}\n style={style}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M18.5 4C19.3284 4 20 4.67157 20 5.5C20 6.32843 19.3284 7 18.5 7C17.6716 7 17 6.32843 17 5.5C17 4.67157 17.6716 4 18.5 4ZM18.5 2C16.9145 2 15.5752 3.05426 15.1449 4.5H10.5V11H8.91946C8.57612 9.42741 7.17556 8.25 5.5 8.25C3.567 8.25 2 9.817 2 11.75C2 13.683 3.567 15.25 5.5 15.25C6.9926 15.25 8.26697 14.3157 8.77019 13H10.5V19.5H15.1449C15.5752 20.9457 16.9145 22 18.5 22C20.433 22 22 20.433 22 18.5C22 16.567 20.433 15 18.5 15C16.9145 15 15.5752 16.0543 15.1449 17.5H12.5V13V11V6.5H15.1449C15.5752 7.94574 16.9145 9 18.5 9C20.433 9 22 7.433 22 5.5C22 3.567 20.433 2 18.5 2ZM17 18.5C17 17.6716 17.6716 17 18.5 17C19.3284 17 20 17.6716 20 18.5C20 19.3284 19.3284 20 18.5 20C17.6716 20 17 19.3284 17 18.5ZM5.5 10.25C6.32843 10.25 7 10.9216 7 11.75C7 12.5784 6.32843 13.25 5.5 13.25C4.67157 13.25 4 12.5784 4 11.75C4 10.9216 4.67157 10.25 5.5 10.25Z\"\n />\n </svg>\n );\n}\n\n/** SBiReplyTemplate — used for \"agent_message_template\" resource tags */\nexport function IconMessageTemplate({ size = 16, fill = 'currentColor', style }: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill={fill}\n style={style}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M2 4.5A2.5 2.5 0 0 1 4.5 2h15A2.5 2.5 0 0 1 22 4.5v11a2.5 2.5 0 0 1-2.5 2.5H6l-4 4V4.5Zm2 12.672L5.172 16H19.5a.5.5 0 0 0 .5-.5v-11a.5.5 0 0 0-.5-.5h-15a.5.5 0 0 0-.5.5v12.672Z\"\n />\n <path d=\"m12 12.404 2.781 1.687-.738-3.179L16.5 8.774l-3.236-.276L12 5.5l-1.264 2.998-3.236.276 2.457 2.138-.738 3.179L12 12.404Z\" />\n </svg>\n );\n}\n\n/** SBiAgents — used for \"handoff\" resource tags */\nexport function IconHandoff({ size = 16, fill = 'currentColor', style }: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill={fill}\n style={style}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 4a8 8 0 0 0-8 8v4a3 3 0 1 1 6 0v3a3 3 0 1 1-6 0v-.5H2V12C2 6.477 6.477 2 12 2s10 4.477 10 10v6.5h-2v.5a3 3 0 1 1-6 0v-3a3 3 0 1 1 6 0v-4a8 8 0 0 0-8-8ZM8 16v3a1 1 0 1 1-2 0v-3a1 1 0 1 1 2 0Zm10 3v-3a1 1 0 1 0-2 0v3a1 1 0 1 0 2 0Z\"\n />\n </svg>\n );\n}\n\n/** SBiTime — used for \"time_diff\" resource tags */\nexport function IconTimeDiff({ size = 16, fill = 'currentColor', style }: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill={fill}\n style={style}\n >\n <path d=\"M12.485 6.244h-2v6.618l4.553 2.277.895-1.79-3.448-1.723V6.244Z\" />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10Zm8-10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z\"\n />\n </svg>\n );\n}\n\n/** SBiAnchor — used for jump points */\nexport function IconAnchor({ size = 16, fill = 'currentColor', style }: IconProps) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 16 16\"\n width={size}\n height={size}\n fill={fill}\n style={style}\n >\n <g fillRule=\"evenodd\" clipPath=\"url(#anchor-clip)\" clipRule=\"evenodd\">\n <path d=\"M8 5.333a2.667 2.667 0 1 1 0 5.333 2.667 2.667 0 0 1 0-5.333Zm0 1.333a1.333 1.333 0 1 0 0 2.667 1.333 1.333 0 0 0 0-2.667Z\" />\n <path d=\"M8.667 2.037a6 6 0 0 1 5.295 5.296h1.371v1.333h-1.37a6 6 0 0 1-5.296 5.295v1.372H7.333V13.96a6 6 0 0 1-5.295-5.295H.667V7.333h1.37a6 6 0 0 1 5.296-5.296V.666h1.334v1.371ZM8 3.333a4.667 4.667 0 1 0 0 9.333 4.667 4.667 0 0 0 0-9.333Z\" />\n </g>\n <defs>\n <clipPath id=\"anchor-clip\">\n <path d=\"M0 0H16V16H0z\" transform=\"translate(0 -.001)\" />\n </clipPath>\n </defs>\n </svg>\n );\n}\n","import React, { forwardRef } from 'react';\n\nexport interface EditorShellProps {\n className?: string;\n style?: React.CSSProperties;\n}\n\n/**\n * Contenteditable container for ProseMirror EditorView.\n * Pass the ref from `useEditorView().viewRef` to mount the editor.\n */\nexport const EditorShell = forwardRef<HTMLDivElement, EditorShellProps>(function EditorShell(\n { className, style },\n ref,\n) {\n return <div ref={ref} className={className} style={style} />;\n});\n","import { createElement } from 'react';\nimport { createRoot, type Root } from 'react-dom/client';\nimport type { Node as PMNode } from 'prosemirror-model';\nimport type { Decoration, DecorationSource, EditorView, NodeView } from 'prosemirror-view';\nimport type { NodeViewFactory } from '../plugin/types';\n\nexport interface ReactNodeViewProps {\n node: PMNode;\n view: EditorView;\n getPos: () => number | undefined;\n selected: boolean;\n /** Outer node decorations currently applied to this node. */\n decorations: readonly Decoration[];\n}\n\nexport interface ReactNodeViewOptions {\n /** The React component to render */\n component: React.ComponentType<ReactNodeViewProps>;\n /** Container tag name (default: 'span' for inline, 'div' for block) */\n as?: string;\n /** CSS class name for the container */\n className?: string;\n /** Whether this is an inline node (default: true) */\n inline?: boolean;\n}\n\nclass ReactNodeViewImpl implements NodeView {\n dom: HTMLElement;\n private root: Root;\n private component: React.ComponentType<ReactNodeViewProps>;\n private _node: PMNode;\n private _view: EditorView;\n private _getPos: () => number | undefined;\n private _selected = false;\n private _decorations: readonly Decoration[] = [];\n\n constructor(\n node: PMNode,\n view: EditorView,\n getPos: () => number | undefined,\n options: ReactNodeViewOptions,\n ) {\n this._node = node;\n this._view = view;\n this._getPos = getPos;\n this.component = options.component;\n\n const tag = options.as ?? (options.inline !== false ? 'span' : 'div');\n this.dom = document.createElement(tag);\n if (options.inline !== false) {\n this.dom.style.display = 'inline-flex';\n this.dom.style.verticalAlign = 'middle';\n }\n if (options.className) {\n this.dom.className = options.className;\n }\n\n this.root = createRoot(this.dom);\n this.render();\n }\n\n private render() {\n this.root.render(\n createElement(this.component, {\n node: this._node,\n view: this._view,\n getPos: this._getPos,\n selected: this._selected,\n decorations: this._decorations,\n }),\n );\n }\n\n update(node: PMNode, decorations: readonly Decoration[], _innerDecorations: DecorationSource): boolean {\n if (node.type !== this._node.type) return false;\n this._node = node;\n this._decorations = decorations;\n this.render();\n return true;\n }\n\n selectNode() {\n this._selected = true;\n this.render();\n }\n\n deselectNode() {\n this._selected = false;\n this.render();\n }\n\n destroy() {\n // Defer unmount to avoid flushSync warnings in React 18\n setTimeout(() => this.root.unmount(), 0);\n }\n\n stopEvent() {\n return false;\n }\n\n ignoreMutation() {\n return true;\n }\n}\n\n/**\n * Creates a NodeViewFactory that renders a React component as a PM NodeView.\n *\n * Usage:\n * ```ts\n * const jumpPointPlugin: ActionbookPlugin = {\n * name: 'jumpPoint',\n * nodeViews: () => ({\n * jumpPoint: createReactNodeView({ component: JumpPointView }),\n * }),\n * };\n * ```\n */\nexport function createReactNodeView(options: ReactNodeViewOptions): NodeViewFactory {\n return (node, view, getPos) => new ReactNodeViewImpl(node, view, getPos, options);\n}\n","import { useRef, useEffect, useCallback, useState, type RefObject } from 'react';\nimport { EditorState, type Transaction } from 'prosemirror-state';\nimport { EditorView } from 'prosemirror-view';\nimport { Node as PMNode } from 'prosemirror-model';\nimport type { DocumentNode } from '../../ast/types';\nimport type { LlmCompletionEndpoint } from '../../lint/types';\nimport { fromProseMirrorJSON, type JSONContent } from '../../compat/prosemirror';\nimport { serializeToMarkdown } from '../../markdown/serializer';\nimport { actionbookSchema } from '../schema';\nimport { createPluginArray } from '../plugin/registry';\nimport { toProseMirrorJSON } from '../bridge/toProseMirrorJSON';\nimport type { ActionbookPlugin } from '../plugin/types';\n\nexport interface EditorViewConfig {\n plugins?: ActionbookPlugin[];\n content?: DocumentNode | null;\n editable?: boolean;\n onTransaction?: (state: EditorState) => void;\n onContentChange?: (doc: DocumentNode) => void;\n /**\n * Optional LLM completion endpoint for LLM-based lint rules.\n * When provided, the editor can run async lint rules that leverage LLM analysis.\n * Accepts any backend: OpenAI, Anthropic, Gemini Nano, custom proxy, etc.\n */\n llmCompletionEndpoint?: LlmCompletionEndpoint;\n}\n\nexport interface EditorViewHandle {\n viewRef: RefObject<HTMLDivElement | null>;\n view: EditorView | null;\n getAST: () => DocumentNode | null;\n getMarkdown: () => string;\n setContent: (doc: DocumentNode) => void;\n focus: () => void;\n destroy: () => void;\n}\n\nfunction docToState(doc: DocumentNode | null | undefined, plugins: import('prosemirror-state').Plugin[]): EditorState {\n const pmJSON = doc ? toProseMirrorJSON(doc) : { type: 'doc', content: [{ type: 'paragraph' }] };\n const pmDoc = PMNode.fromJSON(actionbookSchema, pmJSON);\n return EditorState.create({ doc: pmDoc, plugins });\n}\n\nfunction pmDocToAST(pmDoc: PMNode): DocumentNode {\n const json = pmDoc.toJSON() as JSONContent;\n return fromProseMirrorJSON(json);\n}\n\nexport function useEditorView(config: EditorViewConfig): EditorViewHandle {\n const viewRef = useRef<HTMLDivElement | null>(null);\n const viewInstanceRef = useRef<EditorView | null>(null);\n const [, forceUpdate] = useState(0);\n\n // Stable refs for callbacks\n const configRef = useRef(config);\n configRef.current = config;\n\n useEffect(() => {\n const container = viewRef.current;\n if (!container) return;\n\n const { pmPlugins, nodeViews } = createPluginArray(config.plugins ?? []);\n const state = docToState(config.content, pmPlugins);\n\n const view = new EditorView(container, {\n state,\n nodeViews,\n editable: () => configRef.current.editable !== false,\n dispatchTransaction(tr: Transaction) {\n const newState = view.state.apply(tr);\n view.updateState(newState);\n configRef.current.onTransaction?.(newState);\n if (tr.docChanged) {\n const ast = pmDocToAST(newState.doc);\n configRef.current.onContentChange?.(ast);\n }\n },\n });\n\n viewInstanceRef.current = view;\n forceUpdate((n) => n + 1);\n\n return () => {\n view.destroy();\n viewInstanceRef.current = null;\n };\n // Only re-create on mount/unmount. Plugin and content changes are handled imperatively.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const getAST = useCallback((): DocumentNode | null => {\n const view = viewInstanceRef.current;\n if (!view) return null;\n return pmDocToAST(view.state.doc);\n }, []);\n\n const getMarkdown = useCallback((): string => {\n const ast = getAST();\n if (!ast) return '';\n return serializeToMarkdown(ast);\n }, [getAST]);\n\n const setContent = useCallback((doc: DocumentNode) => {\n const view = viewInstanceRef.current;\n if (!view) return;\n const pmJSON = toProseMirrorJSON(doc);\n const pmDoc = PMNode.fromJSON(actionbookSchema, pmJSON);\n const tr = view.state.tr.replaceWith(0, view.state.doc.content.size, pmDoc.content);\n view.dispatch(tr);\n }, []);\n\n const focus = useCallback(() => {\n viewInstanceRef.current?.focus();\n }, []);\n\n const destroy = useCallback(() => {\n viewInstanceRef.current?.destroy();\n viewInstanceRef.current = null;\n }, []);\n\n return {\n viewRef,\n view: viewInstanceRef.current,\n getAST,\n getMarkdown,\n setContent,\n focus,\n destroy,\n };\n}\n","/**\n * Convert ProseMirror/Tiptap JSONContent to ActionbookAST.\n *\n * This handles the legacy editor_data format stored in LogicV2.\n */\nimport type {\n DocumentNode,\n BlockNode,\n InlineNode,\n Mark,\n ResourceTagType,\n TableNode,\n TableRowNode,\n TableCellNode,\n} from '../ast/types';\n\nconst MAX_DEPTH = 128;\nconst ALLOWED_URL_PROTOCOLS = /^(https?:|mailto:|tel:|#|\\/)/i;\n\n// Minimal JSONContent type (compatible with @tiptap/core)\nexport type JSONContent = {\n type?: string;\n attrs?: Record<string, unknown>;\n content?: JSONContent[];\n marks?: { type: string; attrs?: Record<string, unknown> }[];\n text?: string;\n};\n\nfunction convertPMMark(mark: { type: string; attrs?: Record<string, unknown> }): Mark | null {\n switch (mark.type) {\n case 'bold':\n return { type: 'bold' };\n case 'italic':\n return { type: 'italic' };\n case 'underline':\n return { type: 'underline' };\n case 'strikethrough':\n return { type: 'strikethrough' };\n case 'code':\n return { type: 'code' };\n case 'link': {\n const rawHref = (mark.attrs?.href as string) ?? '';\n // Strip dangerous URL protocols\n if (!ALLOWED_URL_PROTOCOLS.test(rawHref)) return null;\n const title = mark.attrs?.title as string | undefined;\n return title ? { type: 'link', href: rawHref, title } : { type: 'link', href: rawHref };\n }\n // Ignored marks (UI-only or unused)\n case 'diffMark':\n case 'inlineResource':\n case 'textStyle':\n return null;\n default:\n return null;\n }\n}\n\nfunction convertPMInline(node: JSONContent, depth: number): InlineNode[] {\n if (depth > MAX_DEPTH) return [];\n const type = node.type ?? '';\n\n switch (type) {\n case 'text': {\n const marks = (node.marks ?? []).map(convertPMMark).filter((m): m is Mark => m !== null);\n const textNode = node.text ?? '';\n return marks.length > 0 ? [{ type: 'text', text: textNode, marks }] : [{ type: 'text', text: textNode }];\n }\n\n case 'inlineToolTag': {\n const attrs = node.attrs ?? {};\n return [\n {\n type: 'resourceTag',\n tagType: (attrs.type as ResourceTagType) ?? 'tool',\n resourceId: (attrs.resourceId as string) ?? '',\n text: (attrs.text as string) ?? '',\n },\n ];\n }\n\n case 'jumpPoint': {\n const id = (node.attrs?.id as string) ?? '';\n return [{ type: 'jumpPoint', id }];\n }\n\n case 'hardBreak':\n return [{ type: 'hardBreak' }];\n\n default:\n if (node.text) {\n return [{ type: 'text', text: node.text }];\n }\n if (node.content) {\n return node.content.flatMap((c) => convertPMInline(c, depth + 1));\n }\n return [];\n }\n}\n\nfunction convertPMBlock(node: JSONContent, depth: number = 0): BlockNode[] {\n if (depth > MAX_DEPTH) return [];\n const type = node.type ?? '';\n const children = node.content ?? [];\n\n switch (type) {\n case 'paragraph':\n return [{ type: 'paragraph', content: children.flatMap((c) => convertPMInline(c, depth + 1)) }];\n\n case 'heading': {\n const level = ((node.attrs?.level as number) ?? 1) as 1 | 2 | 3 | 4 | 5 | 6;\n return [{ type: 'heading', level, content: children.flatMap((c) => convertPMInline(c, depth + 1)) }];\n }\n\n case 'bulletList':\n return [\n {\n type: 'bulletList',\n content: children.map((c) => convertPMListItem(c, depth + 1)),\n },\n ];\n\n case 'orderedList': {\n const start = (node.attrs?.start as number) ?? 1;\n return [\n {\n type: 'orderedList',\n start,\n content: children.map((c) => convertPMListItem(c, depth + 1)),\n },\n ];\n }\n\n case 'listItem': {\n return [convertPMListItem(node, depth)];\n }\n\n case 'blockquote':\n return [{ type: 'blockquote', content: children.flatMap((c) => convertPMBlock(c, depth + 1)) }];\n\n case 'horizontalRule':\n return [{ type: 'horizontalRule' }];\n\n case 'table': {\n const rows: TableRowNode[] = children.map((rowNode) => {\n const cells: TableCellNode[] = (rowNode.content ?? []).map((cellNode) => {\n const cellType = cellNode.type ?? '';\n const isHeader = cellType === 'tableHeader';\n const inlines = (cellNode.content ?? []).flatMap((c) => convertPMInline(c, depth + 3));\n return {\n type: 'tableCell' as const,\n ...(isHeader ? { header: true } : {}),\n content: inlines,\n };\n });\n return { type: 'tableRow' as const, content: cells };\n });\n return [{ type: 'table', content: rows }];\n }\n\n default:\n if (children.length > 0) {\n return children.flatMap((c) => convertPMBlock(c, depth + 1));\n }\n return [];\n }\n}\n\nfunction convertPMListItem(node: JSONContent, depth: number = 0): { type: 'listItem'; checked?: boolean | null; content: BlockNode[] } {\n if (depth > MAX_DEPTH) return { type: 'listItem', content: [{ type: 'paragraph', content: [] }] };\n const children = node.content ?? [];\n const content = children.flatMap((c) => convertPMBlock(c, depth + 1));\n const checked = node.attrs?.checked as boolean | null | undefined;\n const base: { type: 'listItem'; checked?: boolean | null; content: BlockNode[] } = {\n type: 'listItem',\n content: content.length > 0 ? content : [{ type: 'paragraph', content: [] }],\n };\n if (typeof checked === 'boolean') {\n base.checked = checked;\n }\n return base;\n}\n\nexport function fromProseMirrorJSON(pmJSON: JSONContent): DocumentNode {\n if (pmJSON.type !== 'doc') {\n const blocks = convertPMBlock(pmJSON, 0);\n return { type: 'doc', content: blocks.length > 0 ? blocks : [{ type: 'paragraph', content: [] }] };\n }\n\n const children = pmJSON.content ?? [];\n const blocks = children.flatMap((c) => convertPMBlock(c, 0));\n return { type: 'doc', content: blocks.length > 0 ? blocks : [{ type: 'paragraph', content: [] }] };\n}\n","import type { Parents, Text } from 'mdast';\nimport { defaultHandlers, toMarkdown } from 'mdast-util-to-markdown';\nimport type { Handle, Info, Options, State } from 'mdast-util-to-markdown';\nimport { gfmFootnoteToMarkdown } from 'mdast-util-gfm-footnote';\nimport { gfmStrikethroughToMarkdown } from 'mdast-util-gfm-strikethrough';\nimport { gfmTableToMarkdown } from 'mdast-util-gfm-table';\nimport { gfmTaskListItemToMarkdown } from 'mdast-util-gfm-task-list-item';\nimport { resourceTagToMarkdown } from './plugins/resourceTag';\nimport { jumpPointToMarkdown } from './plugins/jumpPoint';\nimport { toMdast } from './mdastAdapter';\nimport type { DocumentNode } from '../ast/types';\n\n// GFM without autolink literal — see parser.ts for rationale.\nconst gfmNoAutolinkToMarkdown = () => ({\n extensions: [\n gfmFootnoteToMarkdown(),\n gfmStrikethroughToMarkdown(),\n gfmTableToMarkdown(),\n gfmTaskListItemToMarkdown(),\n ],\n});\n\nfunction isEmptyParagraph(node: Parents | { type: string; children?: unknown[] }): boolean {\n return node.type === 'paragraph' && (!('children' in node) || !node.children || node.children.length === 0);\n}\n\n/**\n * Custom text handler that prevents unnecessary `_` escaping in inline text.\n *\n * mdast-util-to-markdown's default unsafe rules include\n * `{character: '_', inConstruct: 'phrasing'}`, which escapes every underscore\n * in paragraph/heading text (e.g. `ENUM_VALUE` → `ENUM\\_VALUE`). Since we\n * generate emphasis and strong with `*`, underscores in plain text are never\n * interpreted as emphasis markers and do not need escaping.\n *\n * The `unsafe` option in `toMarkdown` is ADDITIVE (it pushes into the default\n * list, never replaces it), so we cannot override this via options alone.\n * Instead, we temporarily remove the phrasing-`_` rule from `state.unsafe`\n * before delegating to the default text handler.\n */\nfunction textHandler(node: Text, parent: Parents | undefined, state: State, info: Info): string {\n const originalUnsafe = state.unsafe;\n state.unsafe = originalUnsafe.filter((p) => !(p.character === '_' && !p.atBreak));\n const result = (defaultHandlers.text as Options['handlers'] & ((n: Text, p: Parents | undefined, s: State, i: Info) => string))(node, parent, state, info);\n state.unsafe = originalUnsafe;\n return result;\n}\n\nexport function serializeToMarkdown(doc: DocumentNode): string {\n const mdastTree = toMdast(doc);\n\n const result = toMarkdown(mdastTree, {\n bullet: '-',\n rule: '-',\n listItemIndent: 'one',\n emphasis: '*',\n strong: '*',\n resourceLink: true,\n join: [\n // Empty paragraphs represent blank-line spacers.\n // Reduce the separator after an empty paragraph from \\n\\n to \\n\n // so that 1 empty paragraph = 1 extra blank line in the output.\n (left) => (isEmptyParagraph(left) ? 0 : null),\n ],\n handlers: {\n text: textHandler as Handle,\n ...resourceTagToMarkdown().handlers,\n ...jumpPointToMarkdown().handlers,\n },\n extensions: [gfmNoAutolinkToMarkdown()],\n });\n\n return result;\n}\n","export function deprecate(fn) {\n return fn\n}\n\nexport function equal() {}\n\nexport function ok() {}\n\nexport function unreachable() {}\n","/**\n * Normalize an identifier (as found in references, definitions).\n *\n * Collapses markdown whitespace, trim, and then lower- and uppercase.\n *\n * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their\n * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different\n * uppercase character (U+0398 (`Θ`)).\n * So, to get a canonical form, we perform both lower- and uppercase.\n *\n * Using uppercase last makes sure keys will never interact with default\n * prototypal values (such as `constructor`): nothing in the prototype of\n * `Object` is uppercase.\n *\n * @param {string} value\n * Identifier to normalize.\n * @returns {string}\n * Normalized identifier.\n */\nexport function normalizeIdentifier(value) {\n return value\n // Collapse markdown whitespace.\n .replace(/[\\t\\n\\r ]+/g, \" \")\n // Trim.\n .replace(/^ | $/g, '')\n // Some characters are considered “uppercase”, but if their lowercase\n // counterpart is uppercased will result in a different uppercase\n // character.\n // Hence, to get that form, we perform both lower- and uppercase.\n // Upper case makes sure keys will not interact with default prototypal\n // methods: no method is uppercase.\n .toLowerCase().toUpperCase();\n}","/**\n * @import {\n * CompileContext,\n * Extension as FromMarkdownExtension,\n * Handle as FromMarkdownHandle\n * } from 'mdast-util-from-markdown'\n * @import {ToMarkdownOptions} from 'mdast-util-gfm-footnote'\n * @import {\n * Handle as ToMarkdownHandle,\n * Map,\n * Options as ToMarkdownExtension\n * } from 'mdast-util-to-markdown'\n * @import {FootnoteDefinition, FootnoteReference} from 'mdast'\n */\n\nimport {ok as assert} from 'devlop'\nimport {normalizeIdentifier} from 'micromark-util-normalize-identifier'\n\nfootnoteReference.peek = footnoteReferencePeek\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterFootnoteCallString() {\n this.buffer()\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterFootnoteCall(token) {\n this.enter({type: 'footnoteReference', identifier: '', label: ''}, token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterFootnoteDefinitionLabelString() {\n this.buffer()\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterFootnoteDefinition(token) {\n this.enter(\n {type: 'footnoteDefinition', identifier: '', label: '', children: []},\n token\n )\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitFootnoteCallString(token) {\n const label = this.resume()\n const node = this.stack[this.stack.length - 1]\n assert(node.type === 'footnoteReference')\n node.identifier = normalizeIdentifier(\n this.sliceSerialize(token)\n ).toLowerCase()\n node.label = label\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitFootnoteCall(token) {\n this.exit(token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitFootnoteDefinitionLabelString(token) {\n const label = this.resume()\n const node = this.stack[this.stack.length - 1]\n assert(node.type === 'footnoteDefinition')\n node.identifier = normalizeIdentifier(\n this.sliceSerialize(token)\n ).toLowerCase()\n node.label = label\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitFootnoteDefinition(token) {\n this.exit(token)\n}\n\n/** @type {ToMarkdownHandle} */\nfunction footnoteReferencePeek() {\n return '['\n}\n\n/**\n * @type {ToMarkdownHandle}\n * @param {FootnoteReference} node\n */\nfunction footnoteReference(node, _, state, info) {\n const tracker = state.createTracker(info)\n let value = tracker.move('[^')\n const exit = state.enter('footnoteReference')\n const subexit = state.enter('reference')\n value += tracker.move(\n state.safe(state.associationId(node), {after: ']', before: value})\n )\n subexit()\n exit()\n value += tracker.move(']')\n return value\n}\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM footnotes\n * in markdown.\n *\n * @returns {FromMarkdownExtension}\n * Extension for `mdast-util-from-markdown`.\n */\nexport function gfmFootnoteFromMarkdown() {\n return {\n enter: {\n gfmFootnoteCallString: enterFootnoteCallString,\n gfmFootnoteCall: enterFootnoteCall,\n gfmFootnoteDefinitionLabelString: enterFootnoteDefinitionLabelString,\n gfmFootnoteDefinition: enterFootnoteDefinition\n },\n exit: {\n gfmFootnoteCallString: exitFootnoteCallString,\n gfmFootnoteCall: exitFootnoteCall,\n gfmFootnoteDefinitionLabelString: exitFootnoteDefinitionLabelString,\n gfmFootnoteDefinition: exitFootnoteDefinition\n }\n }\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM footnotes\n * in markdown.\n *\n * @param {ToMarkdownOptions | null | undefined} [options]\n * Configuration (optional).\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown`.\n */\nexport function gfmFootnoteToMarkdown(options) {\n // To do: next major: change default.\n let firstLineBlank = false\n\n if (options && options.firstLineBlank) {\n firstLineBlank = true\n }\n\n return {\n handlers: {footnoteDefinition, footnoteReference},\n // This is on by default already.\n unsafe: [{character: '[', inConstruct: ['label', 'phrasing', 'reference']}]\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {FootnoteDefinition} node\n */\n function footnoteDefinition(node, _, state, info) {\n const tracker = state.createTracker(info)\n let value = tracker.move('[^')\n const exit = state.enter('footnoteDefinition')\n const subexit = state.enter('label')\n value += tracker.move(\n state.safe(state.associationId(node), {before: value, after: ']'})\n )\n subexit()\n\n value += tracker.move(']:')\n\n if (node.children && node.children.length > 0) {\n tracker.shift(4)\n\n value += tracker.move(\n (firstLineBlank ? '\\n' : ' ') +\n state.indentLines(\n state.containerFlow(node, tracker.current()),\n firstLineBlank ? mapAll : mapExceptFirst\n )\n )\n }\n\n exit()\n\n return value\n }\n}\n\n/** @type {Map} */\nfunction mapExceptFirst(line, index, blank) {\n return index === 0 ? line : mapAll(line, index, blank)\n}\n\n/** @type {Map} */\nfunction mapAll(line, index, blank) {\n return (blank ? '' : ' ') + line\n}\n","/**\n * @typedef {import('mdast').Delete} Delete\n *\n * @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext\n * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension\n * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle\n *\n * @typedef {import('mdast-util-to-markdown').ConstructName} ConstructName\n * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle\n * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension\n */\n\n/**\n * List of constructs that occur in phrasing (paragraphs, headings), but cannot\n * contain strikethrough.\n * So they sort of cancel each other out.\n * Note: could use a better name.\n *\n * Note: keep in sync with: <https://github.com/syntax-tree/mdast-util-to-markdown/blob/8ce8dbf/lib/unsafe.js#L14>\n *\n * @type {Array<ConstructName>}\n */\nconst constructsWithoutStrikethrough = [\n 'autolink',\n 'destinationLiteral',\n 'destinationRaw',\n 'reference',\n 'titleQuote',\n 'titleApostrophe'\n]\n\nhandleDelete.peek = peekDelete\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM\n * strikethrough in markdown.\n *\n * @returns {FromMarkdownExtension}\n * Extension for `mdast-util-from-markdown` to enable GFM strikethrough.\n */\nexport function gfmStrikethroughFromMarkdown() {\n return {\n canContainEols: ['delete'],\n enter: {strikethrough: enterStrikethrough},\n exit: {strikethrough: exitStrikethrough}\n }\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM\n * strikethrough in markdown.\n *\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown` to enable GFM strikethrough.\n */\nexport function gfmStrikethroughToMarkdown() {\n return {\n unsafe: [\n {\n character: '~',\n inConstruct: 'phrasing',\n notInConstruct: constructsWithoutStrikethrough\n }\n ],\n handlers: {delete: handleDelete}\n }\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterStrikethrough(token) {\n this.enter({type: 'delete', children: []}, token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitStrikethrough(token) {\n this.exit(token)\n}\n\n/**\n * @type {ToMarkdownHandle}\n * @param {Delete} node\n */\nfunction handleDelete(node, _, state, info) {\n const tracker = state.createTracker(info)\n const exit = state.enter('strikethrough')\n let value = tracker.move('~~')\n value += state.containerPhrasing(node, {\n ...tracker.current(),\n before: value,\n after: '~'\n })\n value += tracker.move('~~')\n exit()\n return value\n}\n\n/** @type {ToMarkdownHandle} */\nfunction peekDelete() {\n return '~'\n}\n","// To do: next major: remove.\n/**\n * @typedef {Options} MarkdownTableOptions\n * Configuration.\n */\n\n/**\n * @typedef Options\n * Configuration.\n * @property {boolean | null | undefined} [alignDelimiters=true]\n * Whether to align the delimiters (default: `true`);\n * they are aligned by default:\n *\n * ```markdown\n * | Alpha | B |\n * | ----- | ----- |\n * | C | Delta |\n * ```\n *\n * Pass `false` to make them staggered:\n *\n * ```markdown\n * | Alpha | B |\n * | - | - |\n * | C | Delta |\n * ```\n * @property {ReadonlyArray<string | null | undefined> | string | null | undefined} [align]\n * How to align columns (default: `''`);\n * one style for all columns or styles for their respective columns;\n * each style is either `'l'` (left), `'r'` (right), or `'c'` (center);\n * other values are treated as `''`, which doesn’t place the colon in the\n * alignment row but does align left;\n * *only the lowercased first character is used, so `Right` is fine.*\n * @property {boolean | null | undefined} [delimiterEnd=true]\n * Whether to end each row with the delimiter (default: `true`).\n *\n * > 👉 **Note**: please don’t use this: it could create fragile structures\n * > that aren’t understandable to some markdown parsers.\n *\n * When `true`, there are ending delimiters:\n *\n * ```markdown\n * | Alpha | B |\n * | ----- | ----- |\n * | C | Delta |\n * ```\n *\n * When `false`, there are no ending delimiters:\n *\n * ```markdown\n * | Alpha | B\n * | ----- | -----\n * | C | Delta\n * ```\n * @property {boolean | null | undefined} [delimiterStart=true]\n * Whether to begin each row with the delimiter (default: `true`).\n *\n * > 👉 **Note**: please don’t use this: it could create fragile structures\n * > that aren’t understandable to some markdown parsers.\n *\n * When `true`, there are starting delimiters:\n *\n * ```markdown\n * | Alpha | B |\n * | ----- | ----- |\n * | C | Delta |\n * ```\n *\n * When `false`, there are no starting delimiters:\n *\n * ```markdown\n * Alpha | B |\n * ----- | ----- |\n * C | Delta |\n * ```\n * @property {boolean | null | undefined} [padding=true]\n * Whether to add a space of padding between delimiters and cells\n * (default: `true`).\n *\n * When `true`, there is padding:\n *\n * ```markdown\n * | Alpha | B |\n * | ----- | ----- |\n * | C | Delta |\n * ```\n *\n * When `false`, there is no padding:\n *\n * ```markdown\n * |Alpha|B |\n * |-----|-----|\n * |C |Delta|\n * ```\n * @property {((value: string) => number) | null | undefined} [stringLength]\n * Function to detect the length of table cell content (optional);\n * this is used when aligning the delimiters (`|`) between table cells;\n * full-width characters and emoji mess up delimiter alignment when viewing\n * the markdown source;\n * to fix this, you can pass this function,\n * which receives the cell content and returns its “visible” size;\n * note that what is and isn’t visible depends on where the text is displayed.\n *\n * Without such a function, the following:\n *\n * ```js\n * markdownTable([\n * ['Alpha', 'Bravo'],\n * ['中文', 'Charlie'],\n * ['👩‍❤️‍👩', 'Delta']\n * ])\n * ```\n *\n * Yields:\n *\n * ```markdown\n * | Alpha | Bravo |\n * | - | - |\n * | 中文 | Charlie |\n * | 👩‍❤️‍👩 | Delta |\n * ```\n *\n * With [`string-width`](https://github.com/sindresorhus/string-width):\n *\n * ```js\n * import stringWidth from 'string-width'\n *\n * markdownTable(\n * [\n * ['Alpha', 'Bravo'],\n * ['中文', 'Charlie'],\n * ['👩‍❤️‍👩', 'Delta']\n * ],\n * {stringLength: stringWidth}\n * )\n * ```\n *\n * Yields:\n *\n * ```markdown\n * | Alpha | Bravo |\n * | ----- | ------- |\n * | 中文 | Charlie |\n * | 👩‍❤️‍👩 | Delta |\n * ```\n */\n\n/**\n * @param {string} value\n * Cell value.\n * @returns {number}\n * Cell size.\n */\nfunction defaultStringLength(value) {\n return value.length\n}\n\n/**\n * Generate a markdown\n * ([GFM](https://docs.github.com/en/github/writing-on-github/working-with-advanced-formatting/organizing-information-with-tables))\n * table.\n *\n * @param {ReadonlyArray<ReadonlyArray<string | null | undefined>>} table\n * Table data (matrix of strings).\n * @param {Readonly<Options> | null | undefined} [options]\n * Configuration (optional).\n * @returns {string}\n * Result.\n */\nexport function markdownTable(table, options) {\n const settings = options || {}\n // To do: next major: change to spread.\n const align = (settings.align || []).concat()\n const stringLength = settings.stringLength || defaultStringLength\n /** @type {Array<number>} Character codes as symbols for alignment per column. */\n const alignments = []\n /** @type {Array<Array<string>>} Cells per row. */\n const cellMatrix = []\n /** @type {Array<Array<number>>} Sizes of each cell per row. */\n const sizeMatrix = []\n /** @type {Array<number>} */\n const longestCellByColumn = []\n let mostCellsPerRow = 0\n let rowIndex = -1\n\n // This is a superfluous loop if we don’t align delimiters, but otherwise we’d\n // do superfluous work when aligning, so optimize for aligning.\n while (++rowIndex < table.length) {\n /** @type {Array<string>} */\n const row = []\n /** @type {Array<number>} */\n const sizes = []\n let columnIndex = -1\n\n if (table[rowIndex].length > mostCellsPerRow) {\n mostCellsPerRow = table[rowIndex].length\n }\n\n while (++columnIndex < table[rowIndex].length) {\n const cell = serialize(table[rowIndex][columnIndex])\n\n if (settings.alignDelimiters !== false) {\n const size = stringLength(cell)\n sizes[columnIndex] = size\n\n if (\n longestCellByColumn[columnIndex] === undefined ||\n size > longestCellByColumn[columnIndex]\n ) {\n longestCellByColumn[columnIndex] = size\n }\n }\n\n row.push(cell)\n }\n\n cellMatrix[rowIndex] = row\n sizeMatrix[rowIndex] = sizes\n }\n\n // Figure out which alignments to use.\n let columnIndex = -1\n\n if (typeof align === 'object' && 'length' in align) {\n while (++columnIndex < mostCellsPerRow) {\n alignments[columnIndex] = toAlignment(align[columnIndex])\n }\n } else {\n const code = toAlignment(align)\n\n while (++columnIndex < mostCellsPerRow) {\n alignments[columnIndex] = code\n }\n }\n\n // Inject the alignment row.\n columnIndex = -1\n /** @type {Array<string>} */\n const row = []\n /** @type {Array<number>} */\n const sizes = []\n\n while (++columnIndex < mostCellsPerRow) {\n const code = alignments[columnIndex]\n let before = ''\n let after = ''\n\n if (code === 99 /* `c` */) {\n before = ':'\n after = ':'\n } else if (code === 108 /* `l` */) {\n before = ':'\n } else if (code === 114 /* `r` */) {\n after = ':'\n }\n\n // There *must* be at least one hyphen-minus in each alignment cell.\n let size =\n settings.alignDelimiters === false\n ? 1\n : Math.max(\n 1,\n longestCellByColumn[columnIndex] - before.length - after.length\n )\n\n const cell = before + '-'.repeat(size) + after\n\n if (settings.alignDelimiters !== false) {\n size = before.length + size + after.length\n\n if (size > longestCellByColumn[columnIndex]) {\n longestCellByColumn[columnIndex] = size\n }\n\n sizes[columnIndex] = size\n }\n\n row[columnIndex] = cell\n }\n\n // Inject the alignment row.\n cellMatrix.splice(1, 0, row)\n sizeMatrix.splice(1, 0, sizes)\n\n rowIndex = -1\n /** @type {Array<string>} */\n const lines = []\n\n while (++rowIndex < cellMatrix.length) {\n const row = cellMatrix[rowIndex]\n const sizes = sizeMatrix[rowIndex]\n columnIndex = -1\n /** @type {Array<string>} */\n const line = []\n\n while (++columnIndex < mostCellsPerRow) {\n const cell = row[columnIndex] || ''\n let before = ''\n let after = ''\n\n if (settings.alignDelimiters !== false) {\n const size =\n longestCellByColumn[columnIndex] - (sizes[columnIndex] || 0)\n const code = alignments[columnIndex]\n\n if (code === 114 /* `r` */) {\n before = ' '.repeat(size)\n } else if (code === 99 /* `c` */) {\n if (size % 2) {\n before = ' '.repeat(size / 2 + 0.5)\n after = ' '.repeat(size / 2 - 0.5)\n } else {\n before = ' '.repeat(size / 2)\n after = before\n }\n } else {\n after = ' '.repeat(size)\n }\n }\n\n if (settings.delimiterStart !== false && !columnIndex) {\n line.push('|')\n }\n\n if (\n settings.padding !== false &&\n // Don’t add the opening space if we’re not aligning and the cell is\n // empty: there will be a closing space.\n !(settings.alignDelimiters === false && cell === '') &&\n (settings.delimiterStart !== false || columnIndex)\n ) {\n line.push(' ')\n }\n\n if (settings.alignDelimiters !== false) {\n line.push(before)\n }\n\n line.push(cell)\n\n if (settings.alignDelimiters !== false) {\n line.push(after)\n }\n\n if (settings.padding !== false) {\n line.push(' ')\n }\n\n if (\n settings.delimiterEnd !== false ||\n columnIndex !== mostCellsPerRow - 1\n ) {\n line.push('|')\n }\n }\n\n lines.push(\n settings.delimiterEnd === false\n ? line.join('').replace(/ +$/, '')\n : line.join('')\n )\n }\n\n return lines.join('\\n')\n}\n\n/**\n * @param {string | null | undefined} [value]\n * Value to serialize.\n * @returns {string}\n * Result.\n */\nfunction serialize(value) {\n return value === null || value === undefined ? '' : String(value)\n}\n\n/**\n * @param {string | null | undefined} value\n * Value.\n * @returns {number}\n * Alignment.\n */\nfunction toAlignment(value) {\n const code = typeof value === 'string' ? value.codePointAt(0) : 0\n\n return code === 67 /* `C` */ || code === 99 /* `c` */\n ? 99 /* `c` */\n : code === 76 /* `L` */ || code === 108 /* `l` */\n ? 108 /* `l` */\n : code === 82 /* `R` */ || code === 114 /* `r` */\n ? 114 /* `r` */\n : 0\n}\n","/**\n * @typedef {import('mdast').InlineCode} InlineCode\n * @typedef {import('mdast').Table} Table\n * @typedef {import('mdast').TableCell} TableCell\n * @typedef {import('mdast').TableRow} TableRow\n *\n * @typedef {import('markdown-table').Options} MarkdownTableOptions\n *\n * @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext\n * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension\n * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle\n *\n * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension\n * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle\n * @typedef {import('mdast-util-to-markdown').State} State\n * @typedef {import('mdast-util-to-markdown').Info} Info\n */\n\n/**\n * @typedef Options\n * Configuration.\n * @property {boolean | null | undefined} [tableCellPadding=true]\n * Whether to add a space of padding between delimiters and cells (default:\n * `true`).\n * @property {boolean | null | undefined} [tablePipeAlign=true]\n * Whether to align the delimiters (default: `true`).\n * @property {MarkdownTableOptions['stringLength'] | null | undefined} [stringLength]\n * Function to detect the length of table cell content, used when aligning\n * the delimiters between cells (optional).\n */\n\nimport {ok as assert} from 'devlop'\nimport {markdownTable} from 'markdown-table'\nimport {defaultHandlers} from 'mdast-util-to-markdown'\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM tables in\n * markdown.\n *\n * @returns {FromMarkdownExtension}\n * Extension for `mdast-util-from-markdown` to enable GFM tables.\n */\nexport function gfmTableFromMarkdown() {\n return {\n enter: {\n table: enterTable,\n tableData: enterCell,\n tableHeader: enterCell,\n tableRow: enterRow\n },\n exit: {\n codeText: exitCodeText,\n table: exitTable,\n tableData: exit,\n tableHeader: exit,\n tableRow: exit\n }\n }\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterTable(token) {\n const align = token._align\n assert(align, 'expected `_align` on table')\n this.enter(\n {\n type: 'table',\n align: align.map(function (d) {\n return d === 'none' ? null : d\n }),\n children: []\n },\n token\n )\n this.data.inTable = true\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitTable(token) {\n this.exit(token)\n this.data.inTable = undefined\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterRow(token) {\n this.enter({type: 'tableRow', children: []}, token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exit(token) {\n this.exit(token)\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction enterCell(token) {\n this.enter({type: 'tableCell', children: []}, token)\n}\n\n// Overwrite the default code text data handler to unescape escaped pipes when\n// they are in tables.\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitCodeText(token) {\n let value = this.resume()\n\n if (this.data.inTable) {\n value = value.replace(/\\\\([\\\\|])/g, replace)\n }\n\n const node = this.stack[this.stack.length - 1]\n assert(node.type === 'inlineCode')\n node.value = value\n this.exit(token)\n}\n\n/**\n * @param {string} $0\n * @param {string} $1\n * @returns {string}\n */\nfunction replace($0, $1) {\n // Pipes work, backslashes don’t (but can’t escape pipes).\n return $1 === '|' ? $1 : $0\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM tables in\n * markdown.\n *\n * @param {Options | null | undefined} [options]\n * Configuration.\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown` to enable GFM tables.\n */\nexport function gfmTableToMarkdown(options) {\n const settings = options || {}\n const padding = settings.tableCellPadding\n const alignDelimiters = settings.tablePipeAlign\n const stringLength = settings.stringLength\n const around = padding ? ' ' : '|'\n\n return {\n unsafe: [\n {character: '\\r', inConstruct: 'tableCell'},\n {character: '\\n', inConstruct: 'tableCell'},\n // A pipe, when followed by a tab or space (padding), or a dash or colon\n // (unpadded delimiter row), could result in a table.\n {atBreak: true, character: '|', after: '[\\t :-]'},\n // A pipe in a cell must be encoded.\n {character: '|', inConstruct: 'tableCell'},\n // A colon must be followed by a dash, in which case it could start a\n // delimiter row.\n {atBreak: true, character: ':', after: '-'},\n // A delimiter row can also start with a dash, when followed by more\n // dashes, a colon, or a pipe.\n // This is a stricter version than the built in check for lists, thematic\n // breaks, and setex heading underlines though:\n // <https://github.com/syntax-tree/mdast-util-to-markdown/blob/51a2038/lib/unsafe.js#L57>\n {atBreak: true, character: '-', after: '[:|-]'}\n ],\n handlers: {\n inlineCode: inlineCodeWithTable,\n table: handleTable,\n tableCell: handleTableCell,\n tableRow: handleTableRow\n }\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {Table} node\n */\n function handleTable(node, _, state, info) {\n return serializeData(handleTableAsData(node, state, info), node.align)\n }\n\n /**\n * This function isn’t really used normally, because we handle rows at the\n * table level.\n * But, if someone passes in a table row, this ensures we make somewhat sense.\n *\n * @type {ToMarkdownHandle}\n * @param {TableRow} node\n */\n function handleTableRow(node, _, state, info) {\n const row = handleTableRowAsData(node, state, info)\n const value = serializeData([row])\n // `markdown-table` will always add an align row\n return value.slice(0, value.indexOf('\\n'))\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {TableCell} node\n */\n function handleTableCell(node, _, state, info) {\n const exit = state.enter('tableCell')\n const subexit = state.enter('phrasing')\n const value = state.containerPhrasing(node, {\n ...info,\n before: around,\n after: around\n })\n subexit()\n exit()\n return value\n }\n\n /**\n * @param {Array<Array<string>>} matrix\n * @param {Array<string | null | undefined> | null | undefined} [align]\n */\n function serializeData(matrix, align) {\n return markdownTable(matrix, {\n align,\n // @ts-expect-error: `markdown-table` types should support `null`.\n alignDelimiters,\n // @ts-expect-error: `markdown-table` types should support `null`.\n padding,\n // @ts-expect-error: `markdown-table` types should support `null`.\n stringLength\n })\n }\n\n /**\n * @param {Table} node\n * @param {State} state\n * @param {Info} info\n */\n function handleTableAsData(node, state, info) {\n const children = node.children\n let index = -1\n /** @type {Array<Array<string>>} */\n const result = []\n const subexit = state.enter('table')\n\n while (++index < children.length) {\n result[index] = handleTableRowAsData(children[index], state, info)\n }\n\n subexit()\n\n return result\n }\n\n /**\n * @param {TableRow} node\n * @param {State} state\n * @param {Info} info\n */\n function handleTableRowAsData(node, state, info) {\n const children = node.children\n let index = -1\n /** @type {Array<string>} */\n const result = []\n const subexit = state.enter('tableRow')\n\n while (++index < children.length) {\n // Note: the positional info as used here is incorrect.\n // Making it correct would be impossible due to aligning cells?\n // And it would need copy/pasting `markdown-table` into this project.\n result[index] = handleTableCell(children[index], node, state, info)\n }\n\n subexit()\n\n return result\n }\n\n /**\n * @type {ToMarkdownHandle}\n * @param {InlineCode} node\n */\n function inlineCodeWithTable(node, parent, state) {\n let value = defaultHandlers.inlineCode(node, parent, state)\n\n if (state.stack.includes('tableCell')) {\n value = value.replace(/\\|/g, '\\\\$&')\n }\n\n return value\n }\n}\n","/**\n * @typedef {import('mdast').ListItem} ListItem\n * @typedef {import('mdast').Paragraph} Paragraph\n * @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext\n * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension\n * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle\n * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension\n * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle\n */\n\nimport {ok as assert} from 'devlop'\nimport {defaultHandlers} from 'mdast-util-to-markdown'\n\n/**\n * Create an extension for `mdast-util-from-markdown` to enable GFM task\n * list items in markdown.\n *\n * @returns {FromMarkdownExtension}\n * Extension for `mdast-util-from-markdown` to enable GFM task list items.\n */\nexport function gfmTaskListItemFromMarkdown() {\n return {\n exit: {\n taskListCheckValueChecked: exitCheck,\n taskListCheckValueUnchecked: exitCheck,\n paragraph: exitParagraphWithTaskListItem\n }\n }\n}\n\n/**\n * Create an extension for `mdast-util-to-markdown` to enable GFM task list\n * items in markdown.\n *\n * @returns {ToMarkdownExtension}\n * Extension for `mdast-util-to-markdown` to enable GFM task list items.\n */\nexport function gfmTaskListItemToMarkdown() {\n return {\n unsafe: [{atBreak: true, character: '-', after: '[:|-]'}],\n handlers: {listItem: listItemWithTaskListItem}\n }\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitCheck(token) {\n // We’re always in a paragraph, in a list item.\n const node = this.stack[this.stack.length - 2]\n assert(node.type === 'listItem')\n node.checked = token.type === 'taskListCheckValueChecked'\n}\n\n/**\n * @this {CompileContext}\n * @type {FromMarkdownHandle}\n */\nfunction exitParagraphWithTaskListItem(token) {\n const parent = this.stack[this.stack.length - 2]\n\n if (\n parent &&\n parent.type === 'listItem' &&\n typeof parent.checked === 'boolean'\n ) {\n const node = this.stack[this.stack.length - 1]\n assert(node.type === 'paragraph')\n const head = node.children[0]\n\n if (head && head.type === 'text') {\n const siblings = parent.children\n let index = -1\n /** @type {Paragraph | undefined} */\n let firstParaghraph\n\n while (++index < siblings.length) {\n const sibling = siblings[index]\n if (sibling.type === 'paragraph') {\n firstParaghraph = sibling\n break\n }\n }\n\n if (firstParaghraph === node) {\n // Must start with a space or a tab.\n head.value = head.value.slice(1)\n\n if (head.value.length === 0) {\n node.children.shift()\n } else if (\n node.position &&\n head.position &&\n typeof head.position.start.offset === 'number'\n ) {\n head.position.start.column++\n head.position.start.offset++\n node.position.start = Object.assign({}, head.position.start)\n }\n }\n }\n }\n\n this.exit(token)\n}\n\n/**\n * @type {ToMarkdownHandle}\n * @param {ListItem} node\n */\nfunction listItemWithTaskListItem(node, parent, state, info) {\n const head = node.children[0]\n const checkable =\n typeof node.checked === 'boolean' && head && head.type === 'paragraph'\n const checkbox = '[' + (node.checked ? 'x' : ' ') + '] '\n const tracker = state.createTracker(info)\n\n if (checkable) {\n tracker.move(checkbox)\n }\n\n let value = defaultHandlers.listItem(node, parent, state, {\n ...info,\n ...tracker.current()\n })\n\n if (checkable) {\n value = value.replace(/^(?:[*+-]|\\d+\\.)([\\r\\n]| {1,3})/, check)\n }\n\n return value\n\n /**\n * @param {string} $0\n * @returns {string}\n */\n function check($0) {\n return $0 + checkbox\n }\n}\n","/**\n * Micromark syntax extension + mdast extension for resource tags: {{type:resourceId:text}}\n *\n * Instead of a full micromark extension (which requires complex token/state handling),\n * we use mdast-util-from-markdown's transform hook to post-process text nodes.\n * This is simpler and matches the existing regex approach.\n */\nimport type { Root, PhrasingContent, Text } from 'mdast';\n\nconst RESOURCE_TAG_RE = /\\{\\{([^:}]+):([^:}]*):([^}]+)\\}\\}/g;\nconst VALID_TYPES = new Set(['tool', 'manual', 'agent_message_template', 'handoff', 'time_diff']);\nconst MAX_DEPTH = 128;\n\nexport type ResourceTagMdastNode = {\n type: 'resourceTagMdast';\n data: {\n tagType: string;\n resourceId: string;\n };\n value: string;\n};\n\ndeclare module 'mdast' {\n interface PhrasingContentMap {\n resourceTagMdast: ResourceTagMdastNode;\n }\n\n interface RootContentMap {\n resourceTagMdast: ResourceTagMdastNode;\n }\n}\n\nfunction splitTextWithResourceTags(text: string): (Text | ResourceTagMdastNode)[] {\n const results: (Text | ResourceTagMdastNode)[] = [];\n let lastIndex = 0;\n\n RESOURCE_TAG_RE.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = RESOURCE_TAG_RE.exec(text)) !== null) {\n const [full, tagType, resourceId, displayText] = match;\n if (!VALID_TYPES.has(tagType)) continue;\n\n if (match.index > lastIndex) {\n results.push({ type: 'text', value: text.slice(lastIndex, match.index) });\n }\n results.push({\n type: 'resourceTagMdast',\n data: { tagType, resourceId },\n value: displayText,\n });\n lastIndex = match.index + full.length;\n }\n\n if (lastIndex < text.length) {\n results.push({ type: 'text', value: text.slice(lastIndex) });\n }\n\n return results;\n}\n\nfunction visitNode(node: { children?: unknown[] }, depth: number = 0): void {\n if (depth > MAX_DEPTH) return;\n if (!node.children) return;\n for (const child of node.children) {\n visitNode(child as { children?: unknown[] }, depth + 1);\n }\n if (Array.isArray(node.children)) {\n const newChildren: unknown[] = [];\n for (const child of node.children) {\n if ((child as { type: string }).type === 'text') {\n const parts = splitTextWithResourceTags((child as Text).value);\n newChildren.push(...parts);\n } else {\n newChildren.push(child);\n }\n }\n node.children = newChildren;\n }\n}\n\nexport function resourceTagFromMarkdown() {\n return (tree: Root) => {\n visitNode(tree as unknown as { children?: unknown[] }, 0);\n };\n}\n\n/**\n * Exported for use in combined single-pass transform.\n * Returns the per-node text splitter without constructing a full plugin.\n */\nexport { splitTextWithResourceTags };\n\nexport function resourceTagToMarkdown() {\n return {\n handlers: {\n resourceTagMdast(node: ResourceTagMdastNode): string {\n return `{{${node.data.tagType}:${node.data.resourceId}:${node.value}}}`;\n },\n },\n };\n}\n","/**\n * mdast transform for jump points: ^id^\n * id must match /^[A-Za-z_]+$/\n */\nimport type { Root, Text, PhrasingContent } from 'mdast';\n\nconst JUMP_POINT_RE = /\\^([A-Za-z_]+)\\^/g;\nconst MAX_DEPTH = 128;\n\nexport type JumpPointMdastNode = {\n type: 'jumpPointMdast';\n data: {\n id: string;\n };\n value: string;\n};\n\ndeclare module 'mdast' {\n interface PhrasingContentMap {\n jumpPointMdast: JumpPointMdastNode;\n }\n\n interface RootContentMap {\n jumpPointMdast: JumpPointMdastNode;\n }\n}\n\nfunction splitTextWithJumpPoints(text: string): (Text | JumpPointMdastNode)[] {\n const results: (Text | JumpPointMdastNode)[] = [];\n let lastIndex = 0;\n\n JUMP_POINT_RE.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = JUMP_POINT_RE.exec(text)) !== null) {\n const [full, id] = match;\n\n if (match.index > lastIndex) {\n results.push({ type: 'text', value: text.slice(lastIndex, match.index) });\n }\n results.push({\n type: 'jumpPointMdast',\n data: { id },\n value: id,\n });\n lastIndex = match.index + full.length;\n }\n\n if (lastIndex < text.length) {\n results.push({ type: 'text', value: text.slice(lastIndex) });\n }\n\n return results;\n}\n\nfunction visitNode(node: { children?: unknown[] }, depth: number = 0): void {\n if (depth > MAX_DEPTH) return;\n if (!node.children) return;\n for (const child of node.children) {\n visitNode(child as { children?: unknown[] }, depth + 1);\n }\n if (Array.isArray(node.children)) {\n const newChildren: unknown[] = [];\n for (const child of node.children) {\n if ((child as { type: string }).type === 'text') {\n const parts = splitTextWithJumpPoints((child as Text).value);\n newChildren.push(...parts);\n } else {\n newChildren.push(child);\n }\n }\n node.children = newChildren;\n }\n}\n\nexport function jumpPointFromMarkdown() {\n return (tree: Root) => {\n visitNode(tree as unknown as { children?: unknown[] }, 0);\n };\n}\n\n/**\n * Exported for use in combined single-pass transform.\n * Returns the per-node text splitter without constructing a full plugin.\n */\nexport { splitTextWithJumpPoints };\n\nexport function jumpPointToMarkdown() {\n return {\n handlers: {\n jumpPointMdast(node: JumpPointMdastNode): string {\n return `^${node.data.id}^`;\n },\n },\n };\n}\n","/**\n * Bidirectional conversion between mdast and ActionbookAST.\n */\nimport type { Root, RootContent, PhrasingContent, List, ListItem, Paragraph, Heading, Blockquote, ThematicBreak, Text as MdastText, Strong, Emphasis, InlineCode, Link, Break, Delete } from 'mdast';\nimport type { ResourceTagMdastNode } from './plugins/resourceTag';\nimport type { JumpPointMdastNode } from './plugins/jumpPoint';\nimport type { JinjaIfBlockMdastNode, JinjaIfInlineMdastNode, JinjaBranchMdast } from './plugins/jinjaBlock';\nimport type {\n DocumentNode,\n BlockNode,\n InlineNode,\n Mark,\n TextNode,\n ParagraphNode,\n HeadingNode,\n BulletListNode,\n OrderedListNode,\n ListItemNode,\n BlockquoteNode,\n HorizontalRuleNode,\n ResourceTagNode,\n JumpPointNode,\n HardBreakNode,\n TableNode,\n TableRowNode,\n TableCellNode,\n JinjaIfBlockNode,\n JinjaIfInlineNode,\n JinjaIfBranch,\n} from '../ast/types';\n\nconst MAX_DEPTH = 128;\nconst ALLOWED_URL_PROTOCOLS = /^(https?:|mailto:|tel:|#|\\/)/i;\n\nfunction sanitizeUrl(url: string): string {\n if (ALLOWED_URL_PROTOCOLS.test(url)) return url;\n // Strip dangerous protocols (javascript:, data:, vbscript:, etc.)\n return '';\n}\n\nclass DepthError extends Error {\n constructor(depth: number) {\n super(`Maximum mdast conversion depth (${MAX_DEPTH}) exceeded at depth ${depth}`);\n this.name = 'DepthError';\n }\n}\n\n// === mdast → ActionbookAST ===\n\nfunction convertInline(node: PhrasingContent, marks: Mark[] = [], depth: number = 0): InlineNode[] {\n if (depth > MAX_DEPTH) throw new DepthError(depth);\n\n switch (node.type) {\n case 'text':\n return [marks.length > 0 ? { type: 'text', text: node.value, marks } : { type: 'text', text: node.value }];\n\n case 'strong': {\n const childMarks: Mark[] = [...marks, { type: 'bold' }];\n return (node as Strong).children.flatMap((child) => convertInline(child as PhrasingContent, childMarks, depth + 1));\n }\n\n case 'emphasis': {\n const childMarks: Mark[] = [...marks, { type: 'italic' }];\n return (node as Emphasis).children.flatMap((child) => convertInline(child as PhrasingContent, childMarks, depth + 1));\n }\n\n case 'delete': {\n const childMarks: Mark[] = [...marks, { type: 'strikethrough' }];\n return (node as Delete).children.flatMap((child) => convertInline(child as PhrasingContent, childMarks, depth + 1));\n }\n\n case 'inlineCode':\n return [\n marks.length > 0\n ? { type: 'text', text: (node as InlineCode).value, marks: [...marks, { type: 'code' }] }\n : { type: 'text', text: (node as InlineCode).value, marks: [{ type: 'code' }] },\n ];\n\n case 'link': {\n const href = sanitizeUrl((node as Link).url);\n if (!href) {\n // Dangerous URL protocol → strip the link, keep children as plain text\n return (node as Link).children.flatMap((child) => convertInline(child as PhrasingContent, marks, depth + 1));\n }\n const linkMark: Mark = { type: 'link', href, ...((node as Link).title ? { title: (node as Link).title! } : {}) };\n const childMarks: Mark[] = [...marks, linkMark];\n return (node as Link).children.flatMap((child) => convertInline(child as PhrasingContent, childMarks, depth + 1));\n }\n\n case 'break':\n return [{ type: 'hardBreak' }];\n\n case 'resourceTagMdast' as string: {\n const rtNode = node as unknown as ResourceTagMdastNode;\n return [\n {\n type: 'resourceTag',\n tagType: rtNode.data.tagType as ResourceTagNode['tagType'],\n resourceId: rtNode.data.resourceId,\n text: rtNode.value,\n },\n ];\n }\n\n case 'jumpPointMdast' as string: {\n const jpNode = node as unknown as JumpPointMdastNode;\n return [{ type: 'jumpPoint', id: jpNode.data.id }];\n }\n\n case 'jinjaIfInlineMdast' as string: {\n const jNode = node as unknown as JinjaIfInlineMdastNode;\n const branches: JinjaIfBranch<InlineNode>[] = jNode.branches.map(b => ({\n branchType: b.branchType,\n ...(b.condition ? { condition: b.condition } : {}),\n content: (b.content as PhrasingContent[]).flatMap(c => convertInline(c, [], depth + 1)),\n }));\n return [{ type: 'jinjaIfInline', branches } as InlineNode];\n }\n\n default:\n if ('value' in node && typeof (node as { value: unknown }).value === 'string') {\n return [{ type: 'text', text: (node as { value: string }).value }];\n }\n if ('children' in node && Array.isArray((node as { children: unknown[] }).children)) {\n return (node as { children: PhrasingContent[] }).children.flatMap((child) => convertInline(child, marks, depth + 1));\n }\n return [];\n }\n}\n\nfunction convertBlock(node: RootContent, depth: number = 0): BlockNode[] {\n if (depth > MAX_DEPTH) throw new DepthError(depth);\n\n switch (node.type) {\n case 'paragraph': {\n const para = node as Paragraph;\n const content = para.children.flatMap((child) => convertInline(child as PhrasingContent, [], depth + 1));\n return [{ type: 'paragraph', content }];\n }\n\n case 'heading': {\n const h = node as Heading;\n const content = h.children.flatMap((child) => convertInline(child as PhrasingContent, [], depth + 1));\n return [{ type: 'heading', level: h.depth as HeadingNode['level'], content }];\n }\n\n case 'list': {\n const list = node as List;\n const items = list.children.map((li) => convertListItem(li, depth + 1));\n if (list.ordered) {\n return [{ type: 'orderedList', start: list.start ?? 1, content: items }];\n }\n return [{ type: 'bulletList', content: items }];\n }\n\n case 'blockquote': {\n const bq = node as Blockquote;\n const content = bq.children.flatMap((child) => convertBlock(child, depth + 1));\n return [{ type: 'blockquote', content }];\n }\n\n case 'thematicBreak':\n return [{ type: 'horizontalRule' }];\n\n case 'jinjaIfBlockMdast' as string: {\n const jNode = node as unknown as JinjaIfBlockMdastNode;\n const branches: JinjaIfBranch<BlockNode>[] = jNode.branches.map(b => ({\n branchType: b.branchType,\n ...(b.condition ? { condition: b.condition } : {}),\n content: (b.content as RootContent[]).flatMap(c => convertBlock(c, depth + 1)),\n }));\n return [{ type: 'jinjaIfBlock', branches } as BlockNode];\n }\n\n case 'table': {\n const tbl = node as { type: 'table'; children: Array<{ type: 'tableRow'; children: Array<{ type: 'tableCell'; children: PhrasingContent[] }> }>; align?: (string | null)[] };\n const rows: TableRowNode[] = tbl.children.map((row, rowIdx) => {\n const cells: TableCellNode[] = row.children.map((cell) => {\n const content = cell.children.flatMap((child) => convertInline(child as PhrasingContent, [], depth + 2));\n return {\n type: 'tableCell' as const,\n ...(rowIdx === 0 ? { header: true } : {}),\n content,\n };\n });\n return { type: 'tableRow' as const, content: cells };\n });\n return [{ type: 'table', content: rows }];\n }\n\n default:\n if ('children' in node && Array.isArray((node as { children: unknown[] }).children)) {\n const inlines = (node as { children: PhrasingContent[] }).children.flatMap((child) =>\n convertInline(child as PhrasingContent, [], depth + 1),\n );\n if (inlines.length > 0) return [{ type: 'paragraph', content: inlines }];\n }\n if ('value' in node && typeof (node as { value: unknown }).value === 'string') {\n return [{ type: 'paragraph', content: [{ type: 'text', text: (node as { value: string }).value }] }];\n }\n return [];\n }\n}\n\nfunction convertListItem(node: ListItem, depth: number = 0): ListItemNode {\n if (depth > MAX_DEPTH) throw new DepthError(depth);\n const content = node.children.flatMap((child) => convertBlock(child as RootContent, depth + 1));\n const base: ListItemNode = { type: 'listItem', content: content.length > 0 ? content : [{ type: 'paragraph', content: [] }] };\n if (typeof node.checked === 'boolean') {\n return { ...base, checked: node.checked };\n }\n return base;\n}\n\nexport function fromMdast(root: Root): DocumentNode {\n const blocks: BlockNode[] = [];\n\n for (let i = 0; i < root.children.length; i++) {\n // Detect extra blank lines between consecutive blocks and restore as empty paragraphs.\n // Standard markdown block separation = 1 blank line. Each additional blank line\n // maps to one empty paragraph (1:1), matching the serializer's join function\n // that outputs \\n (instead of \\n\\n) after empty paragraphs.\n if (i > 0) {\n const prev = root.children[i - 1] as { position?: { end?: { line?: number } } };\n const curr = root.children[i] as { position?: { start?: { line?: number } } };\n const prevEndLine = prev.position?.end?.line ?? 0;\n const currStartLine = curr.position?.start?.line ?? 0;\n const emptyCount = currStartLine - prevEndLine - 2;\n for (let j = 0; j < emptyCount; j++) {\n blocks.push({ type: 'paragraph', content: [] });\n }\n }\n\n blocks.push(...convertBlock(root.children[i], 0));\n }\n\n return { type: 'doc', content: blocks.length > 0 ? blocks : [{ type: 'paragraph', content: [] }] };\n}\n\n// === ActionbookAST → mdast ===\n\nfunction inlineToMdast(node: InlineNode, depth: number = 0): PhrasingContent[] {\n if (depth > MAX_DEPTH) throw new DepthError(depth);\n\n switch (node.type) {\n case 'text': {\n const marks = node.marks ?? [];\n let result: PhrasingContent[] = [{ type: 'text', value: node.text } as MdastText];\n\n for (const mark of marks) {\n switch (mark.type) {\n case 'bold':\n result = [{ type: 'strong', children: result as Strong['children'] }];\n break;\n case 'italic':\n result = [{ type: 'emphasis', children: result as Emphasis['children'] }];\n break;\n case 'strikethrough':\n result = [{ type: 'delete', children: result as Delete['children'] }];\n break;\n case 'underline':\n // Underline has no markdown representation; mark is lost on serialization\n break;\n case 'code':\n result = [{ type: 'inlineCode', value: node.text }];\n break;\n case 'link':\n result = [\n {\n type: 'link',\n url: mark.href,\n ...(mark.title ? { title: mark.title } : {}),\n children: result as Link['children'],\n },\n ];\n break;\n }\n }\n return result;\n }\n\n case 'resourceTag':\n return [\n {\n type: 'resourceTagMdast',\n data: { tagType: node.tagType, resourceId: node.resourceId },\n value: node.text,\n } as unknown as PhrasingContent,\n ];\n\n case 'jumpPoint':\n return [\n {\n type: 'jumpPointMdast',\n data: { id: node.id },\n value: node.id,\n } as unknown as PhrasingContent,\n ];\n\n case 'hardBreak':\n return [{ type: 'break' } as Break];\n\n case 'jinjaIfInline': {\n const jNode = node as JinjaIfInlineNode;\n const result: PhrasingContent[] = [];\n for (const branch of jNode.branches) {\n const tagText = branch.branchType === 'else'\n ? '{% else %}'\n : `{% ${branch.branchType} ${branch.condition ?? ''} %}`.trim();\n result.push({ type: 'text', value: tagText } as MdastText);\n for (const child of branch.content) {\n result.push(...inlineToMdast(child, depth + 1));\n }\n }\n result.push({ type: 'text', value: '{% endif %}' } as MdastText);\n return result;\n }\n }\n}\n\nfunction blockToMdast(node: BlockNode, depth: number = 0): RootContent[] {\n if (depth > MAX_DEPTH) throw new DepthError(depth);\n\n switch (node.type) {\n case 'paragraph':\n return [{ type: 'paragraph', children: node.content.flatMap((c) => inlineToMdast(c, depth + 1)) }];\n\n case 'heading':\n return [{ type: 'heading', depth: node.level, children: node.content.flatMap((c) => inlineToMdast(c, depth + 1)) }];\n\n case 'bulletList':\n return [\n {\n type: 'list',\n ordered: false,\n spread: false,\n children: node.content.map((li) => listItemToMdast(li, depth + 1)),\n },\n ];\n\n case 'orderedList':\n return [\n {\n type: 'list',\n ordered: true,\n start: node.start,\n spread: false,\n children: node.content.map((li) => listItemToMdast(li, depth + 1)),\n },\n ];\n\n case 'listItem':\n return listItemToMdast(node, depth).children.flatMap((child) => [child as RootContent]);\n\n case 'blockquote':\n return [{ type: 'blockquote', children: node.content.flatMap((c) => blockToMdast(c, depth + 1)) as Blockquote['children'] }];\n\n case 'horizontalRule':\n return [{ type: 'thematicBreak' }];\n\n case 'jinjaIfBlock': {\n const jNode = node as JinjaIfBlockNode;\n const result: RootContent[] = [];\n for (const branch of jNode.branches) {\n const tagText = branch.branchType === 'else'\n ? '{% else %}'\n : `{% ${branch.branchType} ${branch.condition ?? ''} %}`.trim();\n result.push({ type: 'paragraph', children: [{ type: 'text', value: tagText } as MdastText] } as Paragraph);\n for (const child of branch.content) {\n result.push(...blockToMdast(child, depth + 1));\n }\n }\n result.push({ type: 'paragraph', children: [{ type: 'text', value: '{% endif %}' } as MdastText] } as Paragraph);\n return result;\n }\n\n case 'table': {\n const rows = node.content.map((row) => ({\n type: 'tableRow' as const,\n children: row.content.map((cell) => ({\n type: 'tableCell' as const,\n children: cell.content.flatMap((c) => inlineToMdast(c, depth + 2)) as PhrasingContent[],\n })),\n }));\n return [{ type: 'table', children: rows } as unknown as RootContent];\n }\n }\n}\n\nfunction listItemToMdast(node: ListItemNode, depth: number = 0): ListItem {\n if (depth > MAX_DEPTH) throw new DepthError(depth);\n const result: ListItem = {\n type: 'listItem',\n spread: false,\n children: node.content.flatMap((child) => blockToMdast(child, depth + 1)) as ListItem['children'],\n };\n if (typeof node.checked === 'boolean') {\n result.checked = node.checked;\n }\n return result;\n}\n\nexport function toMdast(doc: DocumentNode): Root {\n return {\n type: 'root',\n children: doc.content.flatMap((c) => blockToMdast(c, 0)),\n };\n}\n","/**\n * Convert ActionbookAST → ProseMirror JSONContent.\n */\nimport type { BlockNode, DocumentNode, InlineNode, JinjaIfBlockNode, JinjaIfInlineNode, Mark } from '../../ast/types';\nimport type { JSONContent } from '../../compat/prosemirror';\n\nconst ALLOWED_URL_PROTOCOLS = /^(https?:|mailto:|tel:|#|\\/)/i;\n\nfunction assertNever(value: never): never {\n throw new Error(`Unexpected AST node: ${JSON.stringify(value)}`);\n}\n\nfunction convertMark(mark: Mark): NonNullable<JSONContent['marks']>[number] {\n switch (mark.type) {\n case 'bold':\n return { type: 'bold' };\n case 'italic':\n return { type: 'italic' };\n case 'underline':\n return { type: 'underline' };\n case 'strikethrough':\n return { type: 'strikethrough' };\n case 'code':\n return { type: 'code' };\n case 'link': {\n const href = ALLOWED_URL_PROTOCOLS.test(mark.href) ? mark.href : '';\n return mark.title ? { type: 'link', attrs: { href, title: mark.title } } : { type: 'link', attrs: { href } };\n }\n default:\n return assertNever(mark);\n }\n}\n\nfunction convertInlineToArray(node: InlineNode): JSONContent[] {\n switch (node.type) {\n case 'jinjaIfInline': {\n const jNode = node as JinjaIfInlineNode;\n const parts: JSONContent[] = [];\n for (const branch of jNode.branches) {\n const tagText = branch.branchType === 'else'\n ? '{% else %}'\n : `{% ${branch.branchType} ${branch.condition ?? ''} %}`.trim();\n parts.push({ type: 'text', text: tagText });\n for (const child of branch.content) {\n parts.push(...convertInlineToArray(child));\n }\n }\n parts.push({ type: 'text', text: '{% endif %}' });\n return parts;\n }\n default:\n return [convertInline(node)];\n }\n}\n\nexport function convertInline(node: InlineNode): JSONContent {\n switch (node.type) {\n case 'text': {\n const result: JSONContent = { type: 'text', text: node.text };\n if (node.marks && node.marks.length > 0) {\n result.marks = node.marks.map(convertMark);\n }\n return result;\n }\n case 'resourceTag':\n return {\n type: 'inlineToolTag',\n attrs: {\n type: node.tagType,\n resourceId: node.resourceId,\n text: node.text,\n },\n };\n case 'jumpPoint':\n return {\n type: 'jumpPoint',\n attrs: { id: node.id },\n };\n case 'hardBreak':\n return { type: 'hardBreak' };\n case 'jinjaIfInline': {\n // Flatten to single text node for PM\n const parts = convertInlineToArray(node);\n const fullText = parts.map(p => p.text ?? '').join('');\n return { type: 'text', text: fullText };\n }\n default:\n return assertNever(node as never);\n }\n}\n\nfunction convertBlockToArray(node: BlockNode): JSONContent[] {\n if (node.type === 'jinjaIfBlock') {\n const jNode = node as JinjaIfBlockNode;\n const result: JSONContent[] = [];\n for (const branch of jNode.branches) {\n const tagText = branch.branchType === 'else'\n ? '{% else %}'\n : `{% ${branch.branchType} ${branch.condition ?? ''} %}`.trim();\n result.push({ type: 'paragraph', content: [{ type: 'text', text: tagText }] });\n for (const child of branch.content) {\n result.push(...convertBlockToArray(child));\n }\n }\n result.push({ type: 'paragraph', content: [{ type: 'text', text: '{% endif %}' }] });\n return result;\n }\n return [convertBlock(node)];\n}\n\nexport function convertBlock(node: BlockNode): JSONContent {\n switch (node.type) {\n case 'paragraph':\n return {\n type: 'paragraph',\n content: node.content.flatMap(convertInlineToArray),\n };\n case 'heading':\n return {\n type: 'heading',\n attrs: { level: node.level },\n content: node.content.flatMap(convertInlineToArray),\n };\n case 'bulletList':\n return {\n type: 'bulletList',\n content: node.content.map(convertBlock),\n };\n case 'orderedList':\n return {\n type: 'orderedList',\n attrs: { start: node.start },\n content: node.content.map(convertBlock),\n };\n case 'listItem': {\n const result: JSONContent = {\n type: 'listItem',\n content: node.content.flatMap(convertBlockToArray),\n };\n if (node.checked != null) {\n result.attrs = { checked: node.checked };\n }\n return result;\n }\n case 'blockquote':\n return {\n type: 'blockquote',\n content: node.content.flatMap(convertBlockToArray),\n };\n case 'horizontalRule':\n return { type: 'horizontalRule' };\n case 'table':\n return {\n type: 'table',\n content: node.content.map((row) => ({\n type: 'tableRow',\n content: row.content.map((cell) => ({\n type: cell.header ? 'tableHeader' : 'tableCell',\n content: cell.content.flatMap(convertInlineToArray),\n })),\n })),\n };\n case 'jinjaIfBlock': {\n // Should be handled by convertBlockToArray, but handle here for direct calls\n const jNode = node as JinjaIfBlockNode;\n const result: JSONContent[] = [];\n for (const branch of jNode.branches) {\n const tagText = branch.branchType === 'else'\n ? '{% else %}'\n : `{% ${branch.branchType} ${branch.condition ?? ''} %}`.trim();\n result.push({ type: 'paragraph', content: [{ type: 'text', text: tagText }] });\n for (const child of branch.content) {\n result.push(...convertBlockToArray(child));\n }\n }\n result.push({ type: 'paragraph', content: [{ type: 'text', text: '{% endif %}' }] });\n return result[0] ?? { type: 'paragraph', content: [] };\n }\n default:\n return assertNever(node as never);\n }\n}\n\nexport function toProseMirrorJSON(doc: DocumentNode): JSONContent {\n return {\n type: 'doc',\n content: doc.content.flatMap(convertBlockToArray),\n };\n}\n\n/**\n * Convert parseFragment() output (InlineNode[] | BlockNode[]) to PM JSONContent[].\n * If nodes are inline, wraps them in a single paragraph.\n */\nexport function astNodesToJSONContent(nodes: (InlineNode | BlockNode)[]): JSONContent[] {\n if (nodes.length === 0) return [];\n\n const firstType = nodes[0].type;\n const isInlineFragment =\n firstType === 'text' || firstType === 'resourceTag' || firstType === 'jumpPoint' || firstType === 'hardBreak';\n\n if (isInlineFragment) {\n return [{ type: 'paragraph', content: (nodes as InlineNode[]).flatMap(convertInlineToArray) }];\n }\n\n return (nodes as BlockNode[]).flatMap(convertBlockToArray);\n}\n","import { history } from 'prosemirror-history';\nimport type { ActionbookPlugin } from './types';\n\nexport function createHistoryPlugin(): ActionbookPlugin {\n return {\n name: 'history',\n plugins: () => [history()],\n };\n}\n","/**\n * Input rules for markdown-style text formatting.\n *\n * Provides real-time conversion of typed markdown syntax into ProseMirror nodes/marks:\n *\n * \"- \" or \"* \" → bulletList\n * \"1. \" → orderedList\n * \"- [ ] \" / \"- [x] \" → bulletList with todo item\n * \"^id^\" → jumpPoint (duplicate IDs are rejected)\n * **text** → bold\n * *text* → italic\n * ~~text~~ → strikethrough\n * `text` → inline code\n */\nimport { InputRule, wrappingInputRule } from 'prosemirror-inputrules';\nimport type { MarkType } from 'prosemirror-model';\nimport { actionbookSchema } from '../schema';\nimport type { ActionbookPlugin } from './types';\n\nconst BULLET_LIST_RE = /^\\s*([-*])\\s$/;\nconst ORDERED_LIST_RE = /^(\\d+)\\.\\s$/;\nconst JUMP_POINT_RE = /\\^([A-Za-z_][A-Za-z0-9_]*)\\^$/;\n\n// Inline mark autoformat patterns\n// **text** or __text__ → bold\nconst BOLD_STAR_RE = /(?:^|[^*])\\*\\*([^*]+)\\*\\*$/;\nconst BOLD_UNDER_RE = /(?:^|[^_])__([^_]+)__$/;\n// *text* or _text_ → italic (must not match **)\nconst ITALIC_STAR_RE = /(?:^|[^*])\\*([^*]+)\\*$/;\nconst ITALIC_UNDER_RE = /(?:^|[^_])_([^_]+)_$/;\n// ~~text~~ → strikethrough\nconst STRIKE_RE = /(?:^|[^~])~~([^~]+)~~$/;\n// `text` → inline code\nconst CODE_RE = /(?:^|[^`])`([^`]+)`$/;\n\nfunction markInputRule(pattern: RegExp, markType: MarkType, markerLen: number): InputRule {\n return new InputRule(pattern, (state, match, start, end) => {\n const textContent = match[1];\n // Adjust start to account for possible non-marker character before the opening marker\n const fullMatch = match[0];\n const actualStart = end - fullMatch.length + (fullMatch.length - markerLen * 2 - textContent.length);\n\n const tr = state.tr;\n tr.delete(actualStart, end);\n const textNode = state.schema.text(textContent, [markType.create()]);\n tr.insert(actualStart, textNode);\n return tr;\n });\n}\n\nexport function createInputRulesPlugin(): ActionbookPlugin {\n return {\n name: 'inputRules',\n inputRules: () => {\n const rules: InputRule[] = [];\n\n // \"- \" or \"* \" → bulletList\n rules.push(wrappingInputRule(BULLET_LIST_RE, actionbookSchema.nodes.bulletList));\n\n // \"1. \" → orderedList (preserves start number)\n rules.push(\n wrappingInputRule(ORDERED_LIST_RE, actionbookSchema.nodes.orderedList, (match) => ({\n start: +match[1],\n })),\n );\n\n // \"- [ ] \" or \"- [x] \" → bulletList with checked listItem\n rules.push(\n new InputRule(/^\\s*[-*]\\s\\[([ xX])\\]\\s$/, (state, match, start, end) => {\n const checked = match[1] !== ' ';\n const { bulletList: blType, listItem: liType } = actionbookSchema.nodes;\n const li = liType.create({ checked }, state.schema.nodes.paragraph.create());\n const list = blType.create(null, li);\n return state.tr.delete(start, end).insert(start, list);\n }),\n );\n\n // \"^id^\" → jumpPoint (rejects duplicate IDs)\n const jumpPointType = actionbookSchema.nodes.jumpPoint;\n rules.push(\n new InputRule(JUMP_POINT_RE, (state, match, start, end) => {\n const id = match[1];\n let exists = false;\n state.doc.descendants((node) => {\n if (node.type === jumpPointType && node.attrs.id === id) {\n exists = true;\n return false;\n }\n });\n if (exists) return null;\n return state.tr.delete(start, end).insert(start, jumpPointType.create({ id }));\n }),\n );\n\n // Inline mark input rules\n rules.push(markInputRule(BOLD_STAR_RE, actionbookSchema.marks.bold, 2));\n rules.push(markInputRule(BOLD_UNDER_RE, actionbookSchema.marks.bold, 2));\n rules.push(markInputRule(ITALIC_STAR_RE, actionbookSchema.marks.italic, 1));\n rules.push(markInputRule(ITALIC_UNDER_RE, actionbookSchema.marks.italic, 1));\n rules.push(markInputRule(STRIKE_RE, actionbookSchema.marks.strikethrough, 2));\n rules.push(markInputRule(CODE_RE, actionbookSchema.marks.code, 1));\n\n return rules;\n },\n };\n}\n","/**\n * Keymap plugin for the Actionbook editor.\n *\n * Provides keyboard shortcuts matching the sbdashboard Tiptap editor:\n *\n * Backspace — lift list item out one depth when cursor is at start\n * Tab — sink (indent) list item, or insert tab char\n * Shift-Tab — lift (outdent) list item, or delete tab char\n * Enter — split list item; lift empty list item out of list\n * Shift-Enter — insert hardBreak\n * Mod-Shift-7 — wrap selection in bulletList\n * Mod-Shift-8 — wrap selection in orderedList\n */\nimport { chainCommands, newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock, toggleMark } from 'prosemirror-commands';\nimport { liftListItem, sinkListItem, splitListItem, wrapInList } from 'prosemirror-schema-list';\nimport type { Command } from 'prosemirror-state';\nimport { actionbookSchema } from '../schema';\nimport type { ActionbookPlugin } from './types';\n\nconst TAB_CHAR = '\\u0009';\n\nconst { listItem, bulletList, orderedList, hardBreak } = actionbookSchema.nodes;\nconst { bold: boldMark, italic: italicMark, underline: underlineMark, strikethrough: strikethroughMark, code: codeMark } = actionbookSchema.marks;\n\n/**\n * Returns true only when the cursor's block is the direct child of a listItem.\n * Using `depth - 1` instead of walking all ancestors avoids false positives\n * when a listItem is a distant ancestor (e.g. cursor in a blockquote inside a\n * listItem) — those cases should fall through to the default Backspace handler.\n */\nfunction cursorDirectlyInListItem(state: Parameters<Command>[0]): boolean {\n const { $from } = state.selection;\n return $from.depth >= 2 && $from.node($from.depth - 1).type === listItem;\n}\n\n/**\n * Backspace at the start of a list item → lift one depth out.\n * Prevents the default join-backward behaviour and acts like Shift-Tab.\n */\nconst backspaceCommand: Command = (state, dispatch) => {\n const { $from } = state.selection;\n if (!state.selection.empty) return false;\n if ($from.parentOffset !== 0) return false;\n if (!cursorDirectlyInListItem(state)) return false;\n // Only intercept when cursor is in the FIRST child of the listItem.\n // If cursor is in a later block (e.g. empty paragraph after a nested list),\n // fall through to joinBackward so cursor moves to the end of the previous block.\n if ($from.index($from.depth - 1) !== 0) return false;\n return liftListItem(listItem)(state, dispatch);\n};\n\nconst tabCommand: Command = (state, dispatch) => {\n const { $from } = state.selection;\n if (cursorDirectlyInListItem(state) && $from.parentOffset === 0) {\n if (sinkListItem(listItem)(state, dispatch)) return true;\n }\n if (dispatch) dispatch(state.tr.insertText(TAB_CHAR));\n return true;\n};\n\nconst shiftTabCommand: Command = (state, dispatch) => {\n const { $from } = state.selection;\n if (cursorDirectlyInListItem(state) && $from.parentOffset === 0) {\n return liftListItem(listItem)(state, dispatch);\n }\n const pos = $from.pos;\n if (state.doc.textBetween(pos - 1, pos) === TAB_CHAR) {\n if (dispatch) dispatch(state.tr.delete(pos - 1, pos));\n return true;\n }\n return true;\n};\n\nconst enterCommand: Command = chainCommands(\n newlineInCode,\n // Split list item on Enter; lift empty list item out of list\n splitListItem(listItem),\n createParagraphNear,\n liftEmptyBlock,\n splitBlock,\n);\n\nconst shiftEnterCommand: Command = (state, dispatch) => {\n if (dispatch) {\n dispatch(\n state.tr.replaceSelectionWith(hardBreak.create()).scrollIntoView(),\n );\n }\n return true;\n};\n\nexport function createKeymapPlugin(): ActionbookPlugin {\n return {\n name: 'keymapPlugin',\n keymap: () => ({\n Backspace: backspaceCommand,\n Tab: tabCommand,\n 'Shift-Tab': shiftTabCommand,\n Enter: enterCommand,\n 'Shift-Enter': shiftEnterCommand,\n 'Mod-b': toggleMark(boldMark),\n 'Mod-i': toggleMark(italicMark),\n 'Mod-u': toggleMark(underlineMark),\n 'Mod-Shift-x': toggleMark(strikethroughMark),\n 'Mod-e': toggleMark(codeMark),\n 'Mod-Shift-7': wrapInList(bulletList),\n 'Mod-Shift-8': wrapInList(orderedList),\n }),\n };\n}\n","/**\n * Clipboard plugin: paste plain-text / markdown → ProseMirror nodes,\n * copy ProseMirror nodes → markdown text.\n *\n * Mirrors the MarkdownClipboardManager from sbdashboard, using\n * actionbook-core's own parseFragment / serializeFragment / fromProseMirrorJSON.\n *\n * Jump-point deduplication: if a pasted `^id^` already exists in the doc,\n * the caret `^...^` markers are stripped so the text is kept as plain text\n * rather than creating a duplicate node.\n */\nimport { Fragment, Slice } from 'prosemirror-model';\nimport { Plugin, PluginKey } from 'prosemirror-state';\nimport type { EditorView } from 'prosemirror-view';\nimport { parseFragment, serializeFragment, fromProseMirrorJSON } from '../../index';\nimport { astNodesToJSONContent } from '../bridge/toProseMirrorJSON';\nimport { actionbookSchema } from '../schema';\nimport type { ActionbookPlugin } from './types';\n\nconst key = new PluginKey('markdownClipboard');\n\nfunction textToSlice(text: string, view: EditorView): Slice | null {\n try {\n const existingIds = new Set<string>();\n view.state.doc.descendants((node) => {\n if (node.type.name === 'jumpPoint') existingIds.add(node.attrs.id as string);\n });\n\n // Strip duplicate jump-point markers\n const deduped = text.replace(/\\^([A-Za-z_][A-Za-z0-9_]*)\\^/gm, (match, id) => {\n if (existingIds.has(id)) return id; // keep as plain text\n existingIds.add(id);\n return match;\n });\n\n const astNodes = parseFragment(deduped);\n const pmJSONNodes = astNodesToJSONContent(astNodes);\n const pmNodes = pmJSONNodes.map((json) => actionbookSchema.nodeFromJSON(json));\n const fragment = Fragment.fromArray(pmNodes);\n // Single paragraph → inline paste (openDepth 1); otherwise block paste\n const openDepth = pmJSONNodes.length === 1 && pmJSONNodes[0].type === 'paragraph' ? 1 : 0;\n return new Slice(fragment, openDepth, openDepth);\n } catch {\n return null;\n }\n}\n\nfunction createPlugin(): Plugin {\n return new Plugin({\n key,\n props: {\n handlePaste(view: EditorView, event: ClipboardEvent) {\n const text = event.clipboardData?.getData('text/plain');\n if (!text) return false;\n\n const slice = textToSlice(text, view);\n if (!slice) return false;\n\n view.dispatch(view.state.tr.replaceSelection(slice));\n return true;\n },\n\n clipboardTextParser(text: string, _$context, _plain, view) {\n if (!text) return Slice.empty;\n const slice = textToSlice(text, view!);\n if (!slice) {\n const textNode = actionbookSchema.text(text);\n return new Slice(Fragment.from(textNode), 0, 0);\n }\n return slice;\n },\n\n // Discard pasted HTML — always prefer plain-text markdown\n transformPastedHTML() {\n return '';\n },\n\n clipboardTextSerializer(slice: Slice) {\n try {\n const jsonNodes: Record<string, unknown>[] = [];\n slice.content.forEach((node) => jsonNodes.push(node.toJSON()));\n const doc = fromProseMirrorJSON({ type: 'doc', content: jsonNodes });\n return serializeFragment(doc.content as Parameters<typeof serializeFragment>[0]);\n } catch {\n return '';\n }\n },\n },\n });\n}\n\nexport function createMarkdownClipboardPlugin(): ActionbookPlugin {\n return {\n name: 'markdownClipboard',\n plugins: () => [createPlugin()],\n };\n}\n","import type { AstNode, BlockNode, DocumentNode, InlineNode, JinjaIfBlockNode, JinjaIfInlineNode, NodePath } from './types';\n\n/**\n * Maximum recursion depth for all tree traversal functions.\n * Prevents stack overflow from maliciously deep or malformed input.\n */\nexport const MAX_DEPTH = 128;\n\nexport class TraversalDepthError extends Error {\n constructor(depth: number) {\n super(`Maximum traversal depth (${MAX_DEPTH}) exceeded at depth ${depth}`);\n this.name = 'TraversalDepthError';\n }\n}\n\nfunction getChildren(node: AstNode): readonly AstNode[] {\n switch (node.type) {\n case 'doc':\n case 'blockquote':\n case 'listItem':\n return node.content;\n case 'paragraph':\n case 'heading':\n return node.content;\n case 'bulletList':\n case 'orderedList':\n return node.content;\n case 'jinjaIfBlock':\n return node.branches.flatMap(b => b.content as readonly AstNode[]);\n case 'jinjaIfInline':\n return node.branches.flatMap(b => b.content as readonly AstNode[]);\n default:\n return [];\n }\n}\n\n// Internal recursive implementation shared by visit()\nfunction visitInternal(\n node: AstNode,\n callback: (node: AstNode, parent?: AstNode, path?: NodePath) => void,\n parent: AstNode | undefined,\n path: NodePath,\n depth: number,\n trackPath: boolean,\n): void {\n if (depth > MAX_DEPTH) {\n throw new TraversalDepthError(depth);\n }\n callback(node, parent, trackPath ? path : undefined);\n const children = getChildren(node);\n for (let i = 0; i < children.length; i++) {\n const nextPath = trackPath ? [...path, i] : path;\n visitInternal(children[i], callback, node, nextPath, depth + 1, trackPath);\n }\n}\n\nexport interface VisitOptions {\n /**\n * Whether to compute and pass a NodePath to each callback invocation.\n * Defaults to true for backward compatibility.\n * Set to false for performance-critical traversals that don't need path info.\n */\n trackPath?: boolean;\n}\n\nexport function visit(\n node: AstNode,\n callback: (node: AstNode, parent?: AstNode, path?: NodePath) => void,\n options?: VisitOptions,\n): void {\n visitInternal(node, callback, undefined, [], 0, options?.trackPath ?? true);\n}\n\nexport function map(node: AstNode, fn: (node: AstNode) => AstNode, _depth: number = 0): AstNode {\n if (_depth > MAX_DEPTH) {\n throw new TraversalDepthError(_depth);\n }\n const mapped = fn(node);\n const children = getChildren(mapped);\n if (children.length === 0) return mapped;\n\n const newChildren = children.map((child) => map(child, fn, _depth + 1));\n const changed = newChildren.some((c, i) => c !== children[i]);\n if (!changed) return mapped;\n\n switch (mapped.type) {\n case 'doc':\n return { ...mapped, content: newChildren as BlockNode[] };\n case 'blockquote':\n case 'listItem':\n return { ...mapped, content: newChildren as BlockNode[] };\n case 'paragraph':\n case 'heading':\n return { ...mapped, content: newChildren as InlineNode[] };\n case 'bulletList':\n return { ...mapped, content: newChildren as typeof mapped.content };\n case 'orderedList':\n return { ...mapped, content: newChildren as typeof mapped.content };\n case 'jinjaIfBlock': {\n const jNode = mapped as JinjaIfBlockNode;\n let offset = 0;\n const newBranches = jNode.branches.map(b => {\n const slice = newChildren.slice(offset, offset + b.content.length) as BlockNode[];\n offset += b.content.length;\n return { ...b, content: slice };\n });\n return { ...jNode, branches: newBranches };\n }\n case 'jinjaIfInline': {\n const jNode = mapped as JinjaIfInlineNode;\n let offset = 0;\n const newBranches = jNode.branches.map(b => {\n const slice = newChildren.slice(offset, offset + b.content.length) as InlineNode[];\n offset += b.content.length;\n return { ...b, content: slice };\n });\n return { ...jNode, branches: newBranches };\n }\n default:\n return mapped;\n }\n}\n\nexport function textContent(node: AstNode, _depth: number = 0): string {\n if (_depth > MAX_DEPTH) {\n throw new TraversalDepthError(_depth);\n }\n switch (node.type) {\n case 'text':\n return node.text;\n case 'resourceTag':\n return node.text;\n case 'jumpPoint':\n return `^${node.id}^`;\n case 'hardBreak':\n return '\\n';\n case 'jinjaIfInline': {\n // Reconstruct original {% %} text for analyzer compatibility\n let out = '';\n for (const branch of node.branches) {\n if (branch.branchType === 'if') out += `{% if ${branch.condition} %}`;\n else if (branch.branchType === 'elif') out += `{% elif ${branch.condition} %}`;\n else out += '{% else %}';\n for (const child of branch.content) out += textContent(child, _depth + 1);\n }\n out += '{% endif %}';\n return out;\n }\n case 'horizontalRule':\n return '';\n default: {\n const children = getChildren(node);\n let out = '';\n for (const child of children) out += textContent(child, _depth + 1);\n return out;\n }\n }\n}\n\nexport function findAll(node: AstNode, predicate: (n: AstNode) => boolean): AstNode[] {\n const results: AstNode[] = [];\n visit(node, (n) => {\n if (predicate(n)) results.push(n);\n }, { trackPath: false });\n return results;\n}\n\nexport function nodeAtPath(root: DocumentNode, path: NodePath): AstNode | undefined {\n if (path.length > MAX_DEPTH) {\n throw new TraversalDepthError(path.length);\n }\n let current: AstNode = root;\n for (const index of path) {\n const children = getChildren(current);\n if (index < 0 || index >= children.length) return undefined;\n current = children[index];\n }\n return current;\n}\n","import { fromMarkdown } from 'mdast-util-from-markdown';\nimport { combineExtensions } from 'micromark-util-combine-extensions';\nimport { gfmFootnote } from 'micromark-extension-gfm-footnote';\nimport { gfmStrikethrough } from 'micromark-extension-gfm-strikethrough';\nimport { gfmTable } from 'micromark-extension-gfm-table';\nimport { gfmTaskListItem } from 'micromark-extension-gfm-task-list-item';\nimport { gfmFootnoteFromMarkdown } from 'mdast-util-gfm-footnote';\nimport { gfmStrikethroughFromMarkdown } from 'mdast-util-gfm-strikethrough';\nimport { gfmTableFromMarkdown } from 'mdast-util-gfm-table';\nimport { gfmTaskListItemFromMarkdown } from 'mdast-util-gfm-task-list-item';\nimport { splitTextWithResourceTags } from './plugins/resourceTag';\nimport { splitTextWithJumpPoints } from './plugins/jumpPoint';\nimport type { ResourceTagMdastNode } from './plugins/resourceTag';\nimport type { JumpPointMdastNode } from './plugins/jumpPoint';\nimport { fromMdast } from './mdastAdapter';\nimport { jinjaBlockTransform } from './plugins/jinjaBlock';\nimport type { DocumentNode } from '../ast/types';\nimport type { Root, Text } from 'mdast';\n\nexport interface ParseMarkdownOptions {\n jinjaNodes?: boolean;\n}\n\n// GFM without autolink literal — autolink literal converts escaped emails/URLs\n// (e.g. bookings\\@flynorse.com) into link nodes during the mdast transform pass,\n// which then serialize as <bookings@flynorse.com> instead of preserving the\n// original backslash escaping.\nconst gfmNoAutolink = () =>\n combineExtensions([gfmFootnote(), gfmStrikethrough(), gfmTable(), gfmTaskListItem()]);\n\nconst gfmNoAutolinkFromMarkdown = () => [\n gfmFootnoteFromMarkdown(),\n gfmStrikethroughFromMarkdown(),\n gfmTableFromMarkdown(),\n gfmTaskListItemFromMarkdown(),\n];\n\nconst MAX_DEPTH = 128;\n\ntype CustomNode = ResourceTagMdastNode | JumpPointMdastNode;\n\n/**\n * Combined single-pass transform for resource tags and jump points.\n * Each text node is scanned for both patterns in one iteration,\n * avoiding two separate full-tree traversals.\n */\nfunction combinedTokensFromMarkdown(node: { children?: unknown[] }, depth: number = 0): void {\n if (depth > MAX_DEPTH) return;\n if (!node.children) return;\n for (const child of node.children) {\n combinedTokensFromMarkdown(child as { children?: unknown[] }, depth + 1);\n }\n if (Array.isArray(node.children)) {\n const newChildren: unknown[] = [];\n for (const child of node.children) {\n const c = child as { type: string };\n if (c.type === 'text') {\n // First split by resource tags, then split each resulting text segment by jump points\n const afterResourceTags = splitTextWithResourceTags((child as Text).value);\n for (const part of afterResourceTags) {\n if (part.type === 'text') {\n const afterJumpPoints = splitTextWithJumpPoints(part.value);\n newChildren.push(...afterJumpPoints);\n } else {\n newChildren.push(part as unknown as CustomNode);\n }\n }\n } else {\n newChildren.push(child);\n }\n }\n node.children = newChildren;\n }\n}\n\nexport function parseMarkdown(markdown: string, options?: ParseMarkdownOptions): DocumentNode {\n const tree = fromMarkdown(markdown, {\n extensions: [gfmNoAutolink()],\n mdastExtensions: [gfmNoAutolinkFromMarkdown()],\n });\n\n // Single combined pass for resource tags and jump points\n combinedTokensFromMarkdown(tree as unknown as { children?: unknown[] });\n\n // Optional: transform Jinja tags into structured mdast nodes\n if (options?.jinjaNodes) {\n jinjaBlockTransform(tree as unknown as { type: string; children?: unknown[] });\n }\n\n return fromMdast(tree);\n}\n","/**\n * Like `Array#splice`, but smarter for giant arrays.\n *\n * `Array#splice` takes all items to be inserted as individual argument which\n * causes a stack overflow in V8 when trying to insert 100k items for instance.\n *\n * Otherwise, this does not return the removed items, and takes `items` as an\n * array instead of rest parameters.\n *\n * @template {unknown} T\n * Item type.\n * @param {Array<T>} list\n * List to operate on.\n * @param {number} start\n * Index to remove/insert at (can be negative).\n * @param {number} remove\n * Number of items to remove.\n * @param {Array<T>} items\n * Items to inject into `list`.\n * @returns {undefined}\n * Nothing.\n */\nexport function splice(list, start, remove, items) {\n const end = list.length;\n let chunkStart = 0;\n /** @type {Array<unknown>} */\n let parameters;\n\n // Make start between zero and `end` (included).\n if (start < 0) {\n start = -start > end ? 0 : end + start;\n } else {\n start = start > end ? end : start;\n }\n remove = remove > 0 ? remove : 0;\n\n // No need to chunk the items if there’s only a couple (10k) items.\n if (items.length < 10000) {\n parameters = Array.from(items);\n parameters.unshift(start, remove);\n // @ts-expect-error Hush, it’s fine.\n list.splice(...parameters);\n } else {\n // Delete `remove` items starting from `start`\n if (remove) list.splice(start, remove);\n\n // Insert the items in chunks to not cause stack overflows.\n while (chunkStart < items.length) {\n parameters = items.slice(chunkStart, chunkStart + 10000);\n parameters.unshift(start, 0);\n // @ts-expect-error Hush, it’s fine.\n list.splice(...parameters);\n chunkStart += 10000;\n start += 10000;\n }\n }\n}\n\n/**\n * Append `items` (an array) at the end of `list` (another array).\n * When `list` was empty, returns `items` instead.\n *\n * This prevents a potentially expensive operation when `list` is empty,\n * and adds items in batches to prevent V8 from hanging.\n *\n * @template {unknown} T\n * Item type.\n * @param {Array<T>} list\n * List to operate on.\n * @param {Array<T>} items\n * Items to add to `list`.\n * @returns {Array<T>}\n * Either `list` or `items`.\n */\nexport function push(list, items) {\n if (list.length > 0) {\n splice(list, list.length, 0, items);\n return list;\n }\n return items;\n}","/**\n * @import {\n * Extension,\n * Handles,\n * HtmlExtension,\n * NormalizedExtension\n * } from 'micromark-util-types'\n */\n\nimport {splice} from 'micromark-util-chunked'\n\nconst hasOwnProperty = {}.hasOwnProperty\n\n/**\n * Combine multiple syntax extensions into one.\n *\n * @param {ReadonlyArray<Extension>} extensions\n * List of syntax extensions.\n * @returns {NormalizedExtension}\n * A single combined extension.\n */\nexport function combineExtensions(extensions) {\n /** @type {NormalizedExtension} */\n const all = {}\n let index = -1\n\n while (++index < extensions.length) {\n syntaxExtension(all, extensions[index])\n }\n\n return all\n}\n\n/**\n * Merge `extension` into `all`.\n *\n * @param {NormalizedExtension} all\n * Extension to merge into.\n * @param {Extension} extension\n * Extension to merge.\n * @returns {undefined}\n * Nothing.\n */\nfunction syntaxExtension(all, extension) {\n /** @type {keyof Extension} */\n let hook\n\n for (hook in extension) {\n const maybe = hasOwnProperty.call(all, hook) ? all[hook] : undefined\n /** @type {Record<string, unknown>} */\n const left = maybe || (all[hook] = {})\n /** @type {Record<string, unknown> | undefined} */\n const right = extension[hook]\n /** @type {string} */\n let code\n\n if (right) {\n for (code in right) {\n if (!hasOwnProperty.call(left, code)) left[code] = []\n const value = right[code]\n constructs(\n // @ts-expect-error Looks like a list.\n left[code],\n Array.isArray(value) ? value : value ? [value] : []\n )\n }\n }\n }\n}\n\n/**\n * Merge `list` into `existing` (both lists of constructs).\n * Mutates `existing`.\n *\n * @param {Array<unknown>} existing\n * List of constructs to merge into.\n * @param {Array<unknown>} list\n * List of constructs to merge.\n * @returns {undefined}\n * Nothing.\n */\nfunction constructs(existing, list) {\n let index = -1\n /** @type {Array<unknown>} */\n const before = []\n\n while (++index < list.length) {\n // @ts-expect-error Looks like an object.\n ;(list[index].add === 'after' ? existing : before).push(list[index])\n }\n\n splice(existing, 0, 0, before)\n}\n\n/**\n * Combine multiple HTML extensions into one.\n *\n * @param {ReadonlyArray<HtmlExtension>} htmlExtensions\n * List of HTML extensions.\n * @returns {HtmlExtension}\n * Single combined HTML extension.\n */\nexport function combineHtmlExtensions(htmlExtensions) {\n /** @type {HtmlExtension} */\n const handlers = {}\n let index = -1\n\n while (++index < htmlExtensions.length) {\n htmlExtension(handlers, htmlExtensions[index])\n }\n\n return handlers\n}\n\n/**\n * Merge `extension` into `all`.\n *\n * @param {HtmlExtension} all\n * Extension to merge into.\n * @param {HtmlExtension} extension\n * Extension to merge.\n * @returns {undefined}\n * Nothing.\n */\nfunction htmlExtension(all, extension) {\n /** @type {keyof HtmlExtension} */\n let hook\n\n for (hook in extension) {\n const maybe = hasOwnProperty.call(all, hook) ? all[hook] : undefined\n const left = maybe || (all[hook] = {})\n const right = extension[hook]\n /** @type {keyof Handles} */\n let type\n\n if (right) {\n for (type in right) {\n // @ts-expect-error assume document vs regular handler are managed correctly.\n left[type] = right[type]\n }\n }\n }\n}\n","/**\n * @import {Code} from 'micromark-util-types'\n */\n\nimport { markdownLineEndingOrSpace, unicodePunctuation, unicodeWhitespace } from 'micromark-util-character';\n/**\n * Classify whether a code represents whitespace, punctuation, or something\n * else.\n *\n * Used for attention (emphasis, strong), whose sequences can open or close\n * based on the class of surrounding characters.\n *\n * > 👉 **Note**: eof (`null`) is seen as whitespace.\n *\n * @param {Code} code\n * Code.\n * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined}\n * Group.\n */\nexport function classifyCharacter(code) {\n if (code === null || markdownLineEndingOrSpace(code) || unicodeWhitespace(code)) {\n return 1;\n }\n if (unicodePunctuation(code)) {\n return 2;\n }\n}","/**\n * @import {Event, Resolver, TokenizeContext} from 'micromark-util-types'\n */\n\n/**\n * Call all `resolveAll`s.\n *\n * @param {ReadonlyArray<{resolveAll?: Resolver | undefined}>} constructs\n * List of constructs, optionally with `resolveAll`s.\n * @param {Array<Event>} events\n * List of events.\n * @param {TokenizeContext} context\n * Context used by `tokenize`.\n * @returns {Array<Event>}\n * Changed events.\n */\nexport function resolveAll(constructs, events, context) {\n /** @type {Array<Resolver>} */\n const called = []\n let index = -1\n\n while (++index < constructs.length) {\n const resolve = constructs[index].resolveAll\n\n if (resolve && !called.includes(resolve)) {\n events = resolve(events, context)\n called.push(resolve)\n }\n }\n\n return events\n}\n","/**\n * @import {Effects, State, TokenType} from 'micromark-util-types'\n */\n\nimport { markdownSpace } from 'micromark-util-character';\n\n// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`.\n\n/**\n * Parse spaces and tabs.\n *\n * There is no `nok` parameter:\n *\n * * spaces in markdown are often optional, in which case this factory can be\n * used and `ok` will be switched to whether spaces were found or not\n * * one line ending or space can be detected with `markdownSpace(code)` right\n * before using `factorySpace`\n *\n * ###### Examples\n *\n * Where `␉` represents a tab (plus how much it expands) and `␠` represents a\n * single space.\n *\n * ```markdown\n * ␉\n * ␠␠␠␠\n * ␉␠\n * ```\n *\n * @param {Effects} effects\n * Context.\n * @param {State} ok\n * State switched to when successful.\n * @param {TokenType} type\n * Type (`' \\t'`).\n * @param {number | undefined} [max=Infinity]\n * Max (exclusive).\n * @returns {State}\n * Start state.\n */\nexport function factorySpace(effects, ok, type, max) {\n const limit = max ? max - 1 : Number.POSITIVE_INFINITY;\n let size = 0;\n return start;\n\n /** @type {State} */\n function start(code) {\n if (markdownSpace(code)) {\n effects.enter(type);\n return prefix(code);\n }\n return ok(code);\n }\n\n /** @type {State} */\n function prefix(code) {\n if (markdownSpace(code) && size++ < limit) {\n effects.consume(code);\n return prefix;\n }\n effects.exit(type);\n return ok(code);\n }\n}","/**\n * @import {\n * Construct,\n * State,\n * TokenizeContext,\n * Tokenizer\n * } from 'micromark-util-types'\n */\n\nimport { factorySpace } from 'micromark-factory-space';\nimport { markdownLineEnding, markdownSpace } from 'micromark-util-character';\n/** @type {Construct} */\nexport const blankLine = {\n partial: true,\n tokenize: tokenizeBlankLine\n};\n\n/**\n * @this {TokenizeContext}\n * Context.\n * @type {Tokenizer}\n */\nfunction tokenizeBlankLine(effects, ok, nok) {\n return start;\n\n /**\n * Start of blank line.\n *\n * > 👉 **Note**: `␠` represents a space character.\n *\n * ```markdown\n * > | ␠␠␊\n * ^\n * > | ␊\n * ^\n * ```\n *\n * @type {State}\n */\n function start(code) {\n return markdownSpace(code) ? factorySpace(effects, after, \"linePrefix\")(code) : after(code);\n }\n\n /**\n * At eof/eol, after optional whitespace.\n *\n * > 👉 **Note**: `␠` represents a space character.\n *\n * ```markdown\n * > | ␠␠␊\n * ^\n * > | ␊\n * ^\n * ```\n *\n * @type {State}\n */\n function after(code) {\n return code === null || markdownLineEnding(code) ? ok(code) : nok(code);\n }\n}","/**\n * @import {Event, Exiter, Extension, Resolver, State, Token, TokenizeContext, Tokenizer} from 'micromark-util-types'\n */\n\nimport { blankLine } from 'micromark-core-commonmark';\nimport { factorySpace } from 'micromark-factory-space';\nimport { markdownLineEndingOrSpace } from 'micromark-util-character';\nimport { normalizeIdentifier } from 'micromark-util-normalize-identifier';\nconst indent = {\n tokenize: tokenizeIndent,\n partial: true\n};\n\n// To do: micromark should support a `_hiddenGfmFootnoteSupport`, which only\n// affects label start (image).\n// That will let us drop `tokenizePotentialGfmFootnote*`.\n// It currently has a `_hiddenFootnoteSupport`, which affects that and more.\n// That can be removed when `micromark-extension-footnote` is archived.\n\n/**\n * Create an extension for `micromark` to enable GFM footnote syntax.\n *\n * @returns {Extension}\n * Extension for `micromark` that can be passed in `extensions` to\n * enable GFM footnote syntax.\n */\nexport function gfmFootnote() {\n /** @type {Extension} */\n return {\n document: {\n [91]: {\n name: 'gfmFootnoteDefinition',\n tokenize: tokenizeDefinitionStart,\n continuation: {\n tokenize: tokenizeDefinitionContinuation\n },\n exit: gfmFootnoteDefinitionEnd\n }\n },\n text: {\n [91]: {\n name: 'gfmFootnoteCall',\n tokenize: tokenizeGfmFootnoteCall\n },\n [93]: {\n name: 'gfmPotentialFootnoteCall',\n add: 'after',\n tokenize: tokenizePotentialGfmFootnoteCall,\n resolveTo: resolveToPotentialGfmFootnoteCall\n }\n }\n };\n}\n\n// To do: remove after micromark update.\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizePotentialGfmFootnoteCall(effects, ok, nok) {\n const self = this;\n let index = self.events.length;\n const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []);\n /** @type {Token} */\n let labelStart;\n\n // Find an opening.\n while (index--) {\n const token = self.events[index][1];\n if (token.type === \"labelImage\") {\n labelStart = token;\n break;\n }\n\n // Exit if we’ve walked far enough.\n if (token.type === 'gfmFootnoteCall' || token.type === \"labelLink\" || token.type === \"label\" || token.type === \"image\" || token.type === \"link\") {\n break;\n }\n }\n return start;\n\n /**\n * @type {State}\n */\n function start(code) {\n if (!labelStart || !labelStart._balanced) {\n return nok(code);\n }\n const id = normalizeIdentifier(self.sliceSerialize({\n start: labelStart.end,\n end: self.now()\n }));\n if (id.codePointAt(0) !== 94 || !defined.includes(id.slice(1))) {\n return nok(code);\n }\n effects.enter('gfmFootnoteCallLabelMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteCallLabelMarker');\n return ok(code);\n }\n}\n\n// To do: remove after micromark update.\n/** @type {Resolver} */\nfunction resolveToPotentialGfmFootnoteCall(events, context) {\n let index = events.length;\n /** @type {Token | undefined} */\n let labelStart;\n\n // Find an opening.\n while (index--) {\n if (events[index][1].type === \"labelImage\" && events[index][0] === 'enter') {\n labelStart = events[index][1];\n break;\n }\n }\n // Change the `labelImageMarker` to a `data`.\n events[index + 1][1].type = \"data\";\n events[index + 3][1].type = 'gfmFootnoteCallLabelMarker';\n\n // The whole (without `!`):\n /** @type {Token} */\n const call = {\n type: 'gfmFootnoteCall',\n start: Object.assign({}, events[index + 3][1].start),\n end: Object.assign({}, events[events.length - 1][1].end)\n };\n // The `^` marker\n /** @type {Token} */\n const marker = {\n type: 'gfmFootnoteCallMarker',\n start: Object.assign({}, events[index + 3][1].end),\n end: Object.assign({}, events[index + 3][1].end)\n };\n // Increment the end 1 character.\n marker.end.column++;\n marker.end.offset++;\n marker.end._bufferIndex++;\n /** @type {Token} */\n const string = {\n type: 'gfmFootnoteCallString',\n start: Object.assign({}, marker.end),\n end: Object.assign({}, events[events.length - 1][1].start)\n };\n /** @type {Token} */\n const chunk = {\n type: \"chunkString\",\n contentType: 'string',\n start: Object.assign({}, string.start),\n end: Object.assign({}, string.end)\n };\n\n /** @type {Array<Event>} */\n const replacement = [\n // Take the `labelImageMarker` (now `data`, the `!`)\n events[index + 1], events[index + 2], ['enter', call, context],\n // The `[`\n events[index + 3], events[index + 4],\n // The `^`.\n ['enter', marker, context], ['exit', marker, context],\n // Everything in between.\n ['enter', string, context], ['enter', chunk, context], ['exit', chunk, context], ['exit', string, context],\n // The ending (`]`, properly parsed and labelled).\n events[events.length - 2], events[events.length - 1], ['exit', call, context]];\n events.splice(index, events.length - index + 1, ...replacement);\n return events;\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeGfmFootnoteCall(effects, ok, nok) {\n const self = this;\n const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []);\n let size = 0;\n /** @type {boolean} */\n let data;\n\n // Note: the implementation of `markdown-rs` is different, because it houses\n // core *and* extensions in one project.\n // Therefore, it can include footnote logic inside `label-end`.\n // We can’t do that, but luckily, we can parse footnotes in a simpler way than\n // needed for labels.\n return start;\n\n /**\n * Start of footnote label.\n *\n * ```markdown\n * > | a [^b] c\n * ^\n * ```\n *\n * @type {State}\n */\n function start(code) {\n effects.enter('gfmFootnoteCall');\n effects.enter('gfmFootnoteCallLabelMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteCallLabelMarker');\n return callStart;\n }\n\n /**\n * After `[`, at `^`.\n *\n * ```markdown\n * > | a [^b] c\n * ^\n * ```\n *\n * @type {State}\n */\n function callStart(code) {\n if (code !== 94) return nok(code);\n effects.enter('gfmFootnoteCallMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteCallMarker');\n effects.enter('gfmFootnoteCallString');\n effects.enter('chunkString').contentType = 'string';\n return callData;\n }\n\n /**\n * In label.\n *\n * ```markdown\n * > | a [^b] c\n * ^\n * ```\n *\n * @type {State}\n */\n function callData(code) {\n if (\n // Too long.\n size > 999 ||\n // Closing brace with nothing.\n code === 93 && !data ||\n // Space or tab is not supported by GFM for some reason.\n // `\\n` and `[` not being supported makes sense.\n code === null || code === 91 || markdownLineEndingOrSpace(code)) {\n return nok(code);\n }\n if (code === 93) {\n effects.exit('chunkString');\n const token = effects.exit('gfmFootnoteCallString');\n if (!defined.includes(normalizeIdentifier(self.sliceSerialize(token)))) {\n return nok(code);\n }\n effects.enter('gfmFootnoteCallLabelMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteCallLabelMarker');\n effects.exit('gfmFootnoteCall');\n return ok;\n }\n if (!markdownLineEndingOrSpace(code)) {\n data = true;\n }\n size++;\n effects.consume(code);\n return code === 92 ? callEscape : callData;\n }\n\n /**\n * On character after escape.\n *\n * ```markdown\n * > | a [^b\\c] d\n * ^\n * ```\n *\n * @type {State}\n */\n function callEscape(code) {\n if (code === 91 || code === 92 || code === 93) {\n effects.consume(code);\n size++;\n return callData;\n }\n return callData(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeDefinitionStart(effects, ok, nok) {\n const self = this;\n const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []);\n /** @type {string} */\n let identifier;\n let size = 0;\n /** @type {boolean | undefined} */\n let data;\n return start;\n\n /**\n * Start of GFM footnote definition.\n *\n * ```markdown\n * > | [^a]: b\n * ^\n * ```\n *\n * @type {State}\n */\n function start(code) {\n effects.enter('gfmFootnoteDefinition')._container = true;\n effects.enter('gfmFootnoteDefinitionLabel');\n effects.enter('gfmFootnoteDefinitionLabelMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteDefinitionLabelMarker');\n return labelAtMarker;\n }\n\n /**\n * In label, at caret.\n *\n * ```markdown\n * > | [^a]: b\n * ^\n * ```\n *\n * @type {State}\n */\n function labelAtMarker(code) {\n if (code === 94) {\n effects.enter('gfmFootnoteDefinitionMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteDefinitionMarker');\n effects.enter('gfmFootnoteDefinitionLabelString');\n effects.enter('chunkString').contentType = 'string';\n return labelInside;\n }\n return nok(code);\n }\n\n /**\n * In label.\n *\n * > 👉 **Note**: `cmark-gfm` prevents whitespace from occurring in footnote\n * > definition labels.\n *\n * ```markdown\n * > | [^a]: b\n * ^\n * ```\n *\n * @type {State}\n */\n function labelInside(code) {\n if (\n // Too long.\n size > 999 ||\n // Closing brace with nothing.\n code === 93 && !data ||\n // Space or tab is not supported by GFM for some reason.\n // `\\n` and `[` not being supported makes sense.\n code === null || code === 91 || markdownLineEndingOrSpace(code)) {\n return nok(code);\n }\n if (code === 93) {\n effects.exit('chunkString');\n const token = effects.exit('gfmFootnoteDefinitionLabelString');\n identifier = normalizeIdentifier(self.sliceSerialize(token));\n effects.enter('gfmFootnoteDefinitionLabelMarker');\n effects.consume(code);\n effects.exit('gfmFootnoteDefinitionLabelMarker');\n effects.exit('gfmFootnoteDefinitionLabel');\n return labelAfter;\n }\n if (!markdownLineEndingOrSpace(code)) {\n data = true;\n }\n size++;\n effects.consume(code);\n return code === 92 ? labelEscape : labelInside;\n }\n\n /**\n * After `\\`, at a special character.\n *\n * > 👉 **Note**: `cmark-gfm` currently does not support escaped brackets:\n * > <https://github.com/github/cmark-gfm/issues/240>\n *\n * ```markdown\n * > | [^a\\*b]: c\n * ^\n * ```\n *\n * @type {State}\n */\n function labelEscape(code) {\n if (code === 91 || code === 92 || code === 93) {\n effects.consume(code);\n size++;\n return labelInside;\n }\n return labelInside(code);\n }\n\n /**\n * After definition label.\n *\n * ```markdown\n * > | [^a]: b\n * ^\n * ```\n *\n * @type {State}\n */\n function labelAfter(code) {\n if (code === 58) {\n effects.enter('definitionMarker');\n effects.consume(code);\n effects.exit('definitionMarker');\n if (!defined.includes(identifier)) {\n defined.push(identifier);\n }\n\n // Any whitespace after the marker is eaten, forming indented code\n // is not possible.\n // No space is also fine, just like a block quote marker.\n return factorySpace(effects, whitespaceAfter, 'gfmFootnoteDefinitionWhitespace');\n }\n return nok(code);\n }\n\n /**\n * After definition prefix.\n *\n * ```markdown\n * > | [^a]: b\n * ^\n * ```\n *\n * @type {State}\n */\n function whitespaceAfter(code) {\n // `markdown-rs` has a wrapping token for the prefix that is closed here.\n return ok(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeDefinitionContinuation(effects, ok, nok) {\n /// Start of footnote definition continuation.\n ///\n /// ```markdown\n /// | [^a]: b\n /// > | c\n /// ^\n /// ```\n //\n // Either a blank line, which is okay, or an indented thing.\n return effects.check(blankLine, ok, effects.attempt(indent, ok, nok));\n}\n\n/** @type {Exiter} */\nfunction gfmFootnoteDefinitionEnd(effects) {\n effects.exit('gfmFootnoteDefinition');\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeIndent(effects, ok, nok) {\n const self = this;\n return factorySpace(effects, afterPrefix, 'gfmFootnoteDefinitionIndent', 4 + 1);\n\n /**\n * @type {State}\n */\n function afterPrefix(code) {\n const tail = self.events[self.events.length - 1];\n return tail && tail[1].type === 'gfmFootnoteDefinitionIndent' && tail[2].sliceSerialize(tail[1], true).length === 4 ? ok(code) : nok(code);\n }\n}","/**\n * @import {Options} from 'micromark-extension-gfm-strikethrough'\n * @import {Event, Extension, Resolver, State, Token, TokenizeContext, Tokenizer} from 'micromark-util-types'\n */\n\nimport { splice } from 'micromark-util-chunked';\nimport { classifyCharacter } from 'micromark-util-classify-character';\nimport { resolveAll } from 'micromark-util-resolve-all';\n/**\n * Create an extension for `micromark` to enable GFM strikethrough syntax.\n *\n * @param {Options | null | undefined} [options={}]\n * Configuration.\n * @returns {Extension}\n * Extension for `micromark` that can be passed in `extensions`, to\n * enable GFM strikethrough syntax.\n */\nexport function gfmStrikethrough(options) {\n const options_ = options || {};\n let single = options_.singleTilde;\n const tokenizer = {\n name: 'strikethrough',\n tokenize: tokenizeStrikethrough,\n resolveAll: resolveAllStrikethrough\n };\n if (single === null || single === undefined) {\n single = true;\n }\n return {\n text: {\n [126]: tokenizer\n },\n insideSpan: {\n null: [tokenizer]\n },\n attentionMarkers: {\n null: [126]\n }\n };\n\n /**\n * Take events and resolve strikethrough.\n *\n * @type {Resolver}\n */\n function resolveAllStrikethrough(events, context) {\n let index = -1;\n\n // Walk through all events.\n while (++index < events.length) {\n // Find a token that can close.\n if (events[index][0] === 'enter' && events[index][1].type === 'strikethroughSequenceTemporary' && events[index][1]._close) {\n let open = index;\n\n // Now walk back to find an opener.\n while (open--) {\n // Find a token that can open the closer.\n if (events[open][0] === 'exit' && events[open][1].type === 'strikethroughSequenceTemporary' && events[open][1]._open &&\n // If the sizes are the same:\n events[index][1].end.offset - events[index][1].start.offset === events[open][1].end.offset - events[open][1].start.offset) {\n events[index][1].type = 'strikethroughSequence';\n events[open][1].type = 'strikethroughSequence';\n\n /** @type {Token} */\n const strikethrough = {\n type: 'strikethrough',\n start: Object.assign({}, events[open][1].start),\n end: Object.assign({}, events[index][1].end)\n };\n\n /** @type {Token} */\n const text = {\n type: 'strikethroughText',\n start: Object.assign({}, events[open][1].end),\n end: Object.assign({}, events[index][1].start)\n };\n\n // Opening.\n /** @type {Array<Event>} */\n const nextEvents = [['enter', strikethrough, context], ['enter', events[open][1], context], ['exit', events[open][1], context], ['enter', text, context]];\n const insideSpan = context.parser.constructs.insideSpan.null;\n if (insideSpan) {\n // Between.\n splice(nextEvents, nextEvents.length, 0, resolveAll(insideSpan, events.slice(open + 1, index), context));\n }\n\n // Closing.\n splice(nextEvents, nextEvents.length, 0, [['exit', text, context], ['enter', events[index][1], context], ['exit', events[index][1], context], ['exit', strikethrough, context]]);\n splice(events, open - 1, index - open + 3, nextEvents);\n index = open + nextEvents.length - 2;\n break;\n }\n }\n }\n }\n index = -1;\n while (++index < events.length) {\n if (events[index][1].type === 'strikethroughSequenceTemporary') {\n events[index][1].type = \"data\";\n }\n }\n return events;\n }\n\n /**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\n function tokenizeStrikethrough(effects, ok, nok) {\n const previous = this.previous;\n const events = this.events;\n let size = 0;\n return start;\n\n /** @type {State} */\n function start(code) {\n if (previous === 126 && events[events.length - 1][1].type !== \"characterEscape\") {\n return nok(code);\n }\n effects.enter('strikethroughSequenceTemporary');\n return more(code);\n }\n\n /** @type {State} */\n function more(code) {\n const before = classifyCharacter(previous);\n if (code === 126) {\n // If this is the third marker, exit.\n if (size > 1) return nok(code);\n effects.consume(code);\n size++;\n return more;\n }\n if (size < 2 && !single) return nok(code);\n const token = effects.exit('strikethroughSequenceTemporary');\n const after = classifyCharacter(code);\n token._open = !after || after === 2 && Boolean(before);\n token._close = !before || before === 2 && Boolean(after);\n return ok(code);\n }\n }\n}","/**\n * @import {Event, Extension, Point, Resolver, State, Token, TokenizeContext, Tokenizer} from 'micromark-util-types'\n */\n\n/**\n * @typedef {[number, number, number, number]} Range\n * Cell info.\n *\n * @typedef {0 | 1 | 2 | 3} RowKind\n * Where we are: `1` for head row, `2` for delimiter row, `3` for body row.\n */\n\nimport { factorySpace } from 'micromark-factory-space';\nimport { markdownLineEnding, markdownLineEndingOrSpace, markdownSpace } from 'micromark-util-character';\nimport { EditMap } from './edit-map.js';\nimport { gfmTableAlign } from './infer.js';\n\n/**\n * Create an HTML extension for `micromark` to support GitHub tables syntax.\n *\n * @returns {Extension}\n * Extension for `micromark` that can be passed in `extensions` to enable GFM\n * table syntax.\n */\nexport function gfmTable() {\n return {\n flow: {\n null: {\n name: 'table',\n tokenize: tokenizeTable,\n resolveAll: resolveTable\n }\n }\n };\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeTable(effects, ok, nok) {\n const self = this;\n let size = 0;\n let sizeB = 0;\n /** @type {boolean | undefined} */\n let seen;\n return start;\n\n /**\n * Start of a GFM table.\n *\n * If there is a valid table row or table head before, then we try to parse\n * another row.\n * Otherwise, we try to parse a head.\n *\n * ```markdown\n * > | | a |\n * ^\n * | | - |\n * > | | b |\n * ^\n * ```\n * @type {State}\n */\n function start(code) {\n let index = self.events.length - 1;\n while (index > -1) {\n const type = self.events[index][1].type;\n if (type === \"lineEnding\" ||\n // Note: markdown-rs uses `whitespace` instead of `linePrefix`\n type === \"linePrefix\") index--;else break;\n }\n const tail = index > -1 ? self.events[index][1].type : null;\n const next = tail === 'tableHead' || tail === 'tableRow' ? bodyRowStart : headRowBefore;\n\n // Don’t allow lazy body rows.\n if (next === bodyRowStart && self.parser.lazy[self.now().line]) {\n return nok(code);\n }\n return next(code);\n }\n\n /**\n * Before table head row.\n *\n * ```markdown\n * > | | a |\n * ^\n * | | - |\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headRowBefore(code) {\n effects.enter('tableHead');\n effects.enter('tableRow');\n return headRowStart(code);\n }\n\n /**\n * Before table head row, after whitespace.\n *\n * ```markdown\n * > | | a |\n * ^\n * | | - |\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headRowStart(code) {\n if (code === 124) {\n return headRowBreak(code);\n }\n\n // To do: micromark-js should let us parse our own whitespace in extensions,\n // like `markdown-rs`:\n //\n // ```js\n // // 4+ spaces.\n // if (markdownSpace(code)) {\n // return nok(code)\n // }\n // ```\n\n seen = true;\n // Count the first character, that isn’t a pipe, double.\n sizeB += 1;\n return headRowBreak(code);\n }\n\n /**\n * At break in table head row.\n *\n * ```markdown\n * > | | a |\n * ^\n * ^\n * ^\n * | | - |\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headRowBreak(code) {\n if (code === null) {\n // Note: in `markdown-rs`, we need to reset, in `micromark-js` we don‘t.\n return nok(code);\n }\n if (markdownLineEnding(code)) {\n // If anything other than one pipe (ignoring whitespace) was used, it’s fine.\n if (sizeB > 1) {\n sizeB = 0;\n // To do: check if this works.\n // Feel free to interrupt:\n self.interrupt = true;\n effects.exit('tableRow');\n effects.enter(\"lineEnding\");\n effects.consume(code);\n effects.exit(\"lineEnding\");\n return headDelimiterStart;\n }\n\n // Note: in `markdown-rs`, we need to reset, in `micromark-js` we don‘t.\n return nok(code);\n }\n if (markdownSpace(code)) {\n // To do: check if this is fine.\n // effects.attempt(State::Next(StateName::GfmTableHeadRowBreak), State::Nok)\n // State::Retry(space_or_tab(tokenizer))\n return factorySpace(effects, headRowBreak, \"whitespace\")(code);\n }\n sizeB += 1;\n if (seen) {\n seen = false;\n // Header cell count.\n size += 1;\n }\n if (code === 124) {\n effects.enter('tableCellDivider');\n effects.consume(code);\n effects.exit('tableCellDivider');\n // Whether a delimiter was seen.\n seen = true;\n return headRowBreak;\n }\n\n // Anything else is cell data.\n effects.enter(\"data\");\n return headRowData(code);\n }\n\n /**\n * In table head row data.\n *\n * ```markdown\n * > | | a |\n * ^\n * | | - |\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headRowData(code) {\n if (code === null || code === 124 || markdownLineEndingOrSpace(code)) {\n effects.exit(\"data\");\n return headRowBreak(code);\n }\n effects.consume(code);\n return code === 92 ? headRowEscape : headRowData;\n }\n\n /**\n * In table head row escape.\n *\n * ```markdown\n * > | | a\\-b |\n * ^\n * | | ---- |\n * | | c |\n * ```\n *\n * @type {State}\n */\n function headRowEscape(code) {\n if (code === 92 || code === 124) {\n effects.consume(code);\n return headRowData;\n }\n return headRowData(code);\n }\n\n /**\n * Before delimiter row.\n *\n * ```markdown\n * | | a |\n * > | | - |\n * ^\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headDelimiterStart(code) {\n // Reset `interrupt`.\n self.interrupt = false;\n\n // Note: in `markdown-rs`, we need to handle piercing here too.\n if (self.parser.lazy[self.now().line]) {\n return nok(code);\n }\n effects.enter('tableDelimiterRow');\n // Track if we’ve seen a `:` or `|`.\n seen = false;\n if (markdownSpace(code)) {\n return factorySpace(effects, headDelimiterBefore, \"linePrefix\", self.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4)(code);\n }\n return headDelimiterBefore(code);\n }\n\n /**\n * Before delimiter row, after optional whitespace.\n *\n * Reused when a `|` is found later, to parse another cell.\n *\n * ```markdown\n * | | a |\n * > | | - |\n * ^\n * | | b |\n * ```\n *\n * @type {State}\n */\n function headDelimiterBefore(code) {\n if (code === 45 || code === 58) {\n return headDelimiterValueBefore(code);\n }\n if (code === 124) {\n seen = true;\n // If we start with a pipe, we open a cell marker.\n effects.enter('tableCellDivider');\n effects.consume(code);\n effects.exit('tableCellDivider');\n return headDelimiterCellBefore;\n }\n\n // More whitespace / empty row not allowed at start.\n return headDelimiterNok(code);\n }\n\n /**\n * After `|`, before delimiter cell.\n *\n * ```markdown\n * | | a |\n * > | | - |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterCellBefore(code) {\n if (markdownSpace(code)) {\n return factorySpace(effects, headDelimiterValueBefore, \"whitespace\")(code);\n }\n return headDelimiterValueBefore(code);\n }\n\n /**\n * Before delimiter cell value.\n *\n * ```markdown\n * | | a |\n * > | | - |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterValueBefore(code) {\n // Align: left.\n if (code === 58) {\n sizeB += 1;\n seen = true;\n effects.enter('tableDelimiterMarker');\n effects.consume(code);\n effects.exit('tableDelimiterMarker');\n return headDelimiterLeftAlignmentAfter;\n }\n\n // Align: none.\n if (code === 45) {\n sizeB += 1;\n // To do: seems weird that this *isn’t* left aligned, but that state is used?\n return headDelimiterLeftAlignmentAfter(code);\n }\n if (code === null || markdownLineEnding(code)) {\n return headDelimiterCellAfter(code);\n }\n return headDelimiterNok(code);\n }\n\n /**\n * After delimiter cell left alignment marker.\n *\n * ```markdown\n * | | a |\n * > | | :- |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterLeftAlignmentAfter(code) {\n if (code === 45) {\n effects.enter('tableDelimiterFiller');\n return headDelimiterFiller(code);\n }\n\n // Anything else is not ok after the left-align colon.\n return headDelimiterNok(code);\n }\n\n /**\n * In delimiter cell filler.\n *\n * ```markdown\n * | | a |\n * > | | - |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterFiller(code) {\n if (code === 45) {\n effects.consume(code);\n return headDelimiterFiller;\n }\n\n // Align is `center` if it was `left`, `right` otherwise.\n if (code === 58) {\n seen = true;\n effects.exit('tableDelimiterFiller');\n effects.enter('tableDelimiterMarker');\n effects.consume(code);\n effects.exit('tableDelimiterMarker');\n return headDelimiterRightAlignmentAfter;\n }\n effects.exit('tableDelimiterFiller');\n return headDelimiterRightAlignmentAfter(code);\n }\n\n /**\n * After delimiter cell right alignment marker.\n *\n * ```markdown\n * | | a |\n * > | | -: |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterRightAlignmentAfter(code) {\n if (markdownSpace(code)) {\n return factorySpace(effects, headDelimiterCellAfter, \"whitespace\")(code);\n }\n return headDelimiterCellAfter(code);\n }\n\n /**\n * After delimiter cell.\n *\n * ```markdown\n * | | a |\n * > | | -: |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterCellAfter(code) {\n if (code === 124) {\n return headDelimiterBefore(code);\n }\n if (code === null || markdownLineEnding(code)) {\n // Exit when:\n // * there was no `:` or `|` at all (it’s a thematic break or setext\n // underline instead)\n // * the header cell count is not the delimiter cell count\n if (!seen || size !== sizeB) {\n return headDelimiterNok(code);\n }\n\n // Note: in markdown-rs`, a reset is needed here.\n effects.exit('tableDelimiterRow');\n effects.exit('tableHead');\n // To do: in `markdown-rs`, resolvers need to be registered manually.\n // effects.register_resolver(ResolveName::GfmTable)\n return ok(code);\n }\n return headDelimiterNok(code);\n }\n\n /**\n * In delimiter row, at a disallowed byte.\n *\n * ```markdown\n * | | a |\n * > | | x |\n * ^\n * ```\n *\n * @type {State}\n */\n function headDelimiterNok(code) {\n // Note: in `markdown-rs`, we need to reset, in `micromark-js` we don‘t.\n return nok(code);\n }\n\n /**\n * Before table body row.\n *\n * ```markdown\n * | | a |\n * | | - |\n * > | | b |\n * ^\n * ```\n *\n * @type {State}\n */\n function bodyRowStart(code) {\n // Note: in `markdown-rs` we need to manually take care of a prefix,\n // but in `micromark-js` that is done for us, so if we’re here, we’re\n // never at whitespace.\n effects.enter('tableRow');\n return bodyRowBreak(code);\n }\n\n /**\n * At break in table body row.\n *\n * ```markdown\n * | | a |\n * | | - |\n * > | | b |\n * ^\n * ^\n * ^\n * ```\n *\n * @type {State}\n */\n function bodyRowBreak(code) {\n if (code === 124) {\n effects.enter('tableCellDivider');\n effects.consume(code);\n effects.exit('tableCellDivider');\n return bodyRowBreak;\n }\n if (code === null || markdownLineEnding(code)) {\n effects.exit('tableRow');\n return ok(code);\n }\n if (markdownSpace(code)) {\n return factorySpace(effects, bodyRowBreak, \"whitespace\")(code);\n }\n\n // Anything else is cell content.\n effects.enter(\"data\");\n return bodyRowData(code);\n }\n\n /**\n * In table body row data.\n *\n * ```markdown\n * | | a |\n * | | - |\n * > | | b |\n * ^\n * ```\n *\n * @type {State}\n */\n function bodyRowData(code) {\n if (code === null || code === 124 || markdownLineEndingOrSpace(code)) {\n effects.exit(\"data\");\n return bodyRowBreak(code);\n }\n effects.consume(code);\n return code === 92 ? bodyRowEscape : bodyRowData;\n }\n\n /**\n * In table body row escape.\n *\n * ```markdown\n * | | a |\n * | | ---- |\n * > | | b\\-c |\n * ^\n * ```\n *\n * @type {State}\n */\n function bodyRowEscape(code) {\n if (code === 92 || code === 124) {\n effects.consume(code);\n return bodyRowData;\n }\n return bodyRowData(code);\n }\n}\n\n/** @type {Resolver} */\n\nfunction resolveTable(events, context) {\n let index = -1;\n let inFirstCellAwaitingPipe = true;\n /** @type {RowKind} */\n let rowKind = 0;\n /** @type {Range} */\n let lastCell = [0, 0, 0, 0];\n /** @type {Range} */\n let cell = [0, 0, 0, 0];\n let afterHeadAwaitingFirstBodyRow = false;\n let lastTableEnd = 0;\n /** @type {Token | undefined} */\n let currentTable;\n /** @type {Token | undefined} */\n let currentBody;\n /** @type {Token | undefined} */\n let currentCell;\n const map = new EditMap();\n while (++index < events.length) {\n const event = events[index];\n const token = event[1];\n if (event[0] === 'enter') {\n // Start of head.\n if (token.type === 'tableHead') {\n afterHeadAwaitingFirstBodyRow = false;\n\n // Inject previous (body end and) table end.\n if (lastTableEnd !== 0) {\n flushTableEnd(map, context, lastTableEnd, currentTable, currentBody);\n currentBody = undefined;\n lastTableEnd = 0;\n }\n\n // Inject table start.\n currentTable = {\n type: 'table',\n start: Object.assign({}, token.start),\n // Note: correct end is set later.\n end: Object.assign({}, token.end)\n };\n map.add(index, 0, [['enter', currentTable, context]]);\n } else if (token.type === 'tableRow' || token.type === 'tableDelimiterRow') {\n inFirstCellAwaitingPipe = true;\n currentCell = undefined;\n lastCell = [0, 0, 0, 0];\n cell = [0, index + 1, 0, 0];\n\n // Inject table body start.\n if (afterHeadAwaitingFirstBodyRow) {\n afterHeadAwaitingFirstBodyRow = false;\n currentBody = {\n type: 'tableBody',\n start: Object.assign({}, token.start),\n // Note: correct end is set later.\n end: Object.assign({}, token.end)\n };\n map.add(index, 0, [['enter', currentBody, context]]);\n }\n rowKind = token.type === 'tableDelimiterRow' ? 2 : currentBody ? 3 : 1;\n }\n // Cell data.\n else if (rowKind && (token.type === \"data\" || token.type === 'tableDelimiterMarker' || token.type === 'tableDelimiterFiller')) {\n inFirstCellAwaitingPipe = false;\n\n // First value in cell.\n if (cell[2] === 0) {\n if (lastCell[1] !== 0) {\n cell[0] = cell[1];\n currentCell = flushCell(map, context, lastCell, rowKind, undefined, currentCell);\n lastCell = [0, 0, 0, 0];\n }\n cell[2] = index;\n }\n } else if (token.type === 'tableCellDivider') {\n if (inFirstCellAwaitingPipe) {\n inFirstCellAwaitingPipe = false;\n } else {\n if (lastCell[1] !== 0) {\n cell[0] = cell[1];\n currentCell = flushCell(map, context, lastCell, rowKind, undefined, currentCell);\n }\n lastCell = cell;\n cell = [lastCell[1], index, 0, 0];\n }\n }\n }\n // Exit events.\n else if (token.type === 'tableHead') {\n afterHeadAwaitingFirstBodyRow = true;\n lastTableEnd = index;\n } else if (token.type === 'tableRow' || token.type === 'tableDelimiterRow') {\n lastTableEnd = index;\n if (lastCell[1] !== 0) {\n cell[0] = cell[1];\n currentCell = flushCell(map, context, lastCell, rowKind, index, currentCell);\n } else if (cell[1] !== 0) {\n currentCell = flushCell(map, context, cell, rowKind, index, currentCell);\n }\n rowKind = 0;\n } else if (rowKind && (token.type === \"data\" || token.type === 'tableDelimiterMarker' || token.type === 'tableDelimiterFiller')) {\n cell[3] = index;\n }\n }\n if (lastTableEnd !== 0) {\n flushTableEnd(map, context, lastTableEnd, currentTable, currentBody);\n }\n map.consume(context.events);\n\n // To do: move this into `html`, when events are exposed there.\n // That’s what `markdown-rs` does.\n // That needs updates to `mdast-util-gfm-table`.\n index = -1;\n while (++index < context.events.length) {\n const event = context.events[index];\n if (event[0] === 'enter' && event[1].type === 'table') {\n event[1]._align = gfmTableAlign(context.events, index);\n }\n }\n return events;\n}\n\n/**\n * Generate a cell.\n *\n * @param {EditMap} map\n * @param {Readonly<TokenizeContext>} context\n * @param {Readonly<Range>} range\n * @param {RowKind} rowKind\n * @param {number | undefined} rowEnd\n * @param {Token | undefined} previousCell\n * @returns {Token | undefined}\n */\n// eslint-disable-next-line max-params\nfunction flushCell(map, context, range, rowKind, rowEnd, previousCell) {\n // `markdown-rs` uses:\n // rowKind === 2 ? 'tableDelimiterCell' : 'tableCell'\n const groupName = rowKind === 1 ? 'tableHeader' : rowKind === 2 ? 'tableDelimiter' : 'tableData';\n // `markdown-rs` uses:\n // rowKind === 2 ? 'tableDelimiterCellValue' : 'tableCellText'\n const valueName = 'tableContent';\n\n // Insert an exit for the previous cell, if there is one.\n //\n // ```markdown\n // > | | aa | bb | cc |\n // ^-- exit\n // ^^^^-- this cell\n // ```\n if (range[0] !== 0) {\n previousCell.end = Object.assign({}, getPoint(context.events, range[0]));\n map.add(range[0], 0, [['exit', previousCell, context]]);\n }\n\n // Insert enter of this cell.\n //\n // ```markdown\n // > | | aa | bb | cc |\n // ^-- enter\n // ^^^^-- this cell\n // ```\n const now = getPoint(context.events, range[1]);\n previousCell = {\n type: groupName,\n start: Object.assign({}, now),\n // Note: correct end is set later.\n end: Object.assign({}, now)\n };\n map.add(range[1], 0, [['enter', previousCell, context]]);\n\n // Insert text start at first data start and end at last data end, and\n // remove events between.\n //\n // ```markdown\n // > | | aa | bb | cc |\n // ^-- enter\n // ^-- exit\n // ^^^^-- this cell\n // ```\n if (range[2] !== 0) {\n const relatedStart = getPoint(context.events, range[2]);\n const relatedEnd = getPoint(context.events, range[3]);\n /** @type {Token} */\n const valueToken = {\n type: valueName,\n start: Object.assign({}, relatedStart),\n end: Object.assign({}, relatedEnd)\n };\n map.add(range[2], 0, [['enter', valueToken, context]]);\n if (rowKind !== 2) {\n // Fix positional info on remaining events\n const start = context.events[range[2]];\n const end = context.events[range[3]];\n start[1].end = Object.assign({}, end[1].end);\n start[1].type = \"chunkText\";\n start[1].contentType = \"text\";\n\n // Remove if needed.\n if (range[3] > range[2] + 1) {\n const a = range[2] + 1;\n const b = range[3] - range[2] - 1;\n map.add(a, b, []);\n }\n }\n map.add(range[3] + 1, 0, [['exit', valueToken, context]]);\n }\n\n // Insert an exit for the last cell, if at the row end.\n //\n // ```markdown\n // > | | aa | bb | cc |\n // ^-- exit\n // ^^^^^^-- this cell (the last one contains two “between” parts)\n // ```\n if (rowEnd !== undefined) {\n previousCell.end = Object.assign({}, getPoint(context.events, rowEnd));\n map.add(rowEnd, 0, [['exit', previousCell, context]]);\n previousCell = undefined;\n }\n return previousCell;\n}\n\n/**\n * Generate table end (and table body end).\n *\n * @param {Readonly<EditMap>} map\n * @param {Readonly<TokenizeContext>} context\n * @param {number} index\n * @param {Token} table\n * @param {Token | undefined} tableBody\n */\n// eslint-disable-next-line max-params\nfunction flushTableEnd(map, context, index, table, tableBody) {\n /** @type {Array<Event>} */\n const exits = [];\n const related = getPoint(context.events, index);\n if (tableBody) {\n tableBody.end = Object.assign({}, related);\n exits.push(['exit', tableBody, context]);\n }\n table.end = Object.assign({}, related);\n exits.push(['exit', table, context]);\n map.add(index + 1, 0, exits);\n}\n\n/**\n * @param {Readonly<Array<Event>>} events\n * @param {number} index\n * @returns {Readonly<Point>}\n */\nfunction getPoint(events, index) {\n const event = events[index];\n const side = event[0] === 'enter' ? 'start' : 'end';\n return event[1][side];\n}","/**\n * @import {Event} from 'micromark-util-types'\n */\n\n// Port of `edit_map.rs` from `markdown-rs`.\n// This should move to `markdown-js` later.\n\n// Deal with several changes in events, batching them together.\n//\n// Preferably, changes should be kept to a minimum.\n// Sometimes, it’s needed to change the list of events, because parsing can be\n// messy, and it helps to expose a cleaner interface of events to the compiler\n// and other users.\n// It can also help to merge many adjacent similar events.\n// And, in other cases, it’s needed to parse subcontent: pass some events\n// through another tokenizer and inject the result.\n\n/**\n * @typedef {[number, number, Array<Event>]} Change\n * @typedef {[number, number, number]} Jump\n */\n\n/**\n * Tracks a bunch of edits.\n */\nexport class EditMap {\n /**\n * Create a new edit map.\n */\n constructor() {\n /**\n * Record of changes.\n *\n * @type {Array<Change>}\n */\n this.map = [];\n }\n\n /**\n * Create an edit: a remove and/or add at a certain place.\n *\n * @param {number} index\n * @param {number} remove\n * @param {Array<Event>} add\n * @returns {undefined}\n */\n add(index, remove, add) {\n addImplementation(this, index, remove, add);\n }\n\n // To do: add this when moving to `micromark`.\n // /**\n // * Create an edit: but insert `add` before existing additions.\n // *\n // * @param {number} index\n // * @param {number} remove\n // * @param {Array<Event>} add\n // * @returns {undefined}\n // */\n // addBefore(index, remove, add) {\n // addImplementation(this, index, remove, add, true)\n // }\n\n /**\n * Done, change the events.\n *\n * @param {Array<Event>} events\n * @returns {undefined}\n */\n consume(events) {\n this.map.sort(function (a, b) {\n return a[0] - b[0];\n });\n\n /* c8 ignore next 3 -- `resolve` is never called without tables, so without edits. */\n if (this.map.length === 0) {\n return;\n }\n\n // To do: if links are added in events, like they are in `markdown-rs`,\n // this is needed.\n // // Calculate jumps: where items in the current list move to.\n // /** @type {Array<Jump>} */\n // const jumps = []\n // let index = 0\n // let addAcc = 0\n // let removeAcc = 0\n // while (index < this.map.length) {\n // const [at, remove, add] = this.map[index]\n // removeAcc += remove\n // addAcc += add.length\n // jumps.push([at, removeAcc, addAcc])\n // index += 1\n // }\n //\n // . shiftLinks(events, jumps)\n\n let index = this.map.length;\n /** @type {Array<Array<Event>>} */\n const vecs = [];\n while (index > 0) {\n index -= 1;\n vecs.push(events.slice(this.map[index][0] + this.map[index][1]), this.map[index][2]);\n\n // Truncate rest.\n events.length = this.map[index][0];\n }\n vecs.push(events.slice());\n events.length = 0;\n let slice = vecs.pop();\n while (slice) {\n for (const element of slice) {\n events.push(element);\n }\n slice = vecs.pop();\n }\n\n // Truncate everything.\n this.map.length = 0;\n }\n}\n\n/**\n * Create an edit.\n *\n * @param {EditMap} editMap\n * @param {number} at\n * @param {number} remove\n * @param {Array<Event>} add\n * @returns {undefined}\n */\nfunction addImplementation(editMap, at, remove, add) {\n let index = 0;\n\n /* c8 ignore next 3 -- `resolve` is never called without tables, so without edits. */\n if (remove === 0 && add.length === 0) {\n return;\n }\n while (index < editMap.map.length) {\n if (editMap.map[index][0] === at) {\n editMap.map[index][1] += remove;\n\n // To do: before not used by tables, use when moving to micromark.\n // if (before) {\n // add.push(...editMap.map[index][2])\n // editMap.map[index][2] = add\n // } else {\n editMap.map[index][2].push(...add);\n // }\n\n return;\n }\n index += 1;\n }\n editMap.map.push([at, remove, add]);\n}\n\n// /**\n// * Shift `previous` and `next` links according to `jumps`.\n// *\n// * This fixes links in case there are events removed or added between them.\n// *\n// * @param {Array<Event>} events\n// * @param {Array<Jump>} jumps\n// */\n// function shiftLinks(events, jumps) {\n// let jumpIndex = 0\n// let index = 0\n// let add = 0\n// let rm = 0\n\n// while (index < events.length) {\n// const rmCurr = rm\n\n// while (jumpIndex < jumps.length && jumps[jumpIndex][0] <= index) {\n// add = jumps[jumpIndex][2]\n// rm = jumps[jumpIndex][1]\n// jumpIndex += 1\n// }\n\n// // Ignore items that will be removed.\n// if (rm > rmCurr) {\n// index += rm - rmCurr\n// } else {\n// // ?\n// // if let Some(link) = &events[index].link {\n// // if let Some(next) = link.next {\n// // events[next].link.as_mut().unwrap().previous = Some(index + add - rm);\n// // while jumpIndex < jumps.len() && jumps[jumpIndex].0 <= next {\n// // add = jumps[jumpIndex].2;\n// // rm = jumps[jumpIndex].1;\n// // jumpIndex += 1;\n// // }\n// // events[index].link.as_mut().unwrap().next = Some(next + add - rm);\n// // index = next;\n// // continue;\n// // }\n// // }\n// index += 1\n// }\n// }\n// }","/**\n * @import {Event} from 'micromark-util-types'\n */\n\n/**\n * @typedef {'center' | 'left' | 'none' | 'right'} Align\n */\n\n/**\n * Figure out the alignment of a GFM table.\n *\n * @param {Readonly<Array<Event>>} events\n * List of events.\n * @param {number} index\n * Table enter event.\n * @returns {Array<Align>}\n * List of aligns.\n */\nexport function gfmTableAlign(events, index) {\n let inDelimiterRow = false;\n /** @type {Array<Align>} */\n const align = [];\n while (index < events.length) {\n const event = events[index];\n if (inDelimiterRow) {\n if (event[0] === 'enter') {\n // Start of alignment value: set a new column.\n // To do: `markdown-rs` uses `tableDelimiterCellValue`.\n if (event[1].type === 'tableContent') {\n align.push(events[index + 1][1].type === 'tableDelimiterMarker' ? 'left' : 'none');\n }\n }\n // Exits:\n // End of alignment value: change the column.\n // To do: `markdown-rs` uses `tableDelimiterCellValue`.\n else if (event[1].type === 'tableContent') {\n if (events[index - 1][1].type === 'tableDelimiterMarker') {\n const alignIndex = align.length - 1;\n align[alignIndex] = align[alignIndex] === 'left' ? 'center' : 'right';\n }\n }\n // Done!\n else if (event[1].type === 'tableDelimiterRow') {\n break;\n }\n } else if (event[0] === 'enter' && event[1].type === 'tableDelimiterRow') {\n inDelimiterRow = true;\n }\n index += 1;\n }\n return align;\n}","/**\n * @import {Extension, State, TokenizeContext, Tokenizer} from 'micromark-util-types'\n */\n\nimport { factorySpace } from 'micromark-factory-space';\nimport { markdownLineEnding, markdownLineEndingOrSpace, markdownSpace } from 'micromark-util-character';\nconst tasklistCheck = {\n name: 'tasklistCheck',\n tokenize: tokenizeTasklistCheck\n};\n\n/**\n * Create an HTML extension for `micromark` to support GFM task list items\n * syntax.\n *\n * @returns {Extension}\n * Extension for `micromark` that can be passed in `htmlExtensions` to\n * support GFM task list items when serializing to HTML.\n */\nexport function gfmTaskListItem() {\n return {\n text: {\n [91]: tasklistCheck\n }\n };\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction tokenizeTasklistCheck(effects, ok, nok) {\n const self = this;\n return open;\n\n /**\n * At start of task list item check.\n *\n * ```markdown\n * > | * [x] y.\n * ^\n * ```\n *\n * @type {State}\n */\n function open(code) {\n if (\n // Exit if there’s stuff before.\n self.previous !== null ||\n // Exit if not in the first content that is the first child of a list\n // item.\n !self._gfmTasklistFirstContentOfListItem) {\n return nok(code);\n }\n effects.enter('taskListCheck');\n effects.enter('taskListCheckMarker');\n effects.consume(code);\n effects.exit('taskListCheckMarker');\n return inside;\n }\n\n /**\n * In task list item check.\n *\n * ```markdown\n * > | * [x] y.\n * ^\n * ```\n *\n * @type {State}\n */\n function inside(code) {\n // Currently we match how GH works in files.\n // To match how GH works in comments, use `markdownSpace` (`[\\t ]`) instead\n // of `markdownLineEndingOrSpace` (`[\\t\\n\\r ]`).\n if (markdownLineEndingOrSpace(code)) {\n effects.enter('taskListCheckValueUnchecked');\n effects.consume(code);\n effects.exit('taskListCheckValueUnchecked');\n return close;\n }\n if (code === 88 || code === 120) {\n effects.enter('taskListCheckValueChecked');\n effects.consume(code);\n effects.exit('taskListCheckValueChecked');\n return close;\n }\n return nok(code);\n }\n\n /**\n * At close of task list item check.\n *\n * ```markdown\n * > | * [x] y.\n * ^\n * ```\n *\n * @type {State}\n */\n function close(code) {\n if (code === 93) {\n effects.enter('taskListCheckMarker');\n effects.consume(code);\n effects.exit('taskListCheckMarker');\n effects.exit('taskListCheck');\n return after;\n }\n return nok(code);\n }\n\n /**\n * @type {State}\n */\n function after(code) {\n // EOL in paragraph means there must be something else after it.\n if (markdownLineEnding(code)) {\n return ok(code);\n }\n\n // Space or tab?\n // Check what comes after.\n if (markdownSpace(code)) {\n return effects.check({\n tokenize: spaceThenNonSpace\n }, ok, nok)(code);\n }\n\n // EOF, or non-whitespace, both wrong.\n return nok(code);\n }\n}\n\n/**\n * @this {TokenizeContext}\n * @type {Tokenizer}\n */\nfunction spaceThenNonSpace(effects, ok, nok) {\n return factorySpace(effects, after, \"whitespace\");\n\n /**\n * After whitespace, after task list item check.\n *\n * ```markdown\n * > | * [x] y.\n * ^\n * ```\n *\n * @type {State}\n */\n function after(code) {\n // EOF means there was nothing, so bad.\n // EOL means there’s content after it, so good.\n // Impossible to have more spaces.\n // Anything else is good.\n return code === null ? nok(code) : ok(code);\n }\n}","/**\n * mdast transform plugin for Jinja if/elif/else/endif blocks.\n *\n * Three passes:\n * Pass 1 — Extract Jinja tags absorbed into list item text (Case B)\n * Pass 2 — Group standalone Jinja-tag paragraphs into jinjaIfBlockMdast nodes (Case A)\n * Pass 3 — Structure inline Jinja tags into jinjaIfInlineMdast nodes\n */\n\nconst MAX_DEPTH = 128;\n\n// Regex for a standalone Jinja tag paragraph (entire paragraph is one tag)\nconst JINJA_BLOCK_RE = /^\\s*\\{%\\s*(if|elif|else|endif)\\s*([^%]*?)\\s*%\\}\\s*$/;\n\n// Regex for Jinja tags at line boundaries inside list item text\nconst JINJA_LINE_END_RE = /\\n\\s*(\\{%\\s*(?:if|elif|else|endif)\\s*[^%]*?\\s*%\\})\\s*$/;\nconst JINJA_LINE_START_RE = /^(\\{%\\s*(?:if|elif|else|endif)\\s*[^%]*?\\s*%\\})\\s*\\n/;\n\n// Regex for inline Jinja tags (non-greedy, captures tag type and condition)\nconst JINJA_INLINE_RE = /\\{%\\s*(if|elif|else|endif)\\s*([^%]*?)\\s*%\\}/g;\n\ntype BranchType = 'if' | 'elif' | 'else';\n\nexport interface JinjaBranchMdast {\n branchType: BranchType;\n condition?: string;\n content: unknown[];\n}\n\nexport interface JinjaIfBlockMdastNode {\n type: 'jinjaIfBlockMdast';\n branches: JinjaBranchMdast[];\n}\n\nexport interface JinjaIfInlineMdastNode {\n type: 'jinjaIfInlineMdast';\n branches: JinjaBranchMdast[];\n}\n\ndeclare module 'mdast' {\n interface BlockContentMap {\n jinjaIfBlockMdast: JinjaIfBlockMdastNode;\n }\n interface PhrasingContentMap {\n jinjaIfInlineMdast: JinjaIfInlineMdastNode;\n }\n interface RootContentMap {\n jinjaIfBlockMdast: JinjaIfBlockMdastNode;\n }\n}\n\nfunction parseTag(text: string): { type: 'if' | 'elif' | 'else' | 'endif'; condition?: string } | null {\n const m = text.match(/^\\s*\\{%\\s*(if|elif|else|endif)\\s*([^%]*?)\\s*%\\}\\s*$/);\n if (!m) return null;\n const type = m[1] as 'if' | 'elif' | 'else' | 'endif';\n const condition = m[2]?.trim() || undefined;\n return { type, condition };\n}\n\nfunction isTextOnlyParagraph(node: { type: string; children?: unknown[] }): string | null {\n if (node.type !== 'paragraph') return null;\n if (!node.children || node.children.length !== 1) return null;\n const child = node.children[0] as { type: string; value?: string };\n if (child.type !== 'text') return null;\n return child.value ?? null;\n}\n\n/**\n * Pass 1: Extract Jinja tags absorbed into list item text.\n * When there's no blank line between a Jinja tag and a list, mdast absorbs\n * the tag into the list item's text. We split these out.\n */\nfunction pass1ExtractFromLists(node: { type: string; children?: unknown[] }, depth: number): void {\n if (depth > MAX_DEPTH || !node.children) return;\n\n // Recurse first\n for (const child of node.children) {\n pass1ExtractFromLists(child as { type: string; children?: unknown[] }, depth + 1);\n }\n\n // Only process list nodes\n if (node.type !== 'list') return;\n\n const list = node as { type: string; ordered?: boolean; start?: number; spread?: boolean; children: unknown[] };\n const items = list.children as Array<{ type: string; children: Array<{ type: string; children?: Array<{ type: string; value?: string }> }> }>;\n\n // Scan list items for Jinja tags at text boundaries\n type ExtractedPiece =\n | { kind: 'item'; item: unknown }\n | { kind: 'tag'; raw: string };\n\n const extracted: ExtractedPiece[] = [];\n let hadSplit = false;\n\n for (const item of items) {\n if (item.type !== 'listItem' || !item.children || item.children.length === 0) {\n extracted.push({ kind: 'item', item });\n continue;\n }\n\n // Check first paragraph for leading Jinja tag\n const firstChild = item.children[0];\n if (firstChild.type === 'paragraph' && firstChild.children && firstChild.children.length === 1 && firstChild.children[0].type === 'text') {\n const text = firstChild.children[0].value ?? '';\n const startMatch = text.match(JINJA_LINE_START_RE);\n if (startMatch) {\n hadSplit = true;\n extracted.push({ kind: 'tag', raw: startMatch[1] });\n const remainder = text.slice(startMatch[0].length);\n if (remainder.trim()) {\n firstChild.children[0] = { ...firstChild.children[0], value: remainder };\n extracted.push({ kind: 'item', item });\n } else if (item.children.length > 1) {\n item.children = item.children.slice(1);\n extracted.push({ kind: 'item', item });\n }\n continue;\n }\n }\n\n // Check last paragraph for trailing Jinja tag\n const lastChild = item.children[item.children.length - 1];\n if (lastChild.type === 'paragraph' && lastChild.children && lastChild.children.length === 1 && lastChild.children[0].type === 'text') {\n const text = lastChild.children[0].value ?? '';\n const endMatch = text.match(JINJA_LINE_END_RE);\n if (endMatch) {\n hadSplit = true;\n const remainder = text.slice(0, text.length - endMatch[0].length);\n if (remainder.trim()) {\n lastChild.children[0] = { ...lastChild.children[0], value: remainder };\n extracted.push({ kind: 'item', item });\n } else if (item.children.length > 1) {\n item.children = item.children.slice(0, -1);\n extracted.push({ kind: 'item', item });\n }\n extracted.push({ kind: 'tag', raw: endMatch[1] });\n continue;\n }\n }\n\n extracted.push({ kind: 'item', item });\n }\n\n if (!hadSplit) return;\n\n // Rebuild: replace parent's list node with a sequence of lists and tag paragraphs\n // We need to modify the parent's children. Since we're in the list node itself,\n // we'll reconstruct the list into segments.\n const parent = node as { type: string; children: unknown[] };\n\n // Actually, we need to replace this list node in its parent.\n // Instead, we mark the list with a special property to be expanded later.\n // Let's use a different approach: collect consecutive items into sub-lists,\n // interleaved with tag paragraphs.\n\n const result: unknown[] = [];\n let currentItems: unknown[] = [];\n let itemIndex = 0;\n\n function flushItems(): void {\n if (currentItems.length === 0) return;\n const startNum = list.ordered ? (list.start ?? 1) + itemIndex - currentItems.length : undefined;\n const subList = {\n type: 'list',\n ordered: list.ordered ?? false,\n spread: list.spread ?? false,\n ...(list.ordered ? { start: startNum } : {}),\n children: currentItems,\n };\n result.push(subList);\n currentItems = [];\n }\n\n for (const piece of extracted) {\n if (piece.kind === 'item') {\n currentItems.push(piece.item);\n itemIndex++;\n } else {\n flushItems();\n result.push({\n type: 'paragraph',\n children: [{ type: 'text', value: piece.raw }],\n });\n }\n }\n flushItems();\n\n // Mark this node for expansion in parent\n (node as { _jinjaExpanded?: unknown[] })._jinjaExpanded = result;\n}\n\n/**\n * After pass1, expand any list nodes that were marked with _jinjaExpanded.\n */\nfunction expandMarkedLists(node: { type: string; children?: unknown[] }, depth: number): void {\n if (depth > MAX_DEPTH || !node.children) return;\n\n // Process children first (bottom-up)\n for (const child of node.children) {\n expandMarkedLists(child as { type: string; children?: unknown[] }, depth + 1);\n }\n\n const newChildren: unknown[] = [];\n let changed = false;\n for (const child of node.children) {\n const c = child as { _jinjaExpanded?: unknown[] };\n if (c._jinjaExpanded) {\n newChildren.push(...c._jinjaExpanded);\n changed = true;\n } else {\n newChildren.push(child);\n }\n }\n if (changed) {\n node.children = newChildren;\n }\n}\n\n/**\n * Pass 2: Group standalone Jinja-tag paragraphs into jinjaIfBlockMdast nodes.\n * Works on children of root, blockquote, and listItem.\n */\nfunction pass2GroupBlocks(node: { type: string; children?: unknown[] }, depth: number): void {\n if (depth > MAX_DEPTH || !node.children) return;\n\n // Recurse into children first\n for (const child of node.children) {\n pass2GroupBlocks(child as { type: string; children?: unknown[] }, depth + 1);\n }\n\n // Only process container nodes\n const containerTypes = new Set(['root', 'blockquote', 'listItem']);\n if (!containerTypes.has(node.type)) return;\n\n const children = node.children as Array<{ type: string; children?: unknown[] }>;\n const result: unknown[] = [];\n let i = 0;\n\n while (i < children.length) {\n const child = children[i];\n const text = isTextOnlyParagraph(child);\n const tag = text ? parseTag(text) : null;\n\n if (!tag || tag.type !== 'if') {\n result.push(child);\n i++;\n continue;\n }\n\n // Found {% if %} - use stack to find matching {% endif %}\n const ifParagraph = child; // save for position\n const branches: JinjaBranchMdast[] = [];\n let currentBranch: JinjaBranchMdast = {\n branchType: 'if',\n condition: tag.condition,\n content: [],\n };\n branches.push(currentBranch);\n\n let nestDepth = 1;\n i++; // skip the {% if %} paragraph\n\n let matched = false;\n let endifParagraph: { type: string; children?: unknown[]; position?: unknown } | null = null;\n while (i < children.length && nestDepth > 0) {\n const innerChild = children[i];\n const innerText = isTextOnlyParagraph(innerChild);\n const innerTag = innerText ? parseTag(innerText) : null;\n\n if (innerTag) {\n if (innerTag.type === 'if') {\n nestDepth++;\n if (nestDepth > 1) {\n currentBranch.content.push(innerChild);\n }\n } else if (innerTag.type === 'endif') {\n nestDepth--;\n if (nestDepth === 0) {\n matched = true;\n endifParagraph = innerChild;\n } else {\n currentBranch.content.push(innerChild);\n }\n } else if ((innerTag.type === 'elif' || innerTag.type === 'else') && nestDepth === 1) {\n currentBranch = {\n branchType: innerTag.type as BranchType,\n ...(innerTag.condition ? { condition: innerTag.condition } : {}),\n content: [],\n };\n branches.push(currentBranch);\n } else {\n currentBranch.content.push(innerChild);\n }\n } else {\n currentBranch.content.push(innerChild);\n }\n i++;\n }\n\n if (matched) {\n // Recursively process branch contents\n for (const branch of branches) {\n const wrapper = { type: node.type, children: branch.content };\n pass2GroupBlocks(wrapper, depth + 1);\n branch.content = wrapper.children as unknown[];\n }\n // Propagate position from {% if %} to {% endif %} for blank-line calculation\n const startPos = (ifParagraph as { position?: { start?: unknown } }).position?.start;\n const endPos = (endifParagraph as { position?: { end?: unknown } } | null)?.position?.end;\n const pos = startPos && endPos ? { position: { start: startPos, end: endPos } } : {};\n result.push({ type: 'jinjaIfBlockMdast', branches, ...pos });\n } else {\n // Unmatched {% if %} — restore as plain paragraph\n result.push({ type: 'paragraph', children: [{ type: 'text', value: text }] });\n // Rewind: the content we consumed needs to go back\n // Actually, we already advanced i, and the branches contain the consumed children.\n // We need to flatten them back.\n for (const branch of branches) {\n if (branch !== branches[0]) {\n // Re-emit the branch tag\n const tagText = branch.branchType === 'else'\n ? '{% else %}'\n : `{% ${branch.branchType} ${branch.condition ?? ''} %}`.trim();\n result.push({ type: 'paragraph', children: [{ type: 'text', value: tagText }] });\n }\n result.push(...branch.content);\n }\n }\n }\n\n node.children = result;\n}\n\n/**\n * Pass 3: Structure inline Jinja tags within paragraph/heading text nodes.\n * Only processes direct text children (not inside marks like strong/emphasis).\n */\nfunction pass3InlineJinja(node: { type: string; children?: unknown[] }, depth: number): void {\n if (depth > MAX_DEPTH || !node.children) return;\n\n // Recurse into block-level children\n for (const child of node.children) {\n pass3InlineJinja(child as { type: string; children?: unknown[] }, depth + 1);\n }\n\n // Only process paragraph and heading\n if (node.type !== 'paragraph' && node.type !== 'heading') return;\n\n const children = node.children as Array<{ type: string; value?: string }>;\n\n // Check if any text child contains Jinja tags\n let hasJinja = false;\n for (const child of children) {\n if (child.type === 'text' && child.value) {\n JINJA_INLINE_RE.lastIndex = 0;\n if (JINJA_INLINE_RE.test(child.value)) {\n hasJinja = true;\n break;\n }\n }\n }\n if (!hasJinja) return;\n\n // Split text nodes on Jinja tags, then structure with stack\n const flatParts: Array<{ kind: 'node'; node: unknown } | { kind: 'tag'; tagType: 'if' | 'elif' | 'else' | 'endif'; condition?: string }> = [];\n\n for (const child of children) {\n if (child.type !== 'text' || !child.value) {\n flatParts.push({ kind: 'node', node: child });\n continue;\n }\n\n const text = child.value;\n JINJA_INLINE_RE.lastIndex = 0;\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = JINJA_INLINE_RE.exec(text)) !== null) {\n if (match.index > lastIndex) {\n flatParts.push({ kind: 'node', node: { type: 'text', value: text.slice(lastIndex, match.index) } });\n }\n flatParts.push({\n kind: 'tag',\n tagType: match[1] as 'if' | 'elif' | 'else' | 'endif',\n condition: match[2]?.trim() || undefined,\n });\n lastIndex = match.index + match[0].length;\n }\n\n if (lastIndex < text.length) {\n flatParts.push({ kind: 'node', node: { type: 'text', value: text.slice(lastIndex) } });\n }\n }\n\n // Stack-based structuring\n const result = structureInlineParts(flatParts);\n if (result) {\n node.children = result;\n }\n}\n\nfunction structureInlineParts(\n parts: Array<{ kind: 'node'; node: unknown } | { kind: 'tag'; tagType: 'if' | 'elif' | 'else' | 'endif'; condition?: string }>,\n): unknown[] | null {\n const output: unknown[] = [];\n let i = 0;\n\n while (i < parts.length) {\n const part = parts[i];\n if (part.kind === 'node') {\n output.push(part.node);\n i++;\n } else if (part.kind === 'tag' && part.tagType === 'if') {\n // Collect branches until matching endif\n const branches: JinjaBranchMdast[] = [];\n let currentBranch: JinjaBranchMdast = {\n branchType: 'if',\n condition: part.condition,\n content: [],\n };\n branches.push(currentBranch);\n i++;\n\n let nestDepth = 1;\n let matched = false;\n\n while (i < parts.length && nestDepth > 0) {\n const inner = parts[i];\n if (inner.kind === 'tag') {\n if (inner.tagType === 'if') {\n nestDepth++;\n if (nestDepth > 1) {\n // Nested if — emit as text for now\n currentBranch.content.push({ type: 'text', value: `{% if ${inner.condition ?? ''} %}`.trim() });\n }\n } else if (inner.tagType === 'endif') {\n nestDepth--;\n if (nestDepth === 0) {\n matched = true;\n } else {\n currentBranch.content.push({ type: 'text', value: '{% endif %}' });\n }\n } else if ((inner.tagType === 'elif' || inner.tagType === 'else') && nestDepth === 1) {\n currentBranch = {\n branchType: inner.tagType as BranchType,\n ...(inner.condition ? { condition: inner.condition } : {}),\n content: [],\n };\n branches.push(currentBranch);\n } else {\n // Nested elif/else\n const tagText = inner.tagType === 'else'\n ? '{% else %}'\n : `{% ${inner.tagType} ${inner.condition ?? ''} %}`.trim();\n currentBranch.content.push({ type: 'text', value: tagText });\n }\n } else {\n currentBranch.content.push(inner.node);\n }\n i++;\n }\n\n if (matched) {\n output.push({ type: 'jinjaIfInlineMdast', branches });\n } else {\n // Unmatched — restore as text\n output.push({ type: 'text', value: `{% if ${branches[0].condition ?? ''} %}`.trim() });\n for (const branch of branches) {\n if (branch !== branches[0]) {\n const tagText = branch.branchType === 'else'\n ? '{% else %}'\n : `{% ${branch.branchType} ${branch.condition ?? ''} %}`.trim();\n output.push({ type: 'text', value: tagText });\n }\n output.push(...branch.content);\n }\n }\n } else {\n // Stray elif/else/endif — keep as text\n const p = part as { tagType: string; condition?: string };\n const tagText = p.tagType === 'else'\n ? '{% else %}'\n : p.tagType === 'endif'\n ? '{% endif %}'\n : `{% ${p.tagType} ${p.condition ?? ''} %}`.trim();\n output.push({ type: 'text', value: tagText });\n i++;\n }\n }\n\n return output;\n}\n\n/**\n * Main transform: apply all three passes to an mdast tree.\n */\nexport function jinjaBlockTransform(tree: { type: string; children?: unknown[] }): void {\n // Pass 1: Extract Jinja tags from list item text\n pass1ExtractFromLists(tree, 0);\n expandMarkedLists(tree, 0);\n\n // Pass 2: Group block-level Jinja structures\n pass2GroupBlocks(tree, 0);\n\n // Pass 3: Structure inline Jinja\n pass3InlineJinja(tree, 0);\n}\n","import { parseMarkdown } from './parser';\nimport { serializeToMarkdown } from './serializer';\nimport type { AstNode, BlockNode, InlineNode, DocumentNode } from '../ast/types';\n\n/**\n * Serialize a list of AST nodes to markdown string (for clipboard).\n */\nexport function serializeFragment(nodes: AstNode[]): string {\n if (nodes.length === 0) return '';\n\n // Wrap in a doc for serialization\n const blocks: BlockNode[] = nodes.map((node) => {\n if (node.type === 'text' || node.type === 'resourceTag' || node.type === 'jumpPoint' || node.type === 'hardBreak') {\n return { type: 'paragraph', content: [node] };\n }\n if (node.type === 'doc') {\n // Flatten doc children\n return node.content;\n }\n return node as BlockNode;\n }).flat() as BlockNode[];\n\n const wrapper: DocumentNode = { type: 'doc', content: blocks };\n return serializeToMarkdown(wrapper);\n}\n\n/**\n * Parse a markdown string into a fragment (for clipboard paste).\n * Returns block nodes by default; if the markdown is a single paragraph,\n * returns its inline children.\n */\nexport function parseFragment(markdown: string): InlineNode[] | BlockNode[] {\n const doc = parseMarkdown(markdown);\n\n // If single paragraph, return inline content\n if (doc.content.length === 1 && doc.content[0].type === 'paragraph') {\n return doc.content[0].content as InlineNode[];\n }\n\n return doc.content as BlockNode[];\n}\n","/**\n * Pure text-based Jinja block scanner (no ProseMirror dependency).\n */\nimport type { JinjaBlock } from './types';\n\nconst JINJA_PATTERN = /\\{%\\s*(if|elif|else|endif)\\s*([^%]*?)\\s*%\\}/g;\n\n/**\n * Scan all Jinja blocks from plain text.\n *\n * @param text - Plain text content\n * @returns All Jinja blocks sorted by position\n */\nexport function scanJinjaBlocks(text: string): JinjaBlock[] {\n const blocks: JinjaBlock[] = [];\n\n JINJA_PATTERN.lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = JINJA_PATTERN.exec(text)) !== null) {\n const type = match[1] as JinjaBlock['type'];\n const conditionRaw = match[2].trim();\n const condition = type === 'if' || type === 'elif' ? conditionRaw : undefined;\n\n // Include trailing spaces after tag\n let endIndex = match.index + match[0].length;\n while (endIndex < text.length && text[endIndex] === ' ') {\n endIndex++;\n }\n\n blocks.push({\n type,\n condition,\n startIndex: match.index,\n endIndex,\n raw: match[0],\n });\n }\n\n return blocks.sort((a, b) => a.startIndex - b.startIndex);\n}\n","import type { JinjaBlock, JinjaIfStructure } from './types';\n\nfunction buildStructure(\n partial: { ifBlock: JinjaBlock; elifBlocks: JinjaBlock[]; elseBlock?: JinjaBlock },\n endifBlock: JinjaBlock,\n): JinjaIfStructure {\n const { ifBlock, elifBlocks, elseBlock } = partial;\n const contentRanges: JinjaIfStructure['contentRanges'] = [];\n\n // if branch content\n const ifContentEnd = elifBlocks[0]?.startIndex ?? elseBlock?.startIndex ?? endifBlock.startIndex;\n contentRanges.push({\n type: 'if',\n condition: ifBlock.condition!,\n startIndex: ifBlock.endIndex,\n endIndex: ifContentEnd,\n });\n\n // elif branches\n elifBlocks.forEach((elifBlock, idx) => {\n const nextBlock = elifBlocks[idx + 1] ?? elseBlock ?? endifBlock;\n contentRanges.push({\n type: 'elif',\n condition: elifBlock.condition!,\n startIndex: elifBlock.endIndex,\n endIndex: nextBlock.startIndex,\n });\n });\n\n // else branch\n if (elseBlock) {\n contentRanges.push({\n type: 'else',\n startIndex: elseBlock.endIndex,\n endIndex: endifBlock.startIndex,\n });\n }\n\n return {\n id: `jinja-${ifBlock.startIndex}-${endifBlock.endIndex}`,\n ifBlock,\n elifBlocks,\n elseBlock,\n endifBlock,\n contentRanges,\n };\n}\n\n/**\n * Structure scanned blocks into if~endif structures using stack-based approach.\n */\nexport function structureJinjaBlocks(blocks: JinjaBlock[]): JinjaIfStructure[] {\n const structures: JinjaIfStructure[] = [];\n const stack: Array<{\n ifBlock: JinjaBlock;\n elifBlocks: JinjaBlock[];\n elseBlock?: JinjaBlock;\n }> = [];\n\n for (const block of blocks) {\n switch (block.type) {\n case 'if':\n stack.push({ ifBlock: block, elifBlocks: [] });\n break;\n case 'elif':\n if (stack.length > 0) {\n stack[stack.length - 1].elifBlocks.push(block);\n }\n break;\n case 'else':\n if (stack.length > 0) {\n stack[stack.length - 1].elseBlock = block;\n }\n break;\n case 'endif': {\n const current = stack.pop();\n if (current) {\n structures.push(buildStructure(current, block));\n }\n break;\n }\n }\n }\n\n return structures;\n}\n","import type { DocumentNode } from '../ast/types';\nimport { textContent } from '../ast/traverse';\nimport { scanJinjaBlocks } from './scanner';\nimport { structureJinjaBlocks } from './structurer';\n\nexport interface JinjaVisualBranch {\n type: 'if' | 'elif' | 'else';\n condition?: string;\n blockStartIndex: number;\n blockEndIndex: number;\n tagBlockIndex: number;\n}\n\nexport interface JinjaVisualStructure {\n id: string;\n branches: JinjaVisualBranch[];\n ifTagBlockIndex: number;\n endifTagBlockIndex: number;\n}\n\n/**\n * Single pass: builds cumulative block-end offsets AND the full document text.\n * offsets[i] = exclusive end char index of block i.\n * Avoids calling textContent() twice (once for offsets, once for fullText).\n */\nfunction buildOffsetsAndText(doc: DocumentNode): { offsets: number[]; fullText: string } {\n const offsets: number[] = [];\n const parts: string[] = [];\n let cursor = 0;\n for (const block of doc.content) {\n const t = textContent(block);\n parts.push(t);\n cursor += t.length;\n offsets.push(cursor);\n }\n return { offsets, fullText: parts.join('') };\n}\n\n/**\n * Binary search: returns the block index that contains charIndex.\n * offsets[i] is the exclusive end of block i.\n */\nfunction charIndexToBlockIndex(offsets: number[], charIndex: number): number {\n if (offsets.length === 0) return 0;\n let lo = 0;\n let hi = offsets.length - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (offsets[mid] <= charIndex) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\n/**\n * Analyze a DocumentNode for Jinja if/elif/else/endif structures\n * and map them to block-level indices.\n */\nexport function analyzeJinjaBlocks(doc: DocumentNode): JinjaVisualStructure[] {\n if (doc.content.length === 0) return [];\n\n const { offsets, fullText } = buildOffsetsAndText(doc);\n\n const scanned = scanJinjaBlocks(fullText);\n if (scanned.length === 0) return [];\n\n const structures = structureJinjaBlocks(scanned);\n\n return structures.map((structure) => {\n const ifTagBlockIdx = charIndexToBlockIndex(offsets, structure.ifBlock.startIndex);\n const endifTagBlockIdx = charIndexToBlockIndex(offsets, structure.endifBlock.startIndex);\n\n const branches: JinjaVisualBranch[] = structure.contentRanges.map((range) => {\n // Find the tag block index for this branch\n let tagCharIndex: number;\n if (range.type === 'if') {\n tagCharIndex = structure.ifBlock.startIndex;\n } else if (range.type === 'elif') {\n const elifBlock = structure.elifBlocks.find((b) => b.condition === range.condition);\n tagCharIndex = elifBlock ? elifBlock.startIndex : range.startIndex;\n } else {\n tagCharIndex = structure.elseBlock!.startIndex;\n }\n\n const tagBlockIdx = charIndexToBlockIndex(offsets, tagCharIndex);\n\n // Content block range: from the block containing the content start\n // to the block containing the content end (exclusive)\n let contentStartBlock: number;\n let contentEndBlock: number;\n\n if (range.startIndex >= range.endIndex) {\n // Empty content range\n contentStartBlock = tagBlockIdx;\n contentEndBlock = tagBlockIdx;\n } else {\n contentStartBlock = charIndexToBlockIndex(offsets, range.startIndex);\n // If the content starts in the same block as the tag, the actual content blocks start after\n // But we keep the start as-is since the tag and content may share a block\n const lastContentChar = range.endIndex - 1;\n contentEndBlock = charIndexToBlockIndex(offsets, lastContentChar) + 1;\n }\n\n return {\n type: range.type,\n condition: range.condition,\n blockStartIndex: contentStartBlock,\n blockEndIndex: contentEndBlock,\n tagBlockIndex: tagBlockIdx,\n };\n });\n\n return {\n id: structure.id,\n branches,\n ifTagBlockIndex: ifTagBlockIdx,\n endifTagBlockIndex: endifTagBlockIdx,\n };\n });\n}\n","/**\n * Jump-point adjacent decoration + edit plugins.\n *\n * Adjacent plugin: marks jumpPoint nodes near the cursor with a decoration\n * so the NodeView can show `^id^` raw syntax when the cursor is beside them.\n *\n * Edit plugin: tracks a \"raw range\" after ArrowLeft explodes a jumpPoint atom\n * to `^aa^` text. When the cursor moves outside that range the plugin\n * auto-reconverts the text back to a jumpPoint node (if it still matches\n * `^validId^` and the id has no duplicates elsewhere in the doc).\n *\n * Keymap:\n * Backspace — explode atom to `^aa` (closing `^` consumed), cursor at end\n * ArrowLeft — explode atom to `^aa^`, cursor before closing `^`\n */\nimport { Plugin, PluginKey, TextSelection } from 'prosemirror-state';\nimport type { EditorState, Transaction } from 'prosemirror-state';\nimport { Decoration, DecorationSet } from 'prosemirror-view';\nimport type { ActionbookPlugin } from './types';\n\n// ── Adjacent decoration plugin ────────────────────────────\n\nconst adjacentKey = new PluginKey<DecorationSet>('jumpPointAdjacent');\n\n/** Decoration spec set on a jumpPoint node when the cursor is adjacent. */\nexport const JUMP_POINT_ADJACENT_SPEC = { jumpPointAdjacent: true } as const;\n\nfunction buildDecorations(state: EditorState): DecorationSet {\n const { selection } = state;\n if (!selection.empty) return DecorationSet.empty;\n\n const cursorPos = selection.$from.pos;\n const decorations: Decoration[] = [];\n\n state.doc.descendants((node, pos) => {\n if (node.type.name !== 'jumpPoint') return;\n const nodeEnd = pos + node.nodeSize;\n if (cursorPos === pos || cursorPos === nodeEnd) {\n decorations.push(Decoration.node(pos, nodeEnd, {}, JUMP_POINT_ADJACENT_SPEC));\n }\n });\n\n return DecorationSet.create(state.doc, decorations);\n}\n\n// ── Edit plugin (raw-range tracking + auto-reconvert) ─────\n\ninterface JumpPointEditState {\n rawRange: { from: number; to: number } | null;\n}\n\nexport const jumpPointEditKey = new PluginKey<JumpPointEditState>('jumpPointEdit');\n\n/** Matches the full `^validId^` pattern (letters / underscores only). */\nconst JUMP_POINT_FULL_RE = /^\\^([A-Za-z_][A-Za-z0-9_]*)\\^$/;\n\nfunction createJumpPointEditPlugin(): Plugin<JumpPointEditState> {\n return new Plugin<JumpPointEditState>({\n key: jumpPointEditKey,\n\n state: {\n init: (): JumpPointEditState => ({ rawRange: null }),\n\n apply(tr, prev): JumpPointEditState {\n const meta = tr.getMeta(jumpPointEditKey) as\n | { from: number; to: number }\n | null\n | undefined;\n\n if (meta !== undefined) return { rawRange: meta };\n\n if (prev.rawRange) {\n // Use assoc=-1 for `from` so it stays at the range start when text\n // is inserted/replaced from that position (forward assoc would push\n // it to from+addLen, collapsing the range).\n const from = tr.mapping.map(prev.rawRange.from, -1);\n const to = tr.mapping.map(prev.rawRange.to, 1);\n if (from >= to) return { rawRange: null };\n return { rawRange: { from, to } };\n }\n\n return prev;\n },\n },\n\n appendTransaction(_, __, newState) {\n const pluginState = jumpPointEditKey.getState(newState);\n if (!pluginState?.rawRange) return null;\n\n const { from, to } = pluginState.rawRange;\n const cursor = newState.selection.anchor;\n\n // Still inside the raw region — nothing to do.\n // Use strict `< to` so cursor AT the end of `^aa^` is already \"outside\",\n // meaning a single ArrowRight press from `^aa|^` triggers reconversion.\n if (cursor >= from && cursor < to) return null;\n\n const docSize = newState.doc.content.size;\n const safeFrom = Math.min(from, docSize);\n const safeTo = Math.min(to, docSize);\n\n const reconvertTr = newState.tr;\n reconvertTr.setMeta(jumpPointEditKey, null); // always clear tracking\n\n if (safeFrom < safeTo) {\n const text = newState.doc.textBetween(safeFrom, safeTo);\n const match = JUMP_POINT_FULL_RE.exec(text);\n\n if (match) {\n const [, id] = match;\n const jumpPointType = newState.schema.nodes.jumpPoint;\n\n if (jumpPointType) {\n // Reject duplicate IDs that exist outside the current raw range\n let duplicate = false;\n newState.doc.descendants((node, pos) => {\n if (node.type === jumpPointType && node.attrs.id === id) {\n if (pos < safeFrom || pos >= safeTo) duplicate = true;\n }\n });\n\n if (!duplicate) {\n reconvertTr.replaceWith(safeFrom, safeTo, jumpPointType.create({ id }));\n }\n }\n }\n }\n\n return reconvertTr;\n },\n });\n}\n\n// ── Shared helpers ────────────────────────────────────────\n\n/** Find the jumpPoint atom immediately before the cursor. */\nfunction jumpPointBefore(\n state: EditorState,\n): { id: string; nodeStart: number; nodeEnd: number } | null {\n const { selection } = state;\n if (!selection.empty) return null;\n const { $from } = selection;\n const nodeBefore = $from.nodeBefore;\n if (!nodeBefore || nodeBefore.type.name !== 'jumpPoint') return null;\n const nodeEnd = $from.pos;\n const nodeStart = nodeEnd - nodeBefore.nodeSize;\n return { id: nodeBefore.attrs.id as string, nodeStart, nodeEnd };\n}\n\n/**\n * Backspace on a jumpPoint atom → explode to `^aa` (no closing `^`).\n * Cursor lands at end: `^aa|`\n */\nfunction explodeOnBackspace(state: EditorState): Transaction | null {\n const info = jumpPointBefore(state);\n if (!info) return null;\n const { id, nodeStart, nodeEnd } = info;\n const rawText = `^${id}`;\n const tr = state.tr.replaceWith(nodeStart, nodeEnd, state.schema.text(rawText));\n const cursorPos = Math.min(nodeStart + rawText.length, tr.doc.content.size);\n tr.setSelection(TextSelection.near(tr.doc.resolve(cursorPos)));\n return tr;\n}\n\n/**\n * ArrowLeft on a jumpPoint atom → explode to `^aa^`, cursor before closing `^`.\n * Sets jumpPointEditKey meta so auto-reconvert kicks in when cursor leaves.\n * Result: `^aa|^`\n */\nfunction explodeOnArrowLeft(state: EditorState): Transaction | null {\n const info = jumpPointBefore(state);\n if (!info) return null;\n const { id, nodeStart, nodeEnd } = info;\n const rawText = `^${id}^`;\n const tr = state.tr.replaceWith(nodeStart, nodeEnd, state.schema.text(rawText));\n // cursor before closing `^`\n const cursorPos = Math.min(nodeStart + 1 + id.length, tr.doc.content.size);\n tr.setSelection(TextSelection.near(tr.doc.resolve(cursorPos)));\n // Track range so appendTransaction can reconvert on cursor-leave\n tr.setMeta(jumpPointEditKey, { from: nodeStart, to: nodeStart + rawText.length });\n return tr;\n}\n\n// ── Public factory ────────────────────────────────────────\n\nexport function createJumpPointAdjacentPlugin(): ActionbookPlugin {\n return {\n name: 'jumpPointAdjacent',\n keymap: () => ({\n Backspace: (state, dispatch) => {\n const tr = explodeOnBackspace(state);\n if (!tr) return false;\n if (dispatch) dispatch(tr);\n return true;\n },\n ArrowLeft: (state, dispatch) => {\n const tr = explodeOnArrowLeft(state);\n if (!tr) return false;\n if (dispatch) dispatch(tr);\n return true;\n },\n }),\n plugins: () => [\n createJumpPointEditPlugin(),\n new Plugin({\n key: adjacentKey,\n state: {\n init(_, state) {\n return buildDecorations(state);\n },\n apply(tr, old, _oldState, newState) {\n if (tr.selectionSet || tr.docChanged) {\n return buildDecorations(newState);\n }\n return old.map(tr.mapping, tr.doc);\n },\n },\n props: {\n decorations(state) {\n return adjacentKey.getState(state);\n },\n },\n }),\n ],\n };\n}\n","/**\n * React NodeView plugin for the `jumpPoint` node.\n *\n * Normal state: styled badge (anchor icon + id, yellow background) — matches ActionbookRenderer.\n * Adjacent state: shows `^id^` raw syntax when cursor is immediately before or after the node.\n *\n * Adjacency is communicated via node decorations from `createJumpPointAdjacentPlugin()`.\n */\nimport React from 'react';\nimport { createReactNodeView } from '../nodeView/ReactNodeView';\nimport type { ReactNodeViewProps } from '../nodeView/ReactNodeView';\nimport type { ActionbookPlugin } from './types';\nimport { IconAnchor } from '../components/icons';\n\nconst JUMP_POINT_STYLE: React.CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n backgroundColor: '#FFF2B6',\n border: '1px solid #FFC233',\n color: '#AA5D04',\n borderRadius: '4px',\n padding: '0 0.3em',\n fontSize: '0.85em',\n lineHeight: 1.6,\n userSelect: 'none',\n cursor: 'default',\n boxSizing: 'border-box',\n};\n\nconst JUMP_POINT_ADJACENT_STYLE: React.CSSProperties = {\n ...JUMP_POINT_STYLE,\n backgroundColor: '#FFE680',\n borderColor: '#FF9500',\n};\n\nfunction JumpPointNodeViewComponent({ node, decorations }: ReactNodeViewProps) {\n const id = node.attrs.id as string;\n const isAdjacent = decorations?.some((d) => (d as any).spec?.jumpPointAdjacent === true) ?? false;\n\n if (isAdjacent) {\n return (\n <span style={JUMP_POINT_ADJACENT_STYLE} id={`jp-${id}`}>\n <IconAnchor size={12} fill=\"#AA5D04\" style={{ marginRight: 'max(0.15em, 2px)', flexShrink: 0 }} />\n {`^${id}^`}\n </span>\n );\n }\n\n return (\n <span style={JUMP_POINT_STYLE} id={`jp-${id}`}>\n <IconAnchor size={12} fill=\"#AA5D04\" style={{ marginRight: 'max(0.15em, 2px)', flexShrink: 0 }} />\n {id}\n </span>\n );\n}\n\nexport function createJumpPointNodeViewPlugin(): ActionbookPlugin {\n return {\n name: 'jumpPointNodeView',\n nodeViews: () => ({\n jumpPoint: createReactNodeView({ component: JumpPointNodeViewComponent, inline: true }),\n }),\n };\n}\n","/**\n * Jump point validation plugin — highlights duplicate jump point IDs\n * and broken anchor references in the editor.\n */\nimport { Plugin, PluginKey } from 'prosemirror-state';\nimport { Decoration, DecorationSet } from 'prosemirror-view';\nimport type { Node as PMNode } from 'prosemirror-model';\nimport type { ActionbookPlugin } from './types';\n\nconst validationKey = new PluginKey('jumpPointValidation');\n\nfunction buildValidationDecorations(doc: PMNode): DecorationSet {\n const jumpPointIds = new Map<string, number[]>();\n const anchorRefs: { from: number; to: number; id: string }[] = [];\n\n doc.descendants((node, pos) => {\n if (node.type.name === 'jumpPoint') {\n const id = node.attrs.id as string;\n if (!jumpPointIds.has(id)) jumpPointIds.set(id, []);\n jumpPointIds.get(id)!.push(pos);\n }\n // Check for link marks pointing to #id anchors\n if (node.isText && node.marks) {\n for (const mark of node.marks) {\n if (mark.type.name === 'link') {\n const href = mark.attrs.href as string;\n if (href?.startsWith('#')) {\n anchorRefs.push({ from: pos, to: pos + node.nodeSize, id: href.slice(1) });\n }\n }\n }\n }\n });\n\n const decorations: Decoration[] = [];\n\n // Highlight duplicate jump point IDs\n for (const [, positions] of jumpPointIds) {\n if (positions.length > 1) {\n for (const pos of positions) {\n decorations.push(\n Decoration.node(pos, pos + 1, { class: 'duplicate-jump-point' }),\n );\n }\n }\n }\n\n // Highlight broken anchor references (links to non-existent jump points)\n for (const ref of anchorRefs) {\n if (!jumpPointIds.has(ref.id)) {\n decorations.push(\n Decoration.inline(ref.from, ref.to, { class: 'broken-anchor-ref' }),\n );\n }\n }\n\n return decorations.length > 0 ? DecorationSet.create(doc, decorations) : DecorationSet.empty;\n}\n\nexport function createJumpPointValidationPlugin(): ActionbookPlugin {\n return {\n name: 'jumpPointValidation',\n plugins: () => [\n new Plugin({\n key: validationKey,\n state: {\n init(_, state) {\n return buildValidationDecorations(state.doc);\n },\n apply(tr, oldDecos) {\n if (!tr.docChanged) return oldDecos;\n return buildValidationDecorations(tr.doc);\n },\n },\n props: {\n decorations(state) {\n return validationKey.getState(state) as DecorationSet;\n },\n },\n }),\n ],\n };\n}\n\n/**\n * Check if doc has duplicate jump point IDs.\n */\nexport function hasDuplicateJumpPoints(state: import('prosemirror-state').EditorState): boolean {\n const ids = new Set<string>();\n let hasDup = false;\n state.doc.descendants((node) => {\n if (node.type.name === 'jumpPoint') {\n const id = node.attrs.id as string;\n if (ids.has(id)) { hasDup = true; return false; }\n ids.add(id);\n }\n });\n return hasDup;\n}\n\n/**\n * Check if doc has broken anchor references.\n */\nexport function hasBrokenAnchorRefs(state: import('prosemirror-state').EditorState): boolean {\n const jumpPointIds = new Set<string>();\n state.doc.descendants((node) => {\n if (node.type.name === 'jumpPoint') {\n jumpPointIds.add(node.attrs.id as string);\n }\n });\n\n let hasBroken = false;\n state.doc.descendants((node) => {\n if (hasBroken) return false;\n if (node.isText && node.marks) {\n for (const mark of node.marks) {\n if (mark.type.name === 'link') {\n const href = mark.attrs.href as string;\n if (href?.startsWith('#') && !jumpPointIds.has(href.slice(1))) {\n hasBroken = true;\n return false;\n }\n }\n }\n }\n });\n return hasBroken;\n}\n","/**\n * React NodeView plugin for the `inlineToolTag` node.\n *\n * Renders a styled badge matching ActionbookRenderer's resourceTag output:\n * colored icon block + colored text label with border.\n */\nimport React from 'react';\nimport { createReactNodeView } from '../nodeView/ReactNodeView';\nimport type { ReactNodeViewProps } from '../nodeView/ReactNodeView';\nimport type { ActionbookPlugin } from './types';\nimport {\n IconTool,\n IconManual,\n IconMessageTemplate,\n IconHandoff,\n IconTimeDiff,\n} from '../components/icons';\n\nconst RESOURCE_TAG_COLORS: Record<string, string> = {\n tool: '#027D69',\n manual: '#5959D3',\n agent_message_template: '#8012B3',\n handoff: '#D25309',\n time_diff: '#FB6B6B',\n};\nconst DEFAULT_COLOR = '#027D69';\n\ntype IconComponent = React.ComponentType<{ size?: number; fill?: string; style?: React.CSSProperties }>;\n\nconst RESOURCE_TAG_ICONS: Record<string, IconComponent> = {\n tool: IconTool,\n manual: IconManual,\n agent_message_template: IconMessageTemplate,\n handoff: IconHandoff,\n time_diff: IconTimeDiff,\n};\nconst DEFAULT_ICON = IconTool;\n\nconst OUTER_STYLE: React.CSSProperties = {\n display: 'inline-flex',\n padding: '1px',\n border: '1px solid #CCCCCC',\n borderRadius: '2px',\n alignItems: 'center',\n backgroundColor: 'white',\n userSelect: 'none',\n cursor: 'default',\n boxSizing: 'border-box',\n};\n\nconst ICON_BLOCK_BASE: React.CSSProperties = {\n display: 'inline-flex',\n justifyContent: 'center',\n alignItems: 'center',\n width: '16px',\n height: '16px',\n borderRadius: '2px',\n flexShrink: 0,\n};\n\nconst LABEL_BASE: React.CSSProperties = {\n padding: '0 4px',\n fontSize: '11px',\n lineHeight: 1,\n userSelect: 'none',\n};\n\nfunction InlineToolTagNodeViewComponent({ node }: ReactNodeViewProps) {\n const type = node.attrs.type as string;\n const text = node.attrs.text as string;\n const color = RESOURCE_TAG_COLORS[type] ?? DEFAULT_COLOR;\n const Icon = RESOURCE_TAG_ICONS[type] ?? DEFAULT_ICON;\n\n return (\n <span style={OUTER_STYLE} data-type={type} data-resource-id={node.attrs.resourceId as string}>\n <span style={{ ...ICON_BLOCK_BASE, backgroundColor: color }}>\n <Icon size={9} fill=\"white\" />\n </span>\n <span style={{ ...LABEL_BASE, color }}>{text}</span>\n </span>\n );\n}\n\nexport function createInlineToolTagNodeViewPlugin(): ActionbookPlugin {\n return {\n name: 'inlineToolTagNodeView',\n nodeViews: () => ({\n inlineToolTag: createReactNodeView({ component: InlineToolTagNodeViewComponent, inline: true }),\n }),\n };\n}\n","import { Plugin, PluginKey } from 'prosemirror-state';\nimport { Decoration, DecorationSet } from 'prosemirror-view';\nimport type { Node as PMNode } from 'prosemirror-model';\nimport { fromProseMirrorJSON, type JSONContent } from '../../compat/prosemirror';\nimport { analyzeJinjaBlocks } from '../../jinja/analyzer';\nimport type { ActionbookPlugin } from './types';\n\nconst jinjaPluginKey = new PluginKey('jinjaDecoration');\n\nconst JINJA_TAG_RE = /\\{%\\s*(if|elif|else|endif)\\s*([^%]*?)\\s*%\\}/g;\n\ninterface BlockPosInfo {\n index: number;\n from: number;\n to: number;\n}\n\nfunction getBlockPositions(doc: PMNode): BlockPosInfo[] {\n const blocks: BlockPosInfo[] = [];\n let index = 0;\n doc.forEach((node, offset) => {\n blocks.push({ index, from: offset, to: offset + node.nodeSize });\n index++;\n });\n return blocks;\n}\n\nfunction addInlineChipDecorations(doc: PMNode, decorations: Decoration[]) {\n doc.descendants((node, pos) => {\n if (!node.isText) return;\n const text = node.text!;\n JINJA_TAG_RE.lastIndex = 0;\n let match;\n while ((match = JINJA_TAG_RE.exec(text)) !== null) {\n const from = pos + match.index;\n const to = from + match[0].length;\n const keyword = match[1]; // if | elif | else | endif\n decorations.push(\n Decoration.inline(from, to, {\n class: `jinja-chip jinja-chip-${keyword}`,\n }),\n );\n }\n });\n}\n\nfunction addStructureBorderDecorations(\n doc: PMNode,\n blocks: BlockPosInfo[],\n decorations: Decoration[],\n) {\n const json = doc.toJSON() as JSONContent;\n let ast;\n try {\n ast = fromProseMirrorJSON(json);\n } catch {\n return;\n }\n\n const structures = analyzeJinjaBlocks(ast);\n\n for (const structure of structures) {\n // Build a map: blockIndex → branch type for every block in this structure\n // Tag lines (if/elif/else/endif) get the type of the branch they start\n // Content blocks get the type of their enclosing branch\n const blockBranchType = new Map<number, 'if' | 'elif' | 'else'>();\n\n for (const branch of structure.branches) {\n // The tag line itself\n blockBranchType.set(branch.tagBlockIndex, branch.type);\n // Content blocks under this branch\n for (let i = branch.blockStartIndex; i < branch.blockEndIndex; i++) {\n // Don't overwrite tag lines of subsequent branches\n if (!blockBranchType.has(i)) {\n blockBranchType.set(i, branch.type);\n }\n }\n }\n // endif tag line: use the last branch's type\n const lastBranch = structure.branches[structure.branches.length - 1];\n if (lastBranch && !blockBranchType.has(structure.endifTagBlockIndex)) {\n blockBranchType.set(structure.endifTagBlockIndex, lastBranch.type);\n }\n\n // Now emit decorations per contiguous run of same branch type\n const first = structure.ifTagBlockIndex;\n const last = structure.endifTagBlockIndex;\n\n for (let i = first; i <= last; i++) {\n const block = blocks[i];\n if (!block) continue;\n\n const branchType = blockBranchType.get(i) || 'if';\n const prevType = i > first ? blockBranchType.get(i - 1) : undefined;\n const nextType = i < last ? blockBranchType.get(i + 1) : undefined;\n\n const classes = ['jinja-bar', `jinja-bar-${branchType}`];\n // Segment boundaries: start/end of a contiguous same-color run\n if (i === first || prevType !== branchType) classes.push('jinja-bar-first');\n if (i === last || nextType !== branchType) classes.push('jinja-bar-last');\n\n decorations.push(Decoration.node(block.from, block.to, { class: classes.join(' ') }));\n }\n }\n}\n\nfunction buildDecorations(doc: PMNode): DecorationSet {\n const blocks = getBlockPositions(doc);\n const decorations: Decoration[] = [];\n\n addInlineChipDecorations(doc, decorations);\n addStructureBorderDecorations(doc, blocks, decorations);\n\n if (decorations.length === 0) return DecorationSet.empty;\n return DecorationSet.create(doc, decorations);\n}\n\nexport function createJinjaDecorationPlugin(): ActionbookPlugin {\n return {\n name: 'jinjaDecoration',\n plugins: () => [\n new Plugin({\n key: jinjaPluginKey,\n state: {\n init(_, state) {\n return buildDecorations(state.doc);\n },\n apply(tr, oldDecos) {\n if (!tr.docChanged) return oldDecos;\n return buildDecorations(tr.doc);\n },\n },\n props: {\n decorations(state) {\n return jinjaPluginKey.getState(state) as DecorationSet;\n },\n },\n }),\n ],\n };\n}\n","import { useEffect, useRef, useState } from 'react';\nimport { createRoot, type Root } from 'react-dom/client';\nimport type { Node as PMNode, Schema } from 'prosemirror-model';\nimport type { EditorView, NodeView, ViewMutationRecord } from 'prosemirror-view';\nimport { tokenizeCondition } from '../../jinja/conditionHighlighter';\nimport type { ActionbookPlugin, NodeViewFactory } from './types';\n\ntype BranchType = 'if' | 'elif' | 'else';\n\ninterface BranchContext {\n readonly blockNode: PMNode;\n readonly blockPos: number;\n readonly branchNode: PMNode;\n readonly branchPos: number;\n readonly branchIndex: number;\n}\n\ninterface PopupMenuItem {\n readonly label: string;\n readonly disabled?: boolean;\n readonly onSelect: () => void;\n}\n\ninterface MenuPosition {\n readonly top: number;\n readonly left?: number;\n readonly right?: number;\n}\n\ninterface JinjaBranchHeaderProps {\n readonly branchType: BranchType;\n readonly condition: string;\n readonly editable?: boolean;\n readonly onConditionChange: (value: string) => void;\n readonly onDelete: () => void;\n readonly onAddBranch: (branchType: Exclude<BranchType, 'if'>) => void;\n readonly isLastBranch: boolean;\n readonly hasElseBranch: boolean;\n}\n\ninterface ConditionDisplayProps {\n readonly branchType: BranchType;\n readonly condition: string;\n readonly editable?: boolean;\n readonly onConditionChange: (value: string) => void;\n}\n\ninterface BranchPopupMenuProps {\n readonly items: readonly PopupMenuItem[];\n readonly position: MenuPosition;\n}\n\nconst PLACEHOLDER_TEXT = 'Describe what AI agent should do when this condition is met';\nconst CONDITION_PLACEHOLDER = 'Write a condition in natural language';\nconst STYLE_ID = 'ab-jinja-if-block-styles';\n\nconst JINJA_STYLES = `\n.jinja-if-block {\n margin: 8px 0;\n}\n\n.jinja-branch {\n position: relative;\n display: grid;\n grid-template-areas:\n \"header\"\n \"body\"\n \"footer\";\n gap: 0;\n}\n\n.jinja-branch-controls {\n display: contents;\n}\n\n.jinja-branch-header {\n grid-area: header;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 8px;\n border: 1px solid #E0E0E0;\n border-radius: 4px;\n background: #FFFFFF;\n}\n\n.jinja-branch-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 32px;\n padding: 0 8px;\n border-radius: 4px;\n font-family: \"Roboto Mono\", monospace;\n font-size: 13px;\n font-weight: 700;\n line-height: 20px;\n letter-spacing: -0.3px;\n white-space: nowrap;\n flex-shrink: 0;\n}\n\n.jinja-branch-badge-if,\n.jinja-branch-badge-elif {\n background: #E7F1FF;\n color: #0D0D0D;\n}\n\n.jinja-branch-badge-else {\n background: #F7F7F7;\n color: #424242;\n}\n\n.jinja-branch-condition {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n align-items: center;\n width: 100%;\n padding: 0;\n margin: 0;\n background: transparent;\n border: none;\n color: #0D0D0D;\n cursor: text;\n text-align: left;\n font-family: \"Roboto Mono\", monospace;\n font-size: 13px;\n line-height: 20px;\n letter-spacing: -0.3px;\n white-space: nowrap;\n}\n\n.jinja-branch-condition:focus-visible,\n.jinja-ghost-btn:focus-visible,\n.jinja-popup-item:focus-visible {\n outline: 2px solid rgba(98, 16, 204, 0.28);\n outline-offset: 2px;\n}\n\n.jinja-condition-placeholder {\n color: #A6A6A6;\n font-family: \"Roboto Mono\", monospace;\n font-size: 13px;\n line-height: 20px;\n letter-spacing: -0.3px;\n}\n\n.jinja-token-variable {\n color: #4141B2;\n}\n\n.jinja-token-operator {\n color: #858585;\n}\n\n.jinja-token-value {\n color: #0D0D0D;\n}\n\n.jinja-token-punctuation {\n color: #858585;\n}\n\n.jinja-otherwise {\n flex: 1;\n color: #858585;\n font-family: \"Roboto Mono\", monospace;\n font-size: 13px;\n line-height: 20px;\n letter-spacing: -0.3px;\n}\n\n.jinja-branch-actions,\n.jinja-add-footer-actions {\n position: relative;\n display: inline-flex;\n align-items: center;\n}\n\n.jinja-branch-body {\n grid-area: body;\n display: flex;\n gap: 12px;\n padding: 0 8px;\n min-height: 52px;\n}\n\n.jinja-branch-divider-col {\n width: 32px;\n flex-shrink: 0;\n display: flex;\n align-items: stretch;\n justify-content: center;\n}\n\n.jinja-branch-divider {\n width: 1px;\n background: #E0E0E0;\n}\n\n/* L-shaped divider for the last branch (ELSE) */\n.jinja-branch-last .jinja-branch-divider-col {\n align-items: flex-start;\n padding-left: 16px;\n}\n\n.jinja-branch-last .jinja-branch-divider {\n width: 16px;\n height: 28px;\n background: none;\n border-left: 1px solid #E0E0E0;\n border-bottom: 1px solid #E0E0E0;\n border-bottom-left-radius: 8px;\n}\n\n.jinja-branch-content {\n position: relative;\n flex: 1;\n min-width: 0;\n padding: 16px 0;\n}\n\n.jinja-branch-content.jinja-branch-content-empty::before {\n content: attr(data-placeholder);\n position: absolute;\n top: 16px;\n left: 0;\n color: #A6A6A6;\n font-size: 14px;\n line-height: 20px;\n pointer-events: none;\n}\n\n.jinja-add-footer {\n grid-area: footer;\n display: flex;\n padding: 8px;\n}\n\n.jinja-add-footer .jinja-add-footer-col {\n width: 32px;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.jinja-ghost-btn {\n width: 24px;\n height: 24px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: #858585;\n cursor: pointer;\n}\n\n.jinja-ghost-btn:hover:not(:disabled) {\n background: rgba(13, 13, 13, 0.04);\n}\n\n.jinja-ghost-btn:disabled {\n opacity: 0.45;\n cursor: default;\n}\n\n.jinja-popup-menu {\n position: absolute;\n z-index: 20;\n min-width: 200px;\n padding: 8px 0;\n background: #FFFFFF;\n border-radius: 4px;\n box-shadow: 0px 8px 10px 0px rgba(13,13,13,0.12), 0px 3px 14px 0px rgba(13,13,13,0.08), 0px 3px 5px 0px rgba(13,13,13,0.04);\n}\n\n.jinja-popup-item {\n width: 100%;\n display: block;\n padding: 6px 16px;\n border: none;\n background: transparent;\n color: #0D0D0D;\n text-align: left;\n cursor: pointer;\n font-size: 14px;\n line-height: 20px;\n letter-spacing: -0.1px;\n}\n\n.jinja-popup-item:hover:not(:disabled) {\n background: rgba(13, 13, 13, 0.04);\n}\n\n.jinja-popup-item:disabled {\n color: #A6A6A6;\n cursor: default;\n}\n\n.jinja-condition-input {\n width: 100%;\n min-width: 0;\n padding: 0;\n margin: 0;\n border: none;\n outline: none;\n background: transparent;\n color: #0D0D0D;\n caret-color: #6210CC;\n font-family: \"Roboto Mono\", monospace;\n font-size: 13px;\n line-height: 20px;\n letter-spacing: -0.3px;\n}\n\n.jinja-condition-input::placeholder {\n color: #A6A6A6;\n}\n`;\n\nclass StyleManager {\n private static refCount = 0;\n private static styleEl: HTMLStyleElement | null = null;\n\n static acquire(): void {\n if (this.refCount++ > 0) return;\n\n const existing = document.getElementById(STYLE_ID);\n if (existing instanceof HTMLStyleElement) {\n this.styleEl = existing;\n return;\n }\n\n this.styleEl = document.createElement('style');\n this.styleEl.id = STYLE_ID;\n this.styleEl.textContent = JINJA_STYLES;\n document.head.appendChild(this.styleEl);\n }\n\n static release(): void {\n if (this.refCount === 0) return;\n if (--this.refCount > 0) return;\n\n if (this.styleEl?.parentNode) {\n this.styleEl.remove();\n }\n this.styleEl = null;\n }\n}\n\nfunction getBranchContext(view: EditorView, nodePos: number): BranchContext | null {\n try {\n const { doc } = view.state;\n const resolved = doc.resolve(nodePos);\n let blockDepth = -1;\n\n for (let depth = resolved.depth; depth >= 0; depth--) {\n if (resolved.node(depth).type.name === 'jinjaIfBlock') {\n blockDepth = depth;\n break;\n }\n }\n\n if (blockDepth < 0) {\n return null;\n }\n\n const blockNode = resolved.node(blockDepth);\n const blockPos = blockDepth === 0 ? 0 : resolved.before(blockDepth);\n\n let branchOffset = blockPos + 1;\n for (let index = 0; index < blockNode.childCount; index++) {\n const branchNode = blockNode.child(index);\n if (branchOffset === nodePos) {\n return {\n blockNode,\n blockPos,\n branchNode,\n branchPos: branchOffset,\n branchIndex: index,\n };\n }\n branchOffset += branchNode.nodeSize;\n }\n } catch {\n return null;\n }\n\n return null;\n}\n\nfunction isBranchBodyEmpty(node: PMNode): boolean {\n if (node.childCount !== 1) return false;\n const firstChild = node.firstChild;\n return firstChild?.type.name === 'paragraph' && firstChild.content.size === 0;\n}\n\nfunction isBranchNode(node: PMNode | null | undefined): node is PMNode {\n return node?.type.name === 'jinjaIfBranch';\n}\n\nfunction createBranchNode(schema: Schema, branchType: Exclude<BranchType, 'if'>, condition: string): PMNode | null {\n const branchNodeType = schema.nodes.jinjaIfBranch;\n const paragraphNode = schema.nodes.paragraph?.createAndFill();\n\n if (!branchNodeType || !paragraphNode) {\n return null;\n }\n\n return branchNodeType.create(\n {\n branchType,\n condition: branchType === 'else' ? '' : condition,\n },\n paragraphNode,\n );\n}\n\nfunction getLastBranchOfBlock(view: EditorView, nodePos: number): { index: number; node: PMNode } | null {\n const context = getBranchContext(view, nodePos);\n if (!context || context.blockNode.childCount === 0) {\n return null;\n }\n\n const index = context.blockNode.childCount - 1;\n return {\n index,\n node: context.blockNode.child(index),\n };\n}\n\nfunction getLastNonElseBranchIndex(view: EditorView, nodePos: number): number {\n const context = getBranchContext(view, nodePos);\n if (!context) return -1;\n for (let i = context.blockNode.childCount - 1; i >= 0; i--) {\n if ((context.blockNode.child(i).attrs.branchType as BranchType) !== 'else') return i;\n }\n return -1;\n}\n\nfunction getElseBranch(view: EditorView, nodePos: number): boolean {\n const context = getBranchContext(view, nodePos);\n if (!context) return false;\n\n for (let index = 0; index < context.blockNode.childCount; index++) {\n if ((context.blockNode.child(index).attrs.branchType as BranchType) === 'else') {\n return true;\n }\n }\n\n return false;\n}\n\nfunction deleteBlock(view: EditorView, blockPos: number): boolean {\n const blockNode = view.state.doc.nodeAt(blockPos);\n if (blockNode?.type.name !== 'jinjaIfBlock') {\n return false;\n }\n\n view.dispatch(view.state.tr.delete(blockPos, blockPos + blockNode.nodeSize).scrollIntoView());\n view.focus();\n return true;\n}\n\nfunction insertNewBranch(\n view: EditorView,\n nodePos: number,\n branchType: Exclude<BranchType, 'if'>,\n condition = '',\n): boolean {\n const context = getBranchContext(view, nodePos);\n if (!context) return false;\n if ((context.branchNode.attrs.branchType as BranchType) === 'else') return false;\n\n const lastBranch = getLastBranchOfBlock(view, nodePos);\n if (!lastBranch) return false;\n\n if (branchType === 'else') {\n if (getElseBranch(view, nodePos)) return false;\n if (lastBranch.index !== context.branchIndex) return false;\n }\n\n const newBranch = createBranchNode(view.state.schema, branchType, condition);\n if (!newBranch) return false;\n\n const insertPos = context.branchPos + context.branchNode.nodeSize;\n view.dispatch(view.state.tr.insert(insertPos, newBranch).scrollIntoView());\n view.focus();\n return true;\n}\n\nfunction deleteBranch(view: EditorView, nodePos: number, branchType: BranchType): boolean {\n const context = getBranchContext(view, nodePos);\n if (!context) return false;\n\n if (branchType === 'if') {\n if (context.blockNode.childCount === 1) {\n return deleteBlock(view, context.blockPos);\n }\n\n const nextBranch = context.blockNode.child(context.branchIndex + 1);\n const promotedCondition = typeof nextBranch.attrs.condition === 'string' ? nextBranch.attrs.condition : '';\n const tr = view.state.tr.delete(context.branchPos, context.branchPos + context.branchNode.nodeSize);\n\n tr.setNodeMarkup(context.branchPos, undefined, {\n ...nextBranch.attrs,\n branchType: 'if',\n condition: promotedCondition,\n });\n\n view.dispatch(tr.scrollIntoView());\n view.focus();\n return true;\n }\n\n view.dispatch(view.state.tr.delete(context.branchPos, context.branchPos + context.branchNode.nodeSize).scrollIntoView());\n view.focus();\n return true;\n}\n\nfunction renderCondition(condition: string) {\n const tokens = tokenizeCondition(condition);\n const rendered: JSX.Element[] = [];\n\n for (let index = 0; index < tokens.length; index++) {\n const token = tokens[index];\n // Skip whitespace-only gaps — CSS gap handles spacing between tokens\n rendered.push(\n <span key={`token-${index}-${token.start}`} className={`jinja-token-${token.category}`}>\n {token.text}\n </span>,\n );\n }\n\n return rendered;\n}\n\nfunction ConditionDisplay({\n branchType,\n condition,\n editable = true,\n onConditionChange,\n}: ConditionDisplayProps) {\n const [isEditing, setIsEditing] = useState(false);\n const [draftValue, setDraftValue] = useState(condition);\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (!isEditing) {\n setDraftValue(condition);\n }\n }, [condition, isEditing]);\n\n useEffect(() => {\n if (isEditing) {\n inputRef.current?.focus();\n inputRef.current?.select();\n }\n }, [isEditing]);\n\n if (branchType === 'else') {\n return <span className=\"jinja-otherwise\">Otherwise</span>;\n }\n\n const commit = () => {\n setIsEditing(false);\n if (draftValue !== condition) {\n onConditionChange(draftValue);\n }\n };\n\n const cancel = () => {\n setDraftValue(condition);\n setIsEditing(false);\n };\n\n if (isEditing && editable) {\n return (\n <input\n ref={inputRef}\n className=\"jinja-condition-input\"\n value={draftValue}\n placeholder={CONDITION_PLACEHOLDER}\n onChange={(event) => setDraftValue(event.target.value)}\n onBlur={commit}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n commit();\n }\n\n if (event.key === 'Escape') {\n event.preventDefault();\n cancel();\n }\n }}\n />\n );\n }\n\n return (\n <button\n type=\"button\"\n className=\"jinja-branch-condition\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => {\n if (editable) {\n setDraftValue(condition);\n setIsEditing(true);\n }\n }}\n >\n {condition.length > 0 ? renderCondition(condition) : <span className=\"jinja-condition-placeholder\">{CONDITION_PLACEHOLDER}</span>}\n </button>\n );\n}\n\nfunction BranchPopupMenu({ items, position }: BranchPopupMenuProps) {\n return (\n <div\n className=\"jinja-popup-menu\"\n style={{\n top: position.top,\n left: position.left,\n right: position.right,\n }}\n role=\"menu\"\n >\n {items.map((item) => (\n <button\n key={item.label}\n type=\"button\"\n className=\"jinja-popup-item\"\n disabled={item.disabled}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => {\n if (!item.disabled) {\n item.onSelect();\n }\n }}\n role=\"menuitem\"\n >\n {item.label}\n </button>\n ))}\n </div>\n );\n}\n\nfunction JinjaBranchHeader({\n branchType,\n condition,\n editable = true,\n onConditionChange,\n onDelete,\n onAddBranch,\n isLastBranch,\n hasElseBranch,\n}: JinjaBranchHeaderProps) {\n const [menuSource, setMenuSource] = useState<'kebab' | 'footer' | null>(null);\n const kebabRef = useRef<HTMLDivElement>(null);\n const footerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!menuSource) return;\n\n const handlePointerDown = (event: PointerEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n if (kebabRef.current?.contains(target) || footerRef.current?.contains(target)) {\n return;\n }\n setMenuSource(null);\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n setMenuSource(null);\n }\n };\n\n document.addEventListener('pointerdown', handlePointerDown, true);\n document.addEventListener('keydown', handleKeyDown);\n\n return () => {\n document.removeEventListener('pointerdown', handlePointerDown, true);\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [menuSource]);\n\n const menuItems: PopupMenuItem[] = [];\n const isOnlyIfBranch = branchType === 'if' && isLastBranch && !hasElseBranch;\n const canAddElif = editable && branchType !== 'else' && (branchType === 'elif' || isLastBranch);\n const canAddElse = editable && branchType !== 'else' && isLastBranch && !hasElseBranch;\n\n if (canAddElif) {\n menuItems.push({\n label: 'Else if',\n onSelect: () => onAddBranch('elif'),\n });\n }\n\n if (canAddElse) {\n menuItems.push({\n label: 'Else',\n onSelect: () => onAddBranch('else'),\n });\n }\n\n if (editable) {\n menuItems.push({\n label: isOnlyIfBranch ? 'Delete all' : 'Delete',\n onSelect: onDelete,\n });\n }\n\n const canOpenFooterMenu = editable && isLastBranch && branchType !== 'else';\n const isMenuOpen = (source: 'kebab' | 'footer') => menuSource === source && menuItems.length > 0;\n\n return (\n <>\n <div className=\"jinja-branch-header\">\n <span className={`jinja-branch-badge jinja-branch-badge-${branchType}`}>\n {branchType === 'elif' ? 'ELSE IF' : branchType.toUpperCase()}\n </span>\n <ConditionDisplay\n branchType={branchType}\n condition={condition}\n editable={editable}\n onConditionChange={onConditionChange}\n />\n {editable ? (\n <div className=\"jinja-branch-actions\" ref={kebabRef}>\n <button\n type=\"button\"\n className=\"jinja-ghost-btn\"\n aria-label={`${branchType} branch options`}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => {\n if (menuItems.length > 0) {\n setMenuSource((current) => (current === 'kebab' ? null : 'kebab'));\n }\n }}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\"><circle cx=\"8\" cy=\"3\" r=\"1.5\"/><circle cx=\"8\" cy=\"8\" r=\"1.5\"/><circle cx=\"8\" cy=\"13\" r=\"1.5\"/></svg>\n </button>\n {isMenuOpen('kebab') ? (\n <BranchPopupMenu\n position={{ top: 28, right: 0 }}\n items={menuItems.map((item) => ({\n ...item,\n onSelect: () => {\n setMenuSource(null);\n item.onSelect();\n },\n }))}\n />\n ) : null}\n </div>\n ) : null}\n </div>\n\n {isLastBranch ? (\n <div className=\"jinja-add-footer\">\n <div className=\"jinja-add-footer-col\">\n <div className=\"jinja-add-footer-actions\" ref={footerRef}>\n <button\n type=\"button\"\n className=\"jinja-ghost-btn\"\n aria-label=\"Add branch\"\n disabled={!canOpenFooterMenu}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => {\n if (canOpenFooterMenu && menuItems.length > 0) {\n setMenuSource((current) => (current === 'footer' ? null : 'footer'));\n }\n }}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\"><line x1=\"8\" y1=\"3\" x2=\"8\" y2=\"13\"/><line x1=\"3\" y1=\"8\" x2=\"13\" y2=\"8\"/></svg>\n </button>\n {isMenuOpen('footer') ? (\n <BranchPopupMenu\n position={{ top: 28, left: 0 }}\n items={menuItems\n .filter((item) => item.label === 'Else if' || item.label === 'Else')\n .map((item) => ({\n ...item,\n onSelect: () => {\n setMenuSource(null);\n item.onSelect();\n },\n }))}\n />\n ) : null}\n </div>\n </div>\n </div>\n ) : null}\n </>\n );\n}\n\nclass JinjaIfBlockView implements NodeView {\n dom: HTMLElement;\n contentDOM: HTMLElement;\n\n constructor() {\n this.dom = document.createElement('div');\n this.dom.className = 'jinja-if-block';\n this.dom.setAttribute('data-jinja-if-block', '');\n this.contentDOM = this.dom;\n // Deferred: notify children to re-render after all siblings are mounted\n requestAnimationFrame(() => this.notifyChildren());\n }\n\n private notifyChildren() {\n this.dom.querySelectorAll('.jinja-branch').forEach((el) => {\n el.dispatchEvent(new CustomEvent('jinja-siblings-changed', { bubbles: false }));\n });\n }\n\n update(node: PMNode): boolean {\n if (node.type.name !== 'jinjaIfBlock') return false;\n requestAnimationFrame(() => this.notifyChildren());\n return true;\n }\n}\n\nclass JinjaIfBranchView implements NodeView {\n dom: HTMLElement;\n contentDOM: HTMLElement;\n\n private headerContainer: HTMLElement;\n private root: Root;\n private node: PMNode;\n private view: EditorView;\n private getPos: () => number | undefined;\n\n constructor(node: PMNode, view: EditorView, getPos: () => number | undefined) {\n this.node = node;\n this.view = view;\n this.getPos = getPos;\n\n StyleManager.acquire();\n\n this.dom = document.createElement('div');\n this.headerContainer = document.createElement('div');\n const body = document.createElement('div');\n const dividerColumn = document.createElement('div');\n const divider = document.createElement('div');\n\n this.dom.appendChild(this.headerContainer);\n this.dom.appendChild(body);\n\n this.headerContainer.className = 'jinja-branch-controls';\n this.headerContainer.contentEditable = 'false';\n\n body.className = 'jinja-branch-body';\n dividerColumn.className = 'jinja-branch-divider-col';\n dividerColumn.contentEditable = 'false';\n divider.className = 'jinja-branch-divider';\n dividerColumn.appendChild(divider);\n\n this.contentDOM = document.createElement('div');\n this.contentDOM.className = 'jinja-branch-content';\n this.contentDOM.setAttribute('data-placeholder', PLACEHOLDER_TEXT);\n\n body.appendChild(dividerColumn);\n body.appendChild(this.contentDOM);\n\n this.root = createRoot(this.headerContainer);\n\n // Listen for sibling changes (dispatched by parent JinjaIfBlockView)\n this._onSiblingsChanged = () => this.render();\n this.dom.addEventListener('jinja-siblings-changed', this._onSiblingsChanged);\n\n this.syncDOM();\n this.render();\n }\n\n private _onSiblingsChanged: (() => void) | null = null;\n\n private syncDOM(): void {\n const branchType = this.node.attrs.branchType as BranchType;\n this.dom.className = `jinja-branch jinja-branch-${branchType}`;\n this.dom.setAttribute('data-jinja-branch', '');\n this.dom.setAttribute('data-branch-type', branchType);\n this.dom.setAttribute('data-condition', String(this.node.attrs.condition ?? ''));\n\n this.contentDOM.classList.toggle('jinja-branch-content-empty', isBranchBodyEmpty(this.node));\n }\n\n private render(): void {\n const nodePos = this.getPos();\n if (nodePos == null) return;\n\n const lastBranch = getLastBranchOfBlock(this.view, nodePos);\n const context = getBranchContext(this.view, nodePos);\n if (!lastBranch || !context) return;\n\n const branchType = this.node.attrs.branchType as BranchType;\n const condition = String(this.node.attrs.condition ?? '');\n const isLast = lastBranch.index === context.branchIndex;\n const lastNonElseIdx = getLastNonElseBranchIndex(this.view, nodePos);\n const showAddButton = context.branchIndex === lastNonElseIdx;\n\n // Add/remove last-branch class for L-shaped divider\n this.dom.classList.toggle('jinja-branch-last', isLast);\n\n this.root.render(\n <JinjaBranchHeader\n branchType={branchType}\n condition={condition}\n editable={this.view.editable}\n isLastBranch={showAddButton}\n hasElseBranch={getElseBranch(this.view, nodePos)}\n onConditionChange={(value) => {\n const currentPos = this.getPos();\n if (currentPos == null) return;\n\n this.view.dispatch(\n this.view.state.tr.setNodeMarkup(currentPos, undefined, {\n ...this.node.attrs,\n condition: value,\n }),\n );\n this.view.focus();\n }}\n onDelete={() => {\n const currentPos = this.getPos();\n if (currentPos == null) return;\n deleteBranch(this.view, currentPos, branchType);\n }}\n onAddBranch={(nextBranchType) => {\n const currentPos = this.getPos();\n if (currentPos == null) return;\n insertNewBranch(this.view, currentPos, nextBranchType, '');\n }}\n />,\n );\n }\n\n update(node: PMNode): boolean {\n if (!isBranchNode(node)) return false;\n\n this.node = node;\n this.syncDOM();\n this.render();\n return true;\n }\n\n stopEvent(event: Event): boolean {\n const target = event.target as Node | null;\n return target != null && this.headerContainer.contains(target);\n }\n\n ignoreMutation(mutation: ViewMutationRecord): boolean {\n return this.headerContainer.contains(mutation.target);\n }\n\n destroy(): void {\n if (this._onSiblingsChanged) {\n this.dom.removeEventListener('jinja-siblings-changed', this._onSiblingsChanged);\n }\n StyleManager.release();\n setTimeout(() => this.root.unmount(), 0);\n }\n}\n\nexport function createJinjaIfBlockPlugin(): ActionbookPlugin {\n return {\n name: 'jinjaIfBlock',\n nodeViews: () => ({\n jinjaIfBlock: (() => new JinjaIfBlockView()) as NodeViewFactory,\n jinjaIfBranch: ((node: PMNode, view: EditorView, getPos: () => number | undefined) => (\n new JinjaIfBranchView(node, view, getPos)\n )) as NodeViewFactory,\n }),\n };\n}\n","type TokenType =\n | 'STRING'\n | 'NUMBER'\n | 'BOOL'\n | 'NONE'\n | 'IDENT'\n | 'AND'\n | 'OR'\n | 'NOT'\n | 'IN'\n | 'IS'\n | 'EQ'\n | 'NEQ'\n | 'LT'\n | 'GT'\n | 'LTE'\n | 'GTE'\n | 'LPAREN'\n | 'RPAREN';\n\nexport type HighlightCategory = 'variable' | 'operator' | 'value' | 'punctuation';\n\nexport interface ConditionToken {\n readonly text: string;\n readonly start: number;\n readonly end: number;\n readonly category: HighlightCategory;\n}\n\ninterface RawToken {\n readonly type: TokenType;\n readonly text: string;\n readonly start: number;\n readonly end: number;\n}\n\nconst KEYWORDS: Readonly<Record<string, TokenType>> = {\n and: 'AND',\n or: 'OR',\n not: 'NOT',\n in: 'IN',\n is: 'IS',\n True: 'BOOL',\n False: 'BOOL',\n true: 'BOOL',\n false: 'BOOL',\n None: 'NONE',\n null: 'NONE',\n};\n\nconst CATEGORY_BY_TYPE: Readonly<Record<TokenType, HighlightCategory>> = {\n STRING: 'value',\n NUMBER: 'value',\n BOOL: 'value',\n NONE: 'value',\n IDENT: 'variable',\n AND: 'operator',\n OR: 'operator',\n NOT: 'operator',\n IN: 'operator',\n IS: 'operator',\n EQ: 'operator',\n NEQ: 'operator',\n LT: 'operator',\n GT: 'operator',\n LTE: 'operator',\n GTE: 'operator',\n LPAREN: 'punctuation',\n RPAREN: 'punctuation',\n};\n\nconst NEGATIVE_NUMBER_PRECEDERS = new Set<TokenType>([\n 'AND',\n 'OR',\n 'NOT',\n 'IN',\n 'IS',\n 'EQ',\n 'NEQ',\n 'LT',\n 'GT',\n 'LTE',\n 'GTE',\n 'LPAREN',\n]);\n\nfunction canStartNegativeNumber(tokens: readonly RawToken[]): boolean {\n if (tokens.length === 0) {\n return true;\n }\n\n const previous = tokens[tokens.length - 1];\n return NEGATIVE_NUMBER_PRECEDERS.has(previous.type);\n}\n\nfunction finalizeTokens(input: string, rawTokens: readonly RawToken[]): ConditionToken[] {\n const highlighted: ConditionToken[] = [];\n\n for (let i = 0; i < rawTokens.length; i++) {\n const token = rawTokens[i];\n const next = rawTokens[i + 1];\n\n if (token.type === 'IS' && next?.type === 'NOT') {\n highlighted.push({\n text: input.slice(token.start, next.end),\n start: token.start,\n end: next.end,\n category: 'operator',\n });\n i++;\n continue;\n }\n\n highlighted.push({\n text: token.text,\n start: token.start,\n end: token.end,\n category: CATEGORY_BY_TYPE[token.type],\n });\n }\n\n return highlighted;\n}\n\nexport function tokenizeCondition(input: string): ConditionToken[] {\n const rawTokens: RawToken[] = [];\n let i = 0;\n\n while (i < input.length) {\n const char = input[i];\n\n if (/\\s/.test(char)) {\n i++;\n continue;\n }\n\n if (char === '\"' || char === \"'\") {\n const start = i;\n const quote = char;\n i++;\n\n while (i < input.length) {\n if (input[i] === '\\\\' && i + 1 < input.length) {\n i += 2;\n continue;\n }\n\n if (input[i] === quote) {\n i++;\n rawTokens.push({\n type: 'STRING',\n text: input.slice(start, i),\n start,\n end: i,\n });\n break;\n }\n\n i++;\n }\n\n if (rawTokens[rawTokens.length - 1]?.start !== start) {\n return finalizeTokens(input, rawTokens);\n }\n\n continue;\n }\n\n if (/[0-9]/.test(char) || (char === '-' && i + 1 < input.length && /[0-9]/.test(input[i + 1]) && canStartNegativeNumber(rawTokens))) {\n const start = i;\n\n if (input[i] === '-') {\n i++;\n }\n\n while (i < input.length && /[0-9]/.test(input[i])) {\n i++;\n }\n\n if (i < input.length && input[i] === '.') {\n i++;\n while (i < input.length && /[0-9]/.test(input[i])) {\n i++;\n }\n }\n\n rawTokens.push({\n type: 'NUMBER',\n text: input.slice(start, i),\n start,\n end: i,\n });\n continue;\n }\n\n if (/[a-zA-Z_]/.test(char)) {\n const start = i;\n i++;\n\n while (i < input.length && /[a-zA-Z0-9_.]/.test(input[i])) {\n i++;\n }\n\n const text = input.slice(start, i);\n rawTokens.push({\n type: KEYWORDS[text] ?? 'IDENT',\n text,\n start,\n end: i,\n });\n continue;\n }\n\n if (i + 1 < input.length) {\n const twoChar = input.slice(i, i + 2);\n\n if (twoChar === '==') {\n rawTokens.push({ type: 'EQ', text: twoChar, start: i, end: i + 2 });\n i += 2;\n continue;\n }\n\n if (twoChar === '!=') {\n rawTokens.push({ type: 'NEQ', text: twoChar, start: i, end: i + 2 });\n i += 2;\n continue;\n }\n\n if (twoChar === '<=') {\n rawTokens.push({ type: 'LTE', text: twoChar, start: i, end: i + 2 });\n i += 2;\n continue;\n }\n\n if (twoChar === '>=') {\n rawTokens.push({ type: 'GTE', text: twoChar, start: i, end: i + 2 });\n i += 2;\n continue;\n }\n }\n\n if (char === '<') {\n rawTokens.push({ type: 'LT', text: char, start: i, end: i + 1 });\n i++;\n continue;\n }\n\n if (char === '>') {\n rawTokens.push({ type: 'GT', text: char, start: i, end: i + 1 });\n i++;\n continue;\n }\n\n if (char === '(') {\n rawTokens.push({ type: 'LPAREN', text: char, start: i, end: i + 1 });\n i++;\n continue;\n }\n\n if (char === ')') {\n rawTokens.push({ type: 'RPAREN', text: char, start: i, end: i + 1 });\n i++;\n continue;\n }\n\n return finalizeTokens(input, rawTokens);\n }\n\n return finalizeTokens(input, rawTokens);\n}\n","/**\n * Link editing plugin for the Actionbook editor.\n *\n * UX flow:\n * 1. `[aa](#aa)` is rendered as a clickable \"aa\" link mark.\n * 2. Pressing Backspace while cursor is inside or just after the link\n * \"explodes\" it to raw markdown `[aa](#aa)` for editing.\n * 3. While the cursor stays inside the raw text, normal editing applies.\n * 4. When the cursor leaves the raw region:\n * - If the text still matches `[label](href)` → reconverts to link mark.\n * - Otherwise → stays as plain text (user intentionally broke the link).\n * 5. Completing the markdown syntax by typing `)` triggers the input rule\n * and immediately converts to a link mark.\n */\n\nimport { InputRule, inputRules } from 'prosemirror-inputrules';\nimport { Plugin, PluginKey, TextSelection } from 'prosemirror-state';\nimport type { EditorState, Transaction } from 'prosemirror-state';\nimport type { Mark, MarkType, ResolvedPos } from 'prosemirror-model';\nimport type { ActionbookPlugin } from './types';\n\n// ── Regexes ──────────────────────────────────────────────────────────────────\n\n/** Matches a fully typed `[label](href)` or `[label](href \"title\")` at end of input. */\nconst LINK_INPUT_RE = /\\[([^\\]]*)\\]\\(([^)\\s]*?)(?:\\s+\"([^\"]*)\")?\\)$/;\n\n/**\n * Matches raw link text that spans the entire string.\n * Used to validate/reconvert after cursor leaves the raw editing region.\n */\nconst LINK_FULL_RE = /^\\[([^\\]]*)\\]\\(([^)\\s]*?)(?:\\s+\"([^\"]*)\")?\\)$/;\n\n// ── Plugin state ──────────────────────────────────────────────────────────────\n\ninterface LinkEditState {\n /** Absolute positions of the raw `[label](href)` text currently being edited. */\n rawRange: { from: number; to: number } | null;\n}\n\nconst linkEditKey = new PluginKey<LinkEditState>('linkEdit');\n\n// ── Utilities ─────────────────────────────────────────────────────────────────\n\n/**\n * Find the contiguous extent of a mark type around a resolved position.\n *\n * Handles `inclusive: false` marks (like `link`) correctly: when cursor is\n * placed just AFTER the mark text, the last node of the mark span is found\n * via `childBefore` and the full range is returned.\n */\nfunction getMarkRange(\n $pos: ResolvedPos,\n type: MarkType,\n): { from: number; to: number; mark: Mark } | null {\n const { parentOffset } = $pos;\n\n let child = $pos.parent.childAfter(parentOffset);\n\n // When cursor is exactly at a node boundary, also try the node ending here.\n if (parentOffset === child.offset && child.offset !== 0) {\n child = $pos.parent.childBefore(parentOffset);\n }\n\n if (!child.node) return null;\n\n const mark = child.node.marks.find((m) => m.type === type);\n if (!mark) return null;\n\n const parentStart = $pos.start();\n let { index: startIndex } = child;\n let startPos = parentStart + child.offset;\n let endIndex = startIndex + 1;\n let endPos = startPos + child.node.nodeSize;\n\n while (startIndex > 0 && mark.isInSet($pos.parent.child(startIndex - 1).marks)) {\n startIndex -= 1;\n startPos -= $pos.parent.child(startIndex).nodeSize;\n }\n\n while (\n endIndex < $pos.parent.childCount &&\n mark.isInSet($pos.parent.child(endIndex).marks)\n ) {\n endPos += $pos.parent.child(endIndex).nodeSize;\n endIndex += 1;\n }\n\n return { from: startPos, to: endPos, mark };\n}\n\n/**\n * Replace a link mark span with its raw markdown text `[label](href)`.\n *\n * Cursor placement after explosion: maps the cursor offset within the link\n * label to the same relative position in the raw text (adding 1 for the\n * leading `[`). For cursor at the end of the label, this positions just\n * before `]`, which is natural for continued editing.\n *\n * Returns `null` when the cursor is not at/inside a link mark.\n */\nfunction explodeLinkToRaw(state: EditorState): Transaction | null {\n const { selection, doc, schema } = state;\n if (!selection.empty) return null;\n\n const linkMarkType = schema.marks.link;\n if (!linkMarkType) return null;\n\n const $pos = doc.resolve(selection.from);\n const range = getMarkRange($pos, linkMarkType);\n if (!range) return null;\n\n const { from, to, mark } = range;\n const label = doc.textBetween(from, to);\n const { href, title } = mark.attrs as { href: string; title: string | null };\n const titlePart = title ? ` \"${title}\"` : '';\n const rawText = `[${label}](${href}${titlePart})`;\n\n // +1 for the leading `[`, clamped to label length\n const cursorOffset = Math.min(selection.from - from, label.length);\n const rawCursorOffset = cursorOffset + 1;\n\n const tr = state.tr;\n tr.replaceWith(from, to, schema.text(rawText));\n\n const newPos = Math.min(from + rawCursorOffset, tr.doc.content.size);\n tr.setSelection(TextSelection.near(tr.doc.resolve(newPos)));\n tr.setMeta(linkEditKey, { from, to: from + rawText.length });\n\n return tr;\n}\n\n// ── Auto-reconvert plugin ─────────────────────────────────────────────────────\n\n/**\n * Tracks the raw editing region after a link explosion and reconverts it back\n * to a link mark when the cursor moves outside that region.\n */\nfunction createLinkEditPlugin(): Plugin<LinkEditState> {\n return new Plugin<LinkEditState>({\n key: linkEditKey,\n\n state: {\n init: (): LinkEditState => ({ rawRange: null }),\n\n apply(tr, prev): LinkEditState {\n const meta = tr.getMeta(linkEditKey) as\n | { from: number; to: number }\n | null\n | undefined;\n\n if (meta !== undefined) return { rawRange: meta };\n\n if (prev.rawRange) {\n const from = tr.mapping.map(prev.rawRange.from);\n const to = tr.mapping.map(prev.rawRange.to);\n if (from >= to) return { rawRange: null };\n return { rawRange: { from, to } };\n }\n\n return prev;\n },\n },\n\n appendTransaction(_, __, newState) {\n const pluginState = linkEditKey.getState(newState);\n if (!pluginState?.rawRange) return null;\n\n const { from, to } = pluginState.rawRange;\n\n // Still inside — nothing to do\n if (newState.selection.anchor >= from && newState.selection.anchor <= to) {\n return null;\n }\n\n const docSize = newState.doc.content.size;\n const safeFrom = Math.min(from, docSize);\n const safeTo = Math.min(to, docSize);\n\n const reconvertTr = newState.tr;\n reconvertTr.setMeta(linkEditKey, null);\n\n if (safeFrom < safeTo) {\n const text = newState.doc.textBetween(safeFrom, safeTo);\n const match = LINK_FULL_RE.exec(text);\n\n if (match) {\n const [, label, href, title] = match;\n const linkMarkType = newState.schema.marks.link;\n\n if (linkMarkType && href) {\n const attrs = title ? { href, title: title.trim() } : { href };\n reconvertTr.delete(safeFrom, safeTo);\n if (label.length > 0) {\n reconvertTr.insertText(label, safeFrom);\n reconvertTr.addMark(\n safeFrom,\n safeFrom + label.length,\n linkMarkType.create(attrs),\n );\n }\n }\n }\n }\n\n return reconvertTr;\n },\n });\n}\n\n// ── Input rule ────────────────────────────────────────────────────────────────\n\n/**\n * When the user completes `[label](href)` by typing `)`, immediately convert\n * the matched text to a link mark. Works both for fresh typing and for\n * finalising an edited raw-exploded link.\n */\nfunction createLinkInputRule(): InputRule {\n return new InputRule(\n LINK_INPUT_RE,\n (state, match, start, end) => {\n const [, label, href, title] = match;\n const linkMarkType = state.schema.marks.link;\n if (!linkMarkType || !href) return null;\n\n const displayText = label || href;\n const attrs = title ? { href, title: title.trim() } : { href };\n const { tr } = state;\n\n tr.replaceWith(start, end, state.schema.text(displayText));\n tr.addMark(start, start + displayText.length, linkMarkType.create(attrs));\n tr.setMeta(linkEditKey, null);\n\n return tr;\n },\n );\n}\n\n// ── Click handler (anchor navigation) ────────────────────────────────────────\n\nfunction createLinkClickPlugin(): Plugin {\n return new Plugin({\n key: new PluginKey('linkClick'),\n props: {\n handleDOMEvents: {\n click: (_view, event) => {\n const target = event.target as HTMLElement;\n if (target.tagName !== 'A') return false;\n\n const href = (target as HTMLAnchorElement).getAttribute('href');\n if (!href) return false;\n\n // Internal jump-point links (#section) — scroll instead of navigate\n if (href.startsWith('#')) {\n event.preventDefault();\n const targetId = `jp-${href.slice(1)}`;\n const el = document.getElementById(targetId);\n if (el) {\n el.scrollIntoView({ block: 'end' });\n el.focus();\n if (el.parentElement) {\n el.parentElement.style.outline = '2px solid #6213cc';\n setTimeout(() => {\n (el.parentElement as HTMLElement).style.outline = 'none';\n }, 500);\n }\n }\n return true;\n }\n\n return false;\n },\n },\n },\n });\n}\n\n// ── Public factory ────────────────────────────────────────────────────────────\n\n/**\n * Creates the link editing `ActionbookPlugin`.\n *\n * Bundles:\n * - Backspace → explode to raw markdown\n * - `appendTransaction` auto-reconvert on cursor leave\n * - Input rule for `[label](href)` → link mark\n * - Click handler for internal `#anchor` links\n */\nexport function createLinkPlugin(): ActionbookPlugin {\n return {\n name: 'link',\n plugins: () => [\n createLinkEditPlugin(),\n createLinkClickPlugin(),\n inputRules({ rules: [createLinkInputRule()] }),\n ],\n keymap: () => ({\n Backspace: (state, dispatch) => {\n if (!state.selection.empty) return false;\n\n // Already in raw-edit mode — let normal Backspace through\n if (linkEditKey.getState(state)?.rawRange) return false;\n\n const tr = explodeLinkToRaw(state);\n if (!tr) return false;\n\n if (dispatch) dispatch(tr);\n return true;\n },\n }),\n };\n}\n","/**\n * Drag handle plugin v2 — enterprise-grade block reordering.\n *\n * Key improvements over v1:\n * - Diff-based handle updates (no full DOM rebuild per transaction)\n * - Pointer Events API (unified mouse/touch/pen)\n * - Auto-scroll during drag\n * - Keyboard accessibility (Alt+Arrow, ARIA)\n * - CSS custom properties for theming\n * - Proper style cleanup via adopted stylesheets / ref-count\n * - Class-based state management for testability\n */\nimport { Plugin, PluginKey } from 'prosemirror-state';\nimport type { EditorView } from 'prosemirror-view';\nimport type { Node as PMNode, ResolvedPos } from 'prosemirror-model';\nimport type { Transaction, EditorState, Command } from 'prosemirror-state';\nimport type { ActionbookPlugin } from './types';\n\n// ────────────────────────────────────────────────────────────\n// Constants\n// ────────────────────────────────────────────────────────────\n\nconst PLUGIN_KEY = new PluginKey('dragHandle');\n\nconst GRIP_SVG = `<svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"currentColor\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"4\" cy=\"2.5\" r=\"1.2\"/><circle cx=\"8\" cy=\"2.5\" r=\"1.2\"/>\n <circle cx=\"4\" cy=\"6\" r=\"1.2\"/><circle cx=\"8\" cy=\"6\" r=\"1.2\"/>\n <circle cx=\"4\" cy=\"9.5\" r=\"1.2\"/><circle cx=\"8\" cy=\"9.5\" r=\"1.2\"/>\n</svg>`;\n\nconst AUTO_SCROLL_ZONE = 40;\nconst AUTO_SCROLL_MAX_SPEED = 8;\nconst HANDLE_GAP = 4;\nexport const DRAG_THRESHOLD = 5;\n\n// ────────────────────────────────────────────────────────────\n// Styles (CSS custom properties for theming)\n// ────────────────────────────────────────────────────────────\n\nconst STYLES = /* css */ `\n.ab-drag-handle-layer {\n --ab-dh-color-idle: transparent;\n --ab-dh-color-hover: #c4c4c4;\n --ab-dh-color-visible: #8b8b8b;\n --ab-dh-color-accent: #6366f1;\n --ab-dh-bg-hover: rgba(0,0,0,0.04);\n --ab-dh-bg-active: rgba(99,102,241,0.08);\n --ab-dh-dragging-opacity: 0.4;\n --ab-dh-handle-size: 22px;\n --ab-dh-handle-radius: 4px;\n --ab-dh-transition-duration: 0.15s;\n\n position: absolute;\n top: 0; left: 0; right: 0; bottom: 0;\n pointer-events: none;\n overflow: visible;\n}\n.ab-drag-handle {\n position: absolute;\n width: var(--ab-dh-handle-size);\n height: var(--ab-dh-handle-size);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: grab;\n color: var(--ab-dh-color-idle);\n border-radius: var(--ab-dh-handle-radius);\n transition: color var(--ab-dh-transition-duration), background var(--ab-dh-transition-duration);\n user-select: none;\n pointer-events: auto;\n touch-action: none;\n}\n.ab-drag-handle-layer[data-hover] .ab-drag-handle {\n color: var(--ab-dh-color-hover);\n}\n.ab-drag-handle:hover {\n color: var(--ab-dh-color-visible) !important;\n background: var(--ab-dh-bg-hover);\n}\n.ab-drag-handle:active, .ab-drag-handle.dragging {\n cursor: grabbing;\n color: var(--ab-dh-color-accent) !important;\n background: var(--ab-dh-bg-active);\n}\n.ab-drop-indicator {\n position: absolute;\n left: 0; right: 0;\n height: 2px;\n background: var(--ab-dh-color-accent, #6366f1);\n border-radius: 1px;\n pointer-events: none;\n z-index: 20;\n transition: top 60ms ease-out;\n}\n.ab-block-dragging {\n opacity: var(--ab-dh-dragging-opacity, 0.4);\n}\n@keyframes ab-block-flash {\n from { background: rgba(99,102,241,0.12); }\n to { background: transparent; }\n}\n.ab-block-just-moved {\n animation: ab-block-flash 0.4s ease-out;\n}\n.ab-sr-only {\n position: absolute;\n width: 1px; height: 1px;\n padding: 0; margin: -1px;\n overflow: hidden;\n clip: rect(0,0,0,0);\n white-space: nowrap;\n border: 0;\n}\n`;\n\n// ────────────────────────────────────────────────────────────\n// Style Manager (ref-counted, leak-free)\n// ────────────────────────────────────────────────────────────\n\nclass StyleManager {\n private static refCount = 0;\n private static sheet: CSSStyleSheet | null = null;\n private static styleEl: HTMLStyleElement | null = null;\n\n static acquire(): void {\n if (this.refCount++ > 0) return;\n\n if (typeof CSSStyleSheet !== 'undefined' && 'replaceSync' in CSSStyleSheet.prototype) {\n this.sheet = new CSSStyleSheet();\n this.sheet.replaceSync(STYLES);\n document.adoptedStyleSheets = [...document.adoptedStyleSheets, this.sheet];\n } else {\n // Fallback for older browsers\n this.styleEl = document.createElement('style');\n this.styleEl.id = 'ab-drag-handle-styles';\n this.styleEl.textContent = STYLES;\n document.head.appendChild(this.styleEl);\n }\n }\n\n static release(): void {\n if (--this.refCount > 0) return;\n\n if (this.sheet) {\n document.adoptedStyleSheets = document.adoptedStyleSheets.filter(s => s !== this.sheet);\n this.sheet = null;\n }\n if (this.styleEl) {\n this.styleEl.remove();\n this.styleEl = null;\n }\n }\n}\n\n// ────────────────────────────────────────────────────────────\n// Types\n// ────────────────────────────────────────────────────────────\n\ninterface BlockInfo {\n offset: number;\n nodeSize: number;\n dom: HTMLElement;\n}\n\ninterface HandleEntry {\n el: HTMLElement;\n block: BlockInfo;\n topPx: number;\n listenerCleanup: () => void;\n}\n\ninterface DragState {\n fromIndex: number;\n handle: HTMLElement;\n blockDom: HTMLElement;\n dropTargetIndex: number;\n pointerY: number;\n pointerId: number;\n startX: number;\n startY: number;\n activated: boolean;\n}\n\n// ────────────────────────────────────────────────────────────\n// Pure helpers (exported for testing)\n// ────────────────────────────────────────────────────────────\n\n/**\n * Build a PM transaction that moves the top-level block at `fromIndex`\n * to `toIndex` (insert-before semantics: toIndex is counted in the\n * original ordering).\n *\n * Returns null if the move is a no-op or out of bounds.\n */\nexport function buildMoveTransaction(\n state: EditorState,\n fromIndex: number,\n toIndex: number,\n): Transaction | null {\n const { doc } = state;\n if (fromIndex === toIndex || fromIndex + 1 === toIndex) return null;\n if (fromIndex < 0 || fromIndex >= doc.childCount) return null;\n if (toIndex < 0 || toIndex > doc.childCount) return null;\n\n const node = doc.child(fromIndex);\n\n // Collect offsets of each top-level block\n const offsets: number[] = [];\n doc.forEach((_child, offset) => { offsets.push(offset); });\n\n const nodeStart = offsets[fromIndex];\n const nodeEnd = nodeStart + node.nodeSize;\n\n let tr = state.tr;\n\n if (toIndex > fromIndex) {\n // Moving down: insert first, then delete (keeps positions valid)\n const targetEnd = offsets[toIndex - 1] + doc.child(toIndex - 1).nodeSize;\n tr = tr.insert(targetEnd, node);\n tr = tr.delete(tr.mapping.map(nodeStart), tr.mapping.map(nodeEnd));\n } else {\n // Moving up: delete first, then insert\n const insertPos = offsets[toIndex];\n tr = tr.delete(nodeStart, nodeEnd);\n tr = tr.insert(tr.mapping.map(insertPos), node);\n }\n\n return tr;\n}\n\n/**\n * Given a list of block bounding rects (top/bottom relative to container),\n * determine which gap the pointer is closest to.\n * Returns an index in [0, blocks.length] (insert-before semantics).\n */\nexport function findDropTarget(\n blockRects: Array<{ top: number; bottom: number }>,\n pointerY: number,\n): number {\n if (blockRects.length === 0) return 0;\n\n let bestIndex = 0;\n let bestDist = Infinity;\n\n for (let i = 0; i <= blockRects.length; i++) {\n let gapY: number;\n if (i === 0) {\n gapY = blockRects[0].top;\n } else if (i === blockRects.length) {\n gapY = blockRects[blockRects.length - 1].bottom;\n } else {\n gapY = (blockRects[i - 1].bottom + blockRects[i].top) / 2;\n }\n const dist = Math.abs(pointerY - gapY);\n if (dist < bestDist) {\n bestDist = dist;\n bestIndex = i;\n }\n }\n\n return bestIndex;\n}\n\n/**\n * Compute auto-scroll speed based on pointer proximity to container edges.\n * Returns pixels-per-frame (negative = up, positive = down, 0 = no scroll).\n */\nexport function computeAutoScrollSpeed(\n pointerY: number,\n containerTop: number,\n containerBottom: number,\n): number {\n if (pointerY < containerTop + AUTO_SCROLL_ZONE) {\n const ratio = Math.max(0, (pointerY - containerTop) / AUTO_SCROLL_ZONE);\n return -AUTO_SCROLL_MAX_SPEED * (1 - ratio);\n }\n if (pointerY > containerBottom - AUTO_SCROLL_ZONE) {\n const ratio = Math.max(0, (containerBottom - pointerY) / AUTO_SCROLL_ZONE);\n return AUTO_SCROLL_MAX_SPEED * (1 - ratio);\n }\n return 0;\n}\n\n/**\n * Compare two block lists and return which indices need create/remove/reposition.\n * A block is \"same\" if its offset and nodeSize match.\n */\nexport function diffBlockList(\n prev: Array<{ offset: number; nodeSize: number }>,\n next: Array<{ offset: number; nodeSize: number }>,\n): { added: number[]; removed: number[]; kept: Array<{ prevIdx: number; nextIdx: number }> } {\n const prevMap = new Map<string, number>();\n prev.forEach((b, i) => prevMap.set(`${b.offset}:${b.nodeSize}`, i));\n\n const added: number[] = [];\n const kept: Array<{ prevIdx: number; nextIdx: number }> = [];\n const usedPrev = new Set<number>();\n\n next.forEach((b, i) => {\n const key = `${b.offset}:${b.nodeSize}`;\n const prevIdx = prevMap.get(key);\n if (prevIdx !== undefined && !usedPrev.has(prevIdx)) {\n kept.push({ prevIdx, nextIdx: i });\n usedPrev.add(prevIdx);\n } else {\n added.push(i);\n }\n });\n\n const removed: number[] = [];\n prev.forEach((_, i) => {\n if (!usedPrev.has(i)) removed.push(i);\n });\n\n return { added, removed, kept };\n}\n\n// ────────────────────────────────────────────────────────────\n// DragHandleController\n// ────────────────────────────────────────────────────────────\n\nclass DragHandleController {\n private view: EditorView;\n private layer: HTMLElement;\n private liveRegion: HTMLElement;\n private handles: HandleEntry[] = [];\n private prevBlocks: BlockInfo[] = [];\n private drag: DragState | null = null;\n private dropIndicator: HTMLElement | null = null;\n private scrollRAF: number | null = null;\n private updateRAF: number | null = null;\n private pendingUpdate = false;\n private scrollContainer: HTMLElement;\n private scrollSyncRAF: number | null = null;\n private resizeObserver: ResizeObserver | null = null;\n\n // Hover state\n private hoverBound: { enter: () => void; leave: () => void } | null = null;\n\n // Global fallback handlers active during drag\n private globalCleanup: (() => void) | null = null;\n\n constructor(view: EditorView) {\n this.view = view;\n StyleManager.acquire();\n\n const parent = view.dom.parentNode as HTMLElement;\n const pos = getComputedStyle(parent).position;\n if (pos === 'static' || pos === '') parent.style.position = 'relative';\n\n // Create overlay layer\n this.layer = document.createElement('div');\n this.layer.className = 'ab-drag-handle-layer';\n parent.insertBefore(this.layer, view.dom.nextSibling);\n\n // ARIA live region for announcements\n this.liveRegion = document.createElement('div');\n this.liveRegion.className = 'ab-sr-only';\n this.liveRegion.setAttribute('aria-live', 'assertive');\n this.liveRegion.setAttribute('aria-atomic', 'true');\n parent.appendChild(this.liveRegion);\n\n // Hover behavior: show handles on editor hover\n const onEnter = () => { this.layer.dataset.hover = '1'; };\n const onLeave = () => { if (!this.drag) delete this.layer.dataset.hover; };\n parent.addEventListener('mouseenter', onEnter);\n parent.addEventListener('mouseleave', onLeave);\n this.hoverBound = { enter: onEnter, leave: onLeave };\n\n // Find scroll container\n this.scrollContainer = this.findScrollContainer(view.dom);\n\n // Scroll listener — reposition handles when container scrolls\n this.scrollContainer.addEventListener('scroll', this.onScroll, { passive: true });\n\n // Resize observer — recompute when editor dimensions change\n this.resizeObserver = new ResizeObserver(() => this.scheduleUpdate());\n this.resizeObserver.observe(view.dom);\n\n // Initial render\n this.rebuildHandles();\n }\n\n update(view: EditorView, prevState: EditorState): void {\n this.view = view;\n\n // Skip updates during drag — flush when drag ends\n if (this.drag) {\n this.pendingUpdate = true;\n return;\n }\n\n // Only recompute when doc structure changes\n if (!view.state.doc.eq(prevState.doc)) {\n this.scheduleUpdate();\n }\n }\n\n destroy(): void {\n this.cancelDrag();\n\n if (this.updateRAF !== null) cancelAnimationFrame(this.updateRAF);\n if (this.scrollSyncRAF !== null) cancelAnimationFrame(this.scrollSyncRAF);\n this.scrollContainer.removeEventListener('scroll', this.onScroll);\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n\n // Remove handles and their listeners\n for (const h of this.handles) {\n h.listenerCleanup();\n h.el.remove();\n }\n this.handles = [];\n\n // Remove hover listeners\n if (this.hoverBound) {\n const parent = this.view.dom.parentNode as HTMLElement | null;\n if (parent) {\n parent.removeEventListener('mouseenter', this.hoverBound.enter);\n parent.removeEventListener('mouseleave', this.hoverBound.leave);\n }\n }\n\n this.liveRegion.remove();\n this.layer.remove();\n StyleManager.release();\n }\n\n // ── Private: update pipeline ──\n\n private scheduleUpdate(): void {\n if (this.updateRAF !== null) return;\n this.updateRAF = requestAnimationFrame(() => {\n this.updateRAF = null;\n this.rebuildHandles();\n });\n }\n\n private onScroll = (): void => {\n if (this.scrollSyncRAF !== null) return;\n this.scrollSyncRAF = requestAnimationFrame(() => {\n this.scrollSyncRAF = null;\n if (!this.drag) this.syncHandlePositions();\n });\n };\n\n private collectBlocks(): BlockInfo[] {\n const blocks: BlockInfo[] = [];\n\n this.view.state.doc.forEach((node, offset) => {\n // nodeDOM returns the outermost DOM node for the block at this offset.\n // This is more reliable than domAtPos(offset + 1) which can resolve to\n // the wrong element for leaf blocks (e.g. horizontalRule with nodeSize=1).\n const dom = this.view.nodeDOM(offset);\n if (dom instanceof HTMLElement) {\n blocks.push({ offset, nodeSize: node.nodeSize, dom });\n }\n });\n\n return blocks;\n }\n\n private rebuildHandles(): void {\n const newBlocks = this.collectBlocks();\n const diff = diffBlockList(\n this.prevBlocks.map(b => ({ offset: b.offset, nodeSize: b.nodeSize })),\n newBlocks.map(b => ({ offset: b.offset, nodeSize: b.nodeSize })),\n );\n\n const parent = this.view.dom.parentNode as HTMLElement;\n const parentRect = parent.getBoundingClientRect();\n const editorRect = this.view.dom.getBoundingClientRect();\n const handleSize = parseInt(getComputedStyle(this.layer).getPropertyValue('--ab-dh-handle-size') || '22', 10);\n const handleLeft = editorRect.left - parentRect.left - handleSize - HANDLE_GAP;\n\n // Build new handles array preserving kept entries\n const newHandles: HandleEntry[] = new Array(newBlocks.length);\n\n // Reuse kept handles (reposition if needed)\n for (const { prevIdx, nextIdx } of diff.kept) {\n const entry = this.handles[prevIdx];\n entry.block = newBlocks[nextIdx];\n const blockRect = entry.block.dom.getBoundingClientRect();\n const lineHeight = parseFloat(getComputedStyle(entry.block.dom).lineHeight) || 24;\n const verticalOffset = Math.max(0, (lineHeight - handleSize) / 2);\n const topPx = blockRect.top - parentRect.top + parent.scrollTop + verticalOffset;\n entry.topPx = topPx;\n entry.el.style.top = `${topPx}px`;\n entry.el.style.left = `${handleLeft}px`;\n // Update the index in the pointerdown closure\n this.rebindHandleIndex(entry, nextIdx);\n newHandles[nextIdx] = entry;\n }\n\n // Remove obsolete handles\n for (const idx of diff.removed) {\n const entry = this.handles[idx];\n entry.listenerCleanup();\n entry.el.remove();\n }\n\n // Create new handles\n for (const idx of diff.added) {\n const block = newBlocks[idx];\n const blockRect = block.dom.getBoundingClientRect();\n const lineHeight = parseFloat(getComputedStyle(block.dom).lineHeight) || 24;\n const verticalOffset = Math.max(0, (lineHeight - handleSize) / 2);\n const topPx = blockRect.top - parentRect.top + parent.scrollTop + verticalOffset;\n\n const el = document.createElement('div');\n el.className = 'ab-drag-handle';\n el.setAttribute('data-ab-float', '');\n el.setAttribute('role', 'button');\n el.setAttribute('aria-roledescription', 'drag handle');\n el.setAttribute('aria-label', `블록 ${idx + 1} 이동`);\n el.setAttribute('tabindex', '-1');\n el.innerHTML = GRIP_SVG;\n el.style.left = `${handleLeft}px`;\n el.style.top = `${topPx}px`;\n this.layer.appendChild(el);\n\n const cleanup = this.bindHandleEvents(el, idx);\n newHandles[idx] = { el, block, topPx, listenerCleanup: cleanup };\n }\n\n this.handles = newHandles;\n this.prevBlocks = newBlocks;\n }\n\n private bindHandleEvents(el: HTMLElement, index: number): () => void {\n let currentIndex = index;\n const onPointerDown = (e: PointerEvent) => {\n e.preventDefault();\n if (!this.view.editable) return;\n el.setPointerCapture(e.pointerId);\n // Re-collect block positions at drag start for accuracy\n this.prevBlocks = this.collectBlocks();\n this.syncHandlePositions();\n this.startDrag(currentIndex, el, e);\n };\n const onPointerMove = (e: PointerEvent) => this.onPointerMove(e);\n const onPointerUp = (e: PointerEvent) => this.onPointerUp(e);\n const onLostCapture = () => this.cancelDrag();\n\n const onPointerCancel = () => this.cancelDrag();\n\n el.addEventListener('pointerdown', onPointerDown);\n el.addEventListener('pointermove', onPointerMove);\n el.addEventListener('pointerup', onPointerUp);\n el.addEventListener('pointercancel', onPointerCancel);\n el.addEventListener('lostpointercapture', onLostCapture);\n\n const cleanup = () => {\n el.removeEventListener('pointerdown', onPointerDown);\n el.removeEventListener('pointermove', onPointerMove);\n el.removeEventListener('pointerup', onPointerUp);\n el.removeEventListener('pointercancel', onPointerCancel);\n el.removeEventListener('lostpointercapture', onLostCapture);\n };\n\n // Expose a way to update the captured index\n (el as any).__abUpdateIndex = (newIdx: number) => { currentIndex = newIdx; };\n\n return cleanup;\n }\n\n private rebindHandleIndex(entry: HandleEntry, newIndex: number): void {\n const fn = (entry.el as any).__abUpdateIndex;\n if (fn) fn(newIndex);\n entry.el.setAttribute('aria-label', `블록 ${newIndex + 1} 이동`);\n }\n\n private syncHandlePositions(): void {\n const parent = this.view.dom.parentNode as HTMLElement;\n const parentRect = parent.getBoundingClientRect();\n const editorRect = this.view.dom.getBoundingClientRect();\n const handleSize = parseInt(getComputedStyle(this.layer).getPropertyValue('--ab-dh-handle-size') || '22', 10);\n const handleLeft = editorRect.left - parentRect.left - handleSize - HANDLE_GAP;\n\n for (const entry of this.handles) {\n if (!entry) continue;\n const blockRect = entry.block.dom.getBoundingClientRect();\n const lineHeight = parseFloat(getComputedStyle(entry.block.dom).lineHeight) || 24;\n const verticalOffset = Math.max(0, (lineHeight - handleSize) / 2);\n const topPx = blockRect.top - parentRect.top + parent.scrollTop + verticalOffset;\n entry.topPx = topPx;\n entry.el.style.top = `${topPx}px`;\n entry.el.style.left = `${handleLeft}px`;\n }\n }\n\n // ── Private: drag lifecycle ──\n\n private startDrag(index: number, handle: HTMLElement, e: PointerEvent): void {\n const block = this.prevBlocks[index];\n if (!block) return;\n\n // Guard: clean up any existing drag first (e.g. multi-touch edge case)\n if (this.drag) {\n this.cleanupDragState();\n }\n\n this.drag = {\n fromIndex: index,\n handle,\n blockDom: block.dom,\n dropTargetIndex: index,\n pointerY: e.clientY,\n pointerId: e.pointerId,\n startX: e.clientX,\n startY: e.clientY,\n activated: false,\n };\n\n // Global fallback handlers: catch pointerup/pointercancel even when\n // pointer capture is lost or events don't reach the handle element\n this.addGlobalDragListeners(e.pointerId);\n }\n\n private activateDrag(): void {\n if (!this.drag) return;\n\n this.drag.activated = true;\n this.drag.handle.classList.add('dragging');\n this.drag.blockDom.classList.add('ab-block-dragging');\n\n // Create drop indicator\n const parent = this.view.dom.parentNode as HTMLElement;\n this.dropIndicator = document.createElement('div');\n this.dropIndicator.className = 'ab-drop-indicator';\n this.dropIndicator.style.display = 'none';\n parent.appendChild(this.dropIndicator);\n\n // Start auto-scroll loop\n this.tickAutoScroll();\n }\n\n private addGlobalDragListeners(pointerId: number): void {\n const onDocPointerUp = (e: PointerEvent) => {\n if (e.pointerId === pointerId) this.onPointerUp(e);\n };\n const onDocPointerCancel = (e: PointerEvent) => {\n if (e.pointerId === pointerId) this.cancelDrag();\n };\n const onVisibilityChange = () => {\n if (document.visibilityState === 'hidden') this.cancelDrag();\n };\n\n document.addEventListener('pointerup', onDocPointerUp);\n document.addEventListener('pointercancel', onDocPointerCancel);\n document.addEventListener('visibilitychange', onVisibilityChange);\n\n this.globalCleanup = () => {\n document.removeEventListener('pointerup', onDocPointerUp);\n document.removeEventListener('pointercancel', onDocPointerCancel);\n document.removeEventListener('visibilitychange', onVisibilityChange);\n };\n }\n\n private onPointerMove(e: PointerEvent): void {\n if (!this.drag || e.pointerId !== this.drag.pointerId) return;\n if (!this.view.editable) { this.cancelDrag(); return; }\n\n // Threshold check — only activate drag after moving 5px\n if (!this.drag.activated) {\n const dx = e.clientX - this.drag.startX;\n const dy = e.clientY - this.drag.startY;\n if (dx * dx + dy * dy < DRAG_THRESHOLD * DRAG_THRESHOLD) return;\n this.activateDrag();\n }\n\n this.drag.pointerY = e.clientY;\n this.updateDropTarget();\n }\n\n private updateDropTarget(): void {\n if (!this.drag || !this.dropIndicator) return;\n\n const parent = this.view.dom.parentNode as HTMLElement;\n const parentRect = parent.getBoundingClientRect();\n const editorRect = this.view.dom.getBoundingClientRect();\n\n // Build block rects relative to viewport\n const blockRects = this.prevBlocks.map(b => {\n const r = b.dom.getBoundingClientRect();\n return { top: r.top, bottom: r.bottom };\n });\n\n const targetIndex = findDropTarget(blockRects, this.drag.pointerY);\n this.drag.dropTargetIndex = targetIndex;\n\n // Compute indicator position\n let indicatorY: number;\n if (targetIndex === 0) {\n indicatorY = (blockRects[0]?.top ?? parentRect.top) - parentRect.top + parent.scrollTop - 1;\n } else if (targetIndex >= blockRects.length) {\n const last = blockRects[blockRects.length - 1];\n indicatorY = (last?.bottom ?? parentRect.bottom) - parentRect.top + parent.scrollTop + 1;\n } else {\n const above = blockRects[targetIndex - 1].bottom;\n const below = blockRects[targetIndex].top;\n indicatorY = ((above + below) / 2) - parentRect.top + parent.scrollTop;\n }\n\n // Hide when drop position equals source (no-op)\n const isSamePos = targetIndex === this.drag.fromIndex || targetIndex === this.drag.fromIndex + 1;\n this.dropIndicator.style.display = isSamePos ? 'none' : '';\n this.dropIndicator.style.top = `${indicatorY}px`;\n this.dropIndicator.style.left = `${editorRect.left - parentRect.left}px`;\n this.dropIndicator.style.width = `${editorRect.width}px`;\n }\n\n private onPointerUp(e: PointerEvent): void {\n if (!this.drag || e.pointerId !== this.drag.pointerId) return;\n\n // If threshold was never met, cancel without moving\n if (!this.drag.activated) {\n this.cleanupDragState();\n if (this.pendingUpdate) {\n this.pendingUpdate = false;\n this.scheduleUpdate();\n }\n return;\n }\n\n const fromIndex = this.drag.fromIndex;\n const toIndex = this.drag.dropTargetIndex;\n\n this.cleanupDragState();\n\n // Execute the move\n if (fromIndex !== toIndex && fromIndex + 1 !== toIndex) {\n const tr = buildMoveTransaction(this.view.state, fromIndex, toIndex);\n if (tr) {\n this.view.dispatch(tr.scrollIntoView());\n this.view.focus();\n this.flashMovedBlock(toIndex > fromIndex ? toIndex - 1 : toIndex);\n this.announce(`블록이 위치 ${(toIndex > fromIndex ? toIndex : toIndex + 1)}(으)로 이동됨`);\n }\n }\n\n // Flush pending update\n if (this.pendingUpdate) {\n this.pendingUpdate = false;\n this.scheduleUpdate();\n }\n }\n\n cancelDrag(): void {\n if (!this.drag) return;\n this.cleanupDragState();\n\n if (this.pendingUpdate) {\n this.pendingUpdate = false;\n this.scheduleUpdate();\n }\n }\n\n private cleaningUp = false;\n\n private cleanupDragState(): void {\n if (!this.drag || this.cleaningUp) return;\n this.cleaningUp = true;\n\n this.drag.handle.classList.remove('dragging');\n this.drag.blockDom.classList.remove('ab-block-dragging');\n\n // Try to release pointer capture (may already be released).\n // releasePointerCapture can fire lostpointercapture synchronously,\n // so the cleaningUp guard prevents re-entrant calls.\n try {\n this.drag.handle.releasePointerCapture(this.drag.pointerId);\n } catch { /* already released */ }\n\n this.dropIndicator?.remove();\n this.dropIndicator = null;\n\n // Remove global fallback listeners\n if (this.globalCleanup) {\n this.globalCleanup();\n this.globalCleanup = null;\n }\n\n if (this.scrollRAF !== null) {\n cancelAnimationFrame(this.scrollRAF);\n this.scrollRAF = null;\n }\n\n this.drag = null;\n this.cleaningUp = false;\n // Restore hover state based on actual pointer position\n delete this.layer.dataset.hover;\n }\n\n // ── Private: auto-scroll ──\n\n private tickAutoScroll(): void {\n if (!this.drag) return;\n\n const rect = this.scrollContainer.getBoundingClientRect();\n const speed = computeAutoScrollSpeed(this.drag.pointerY, rect.top, rect.bottom);\n\n if (speed !== 0) {\n this.scrollContainer.scrollBy(0, speed);\n this.syncHandlePositions();\n this.updateDropTarget();\n }\n\n this.scrollRAF = requestAnimationFrame(() => this.tickAutoScroll());\n }\n\n private findScrollContainer(el: HTMLElement): HTMLElement {\n let current = el.parentElement;\n while (current) {\n const overflow = getComputedStyle(current).overflowY;\n if (overflow === 'auto' || overflow === 'scroll') return current;\n current = current.parentElement;\n }\n return el.parentElement ?? el;\n }\n\n // ── Private: feedback ──\n\n private flashMovedBlock(blockIndex: number): void {\n // Re-collect after transaction so we get the new DOM\n requestAnimationFrame(() => {\n const blocks = this.collectBlocks();\n const block = blocks[blockIndex];\n if (!block) return;\n block.dom.classList.add('ab-block-just-moved');\n const onEnd = () => {\n block.dom.classList.remove('ab-block-just-moved');\n block.dom.removeEventListener('animationend', onEnd);\n };\n block.dom.addEventListener('animationend', onEnd);\n });\n }\n\n private announce(message: string): void {\n this.liveRegion.textContent = '';\n // Force screen reader to re-read by clearing then setting\n requestAnimationFrame(() => {\n this.liveRegion.textContent = message;\n });\n }\n}\n\n// ────────────────────────────────────────────────────────────\n// Keyboard commands\n// ────────────────────────────────────────────────────────────\n\nfunction moveBlockCommand(direction: -1 | 1): Command {\n return (state, dispatch) => {\n const $from = state.selection.$from;\n // Resolve to top-level block\n const blockIndex = $from.index(0);\n const toIndex = direction === -1 ? blockIndex - 1 : blockIndex + 2;\n\n if (toIndex < 0 || toIndex > state.doc.childCount) return false;\n\n if (dispatch) {\n const tr = buildMoveTransaction(state, blockIndex, toIndex);\n if (tr) {\n dispatch(tr.scrollIntoView());\n } else {\n return false;\n }\n }\n return true;\n };\n}\n\n// ────────────────────────────────────────────────────────────\n// Plugin factory (public API — unchanged signature)\n// ────────────────────────────────────────────────────────────\n\nexport function createDragHandlePlugin(): ActionbookPlugin {\n return {\n name: 'dragHandle',\n\n plugins: () => {\n let controller: DragHandleController | null = null;\n\n return [\n new Plugin({\n key: PLUGIN_KEY,\n view(editorView) {\n controller = new DragHandleController(editorView);\n return {\n update(view, prevState) {\n controller?.update(view, prevState);\n },\n destroy() {\n controller?.destroy();\n controller = null;\n },\n };\n },\n }),\n ];\n },\n\n keymap: () => ({\n 'Alt-ArrowUp': moveBlockCommand(-1),\n 'Alt-ArrowDown': moveBlockCommand(1),\n }),\n };\n}\n","/**\n * NodeView plugin for todo/checkbox list items.\n * Renders a clickable checkbox when listItem.attrs.checked !== null.\n */\nimport React from 'react';\nimport type { NodeView, EditorView } from 'prosemirror-view';\nimport type { Node as PMNode } from 'prosemirror-model';\nimport type { ActionbookPlugin, NodeViewFactory } from './types';\n\nfunction createCheckboxDOM(checked: boolean): HTMLElement {\n const el = document.createElement('span');\n el.contentEditable = 'false';\n el.style.cssText = `\n display: inline-flex; align-items: center; justify-content: center;\n width: 18px; height: 18px; margin-right: 6px;\n cursor: pointer; border-radius: 4px;\n user-select: none; flex-shrink: 0; vertical-align: middle;\n position: relative; top: -1px; font-size: 12px; font-weight: 700;\n ${checked\n ? 'background: #6366f1; color: #fff; border: none;'\n : 'background: transparent; color: transparent; border: 2px solid #d1d5db;'\n }\n `;\n el.textContent = checked ? '✓' : '';\n return el;\n}\n\nclass TodoListItemView implements NodeView {\n dom: HTMLElement;\n contentDOM: HTMLElement;\n private checkbox: HTMLElement;\n\n constructor(\n private node: PMNode,\n private view: EditorView,\n private getPos: () => number | undefined,\n ) {\n const checked = node.attrs.checked as boolean;\n\n this.dom = document.createElement('li');\n this.dom.className = 'todo-item';\n this.dom.dataset.checked = String(checked);\n this.dom.style.display = 'flex';\n this.dom.style.alignItems = 'flex-start';\n\n this.checkbox = createCheckboxDOM(checked);\n this.checkbox.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n const pos = this.getPos();\n if (pos == null) return;\n this.view.dispatch(\n this.view.state.tr.setNodeMarkup(pos, undefined, {\n ...this.node.attrs,\n checked: !this.node.attrs.checked,\n }),\n );\n });\n\n this.contentDOM = document.createElement('div');\n this.contentDOM.style.flex = '1';\n if (checked) {\n this.contentDOM.style.textDecoration = 'line-through';\n this.contentDOM.style.opacity = '0.6';\n }\n\n this.dom.appendChild(this.checkbox);\n this.dom.appendChild(this.contentDOM);\n }\n\n update(node: PMNode): boolean {\n if (node.type !== this.node.type) return false;\n // If checked changed from/to null, refuse update (different rendering)\n if ((node.attrs.checked == null) !== (this.node.attrs.checked == null)) return false;\n if (node.attrs.checked == null) return false;\n\n this.node = node;\n const checked = node.attrs.checked as boolean;\n this.dom.dataset.checked = String(checked);\n\n // Update checkbox\n const newCb = createCheckboxDOM(checked);\n newCb.addEventListener('mousedown', (e) => {\n e.preventDefault();\n e.stopPropagation();\n const pos = this.getPos();\n if (pos == null) return;\n this.view.dispatch(\n this.view.state.tr.setNodeMarkup(pos, undefined, {\n ...this.node.attrs,\n checked: !this.node.attrs.checked,\n }),\n );\n });\n this.dom.replaceChild(newCb, this.checkbox);\n this.checkbox = newCb;\n\n // Update content styling\n if (checked) {\n this.contentDOM.style.textDecoration = 'line-through';\n this.contentDOM.style.opacity = '0.6';\n } else {\n this.contentDOM.style.textDecoration = '';\n this.contentDOM.style.opacity = '';\n }\n\n return true;\n }\n}\n\nexport function createTodoNodeViewPlugin(): ActionbookPlugin {\n return {\n name: 'todoNodeView',\n nodeViews: () => ({\n listItem: ((node: PMNode, view: EditorView, getPos: () => number | undefined): NodeView => {\n // Only use custom node view for todo items (checked !== null)\n if (node.attrs.checked == null) {\n // Return default node view\n const li = document.createElement('li');\n return { dom: li, contentDOM: li };\n }\n return new TodoListItemView(node, view, getPos);\n }) as NodeViewFactory,\n }),\n };\n}\n","/**\n * Slash-command trigger plugin.\n *\n * Tracks whether the cursor is inside a `/query` pattern and exposes the\n * active range + query string via `slashCommandKey` so that the\n * `SlashCommandMenu` React component can read it and render the popup.\n *\n * The plugin also handles:\n * - Escape → dismisses the menu (sets dismissed state so the same `/`\n * position doesn't re-trigger until the user moves away and types `/` again)\n * - ArrowUp / ArrowDown / Enter → consumed by the React component through\n * a capture-phase keydown listener; the plugin just marks them as handled\n * when the menu is active so ProseMirror doesn't move the cursor.\n */\n\nimport { Plugin, PluginKey } from 'prosemirror-state';\nimport type { EditorState, Transaction } from 'prosemirror-state';\nimport type { ActionbookPlugin } from './types';\n\n// ── Public types ──────────────────────────────────────────\n\nexport interface SlashCommandState {\n /** Whether a slash trigger is currently active. */\n active: boolean;\n /** Document positions of the full `/query` text (inclusive). */\n range: { from: number; to: number } | null;\n /** Text typed after `/`, not including the slash itself. */\n query: string;\n}\n\n// ── Plugin key (exported so SlashCommandMenu can read state) ──\n\nexport const slashCommandKey = new PluginKey<SlashCommandState>('slashCommand');\n\n// ── Internal helpers ──────────────────────────────────────\n\n/**\n * Regex matching `/` followed by zero-or-more non-whitespace chars at the\n * end of the current paragraph text up to the cursor.\n *\n * Allows the trigger at the very start of the line or after whitespace,\n * but not inside a word (e.g. `foo/bar` should NOT trigger).\n */\nconst TRIGGER_RE = /(?:^|\\s)(\\/[^\\s]*)$/;\n\n/** Derive slash-command state purely from editor state + dismissed position. */\nfunction deriveState(\n state: EditorState,\n dismissedFrom: number | null,\n): SlashCommandState {\n const { selection } = state;\n if (!selection.empty) return { active: false, range: null, query: '' };\n\n const { $from } = selection;\n // Only trigger in paragraph-like blocks (not headings etc.)\n const parentType = $from.parent.type.name;\n if (parentType === 'heading') return { active: false, range: null, query: '' };\n\n const textBefore = $from.parent.textBetween(0, $from.parentOffset, '\\n', '\\0');\n const match = TRIGGER_RE.exec(textBefore);\n if (!match) return { active: false, range: null, query: '' };\n\n const slashText = match[1]; // e.g. '/foo'\n const slashStartInParent = textBefore.lastIndexOf(slashText);\n const from = $from.start() + slashStartInParent;\n const to = $from.pos;\n\n // If the user dismissed at this exact slash position, stay inactive\n if (dismissedFrom === from) return { active: false, range: null, query: '' };\n\n return {\n active: true,\n range: { from, to },\n query: slashText.slice(1),\n };\n}\n\n// ── Meta shape ────────────────────────────────────────────\n\ninterface SlashMeta {\n /** Position of the slash that was dismissed (Escape key). */\n dismiss?: number;\n}\n\n// ── Internal plugin state (extends public state with dismiss tracking) ──\n\ninterface InternalState extends SlashCommandState {\n _dismissedFrom: number | null;\n}\n\n// ── Factory ───────────────────────────────────────────────\n\nexport function createSlashCommandPlugin(): ActionbookPlugin {\n const plugin = new Plugin<InternalState>({\n key: slashCommandKey as unknown as PluginKey<InternalState>,\n\n state: {\n init(_, state): InternalState {\n const derived = deriveState(state, null);\n return { ...derived, _dismissedFrom: null };\n },\n\n apply(tr: Transaction, prev: InternalState, _old, newState: EditorState): InternalState {\n const meta = tr.getMeta(slashCommandKey) as SlashMeta | undefined;\n\n let dismissedFrom = prev._dismissedFrom;\n\n if (meta?.dismiss !== undefined) {\n dismissedFrom = meta.dismiss;\n } else if (dismissedFrom !== null) {\n // Clear dismiss if the user typed a new `/` somewhere else\n const derived = deriveState(newState, null);\n if (derived.active && derived.range && derived.range.from !== dismissedFrom) {\n dismissedFrom = null;\n }\n }\n\n const derived = deriveState(newState, dismissedFrom);\n return { ...derived, _dismissedFrom: dismissedFrom };\n },\n },\n\n // Expose only the public fields via the key\n // (InternalState is a superset of SlashCommandState so reads work fine)\n });\n\n return {\n name: 'slashCommand',\n plugins: () => [plugin],\n\n keymap: () => ({\n Escape: (state, dispatch) => {\n const s = slashCommandKey.getState(state) as InternalState | undefined;\n if (!s?.active || !s.range) return false;\n\n // Dismiss: store the slash position so it won't re-trigger\n if (dispatch) {\n const tr = state.tr;\n tr.setMeta(slashCommandKey, { dismiss: s.range.from } satisfies SlashMeta);\n dispatch(tr);\n }\n return true;\n },\n }),\n };\n}\n","/**\n * SlashCommandMenu — injectable floating slash-command picker.\n *\n * Usage:\n * ```tsx\n * // Define items (inject from outside)\n * const items: SlashCommandItem[] = [\n * {\n * id: 'heading1',\n * title: 'Heading 1',\n * description: 'Large section heading',\n * icon: <span>H1</span>,\n * command({ view, range }) {\n * const { state, dispatch } = view;\n * const tr = state.tr.delete(range.from, range.to);\n * setBlockType(heading, { level: 1 })(\n * state.apply(tr),\n * (newTr) => dispatch(tr.steps.length ? tr : newTr),\n * );\n * },\n * },\n * ];\n *\n * // In your editor component:\n * const [editorState, setEditorState] = useState<EditorState | null>(null);\n * const handle = useEditorView({ ..., onTransaction: setEditorState });\n *\n * return (\n * <>\n * <EditorShell ref={handle.viewRef} />\n * <SlashCommandMenu\n * view={handle.view}\n * editorState={editorState}\n * items={items}\n * />\n * </>\n * );\n * ```\n *\n * The `command` callback receives the editor view and the range of the\n * `/query` trigger text. It is responsible for deleting the trigger and\n * inserting whatever content it wants.\n */\n\nimport React, { useEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport type { EditorView } from 'prosemirror-view';\nimport type { EditorState } from 'prosemirror-state';\nimport { slashCommandKey } from '../plugin/slashCommandPlugin';\nimport type { SlashCommandState } from '../plugin/slashCommandPlugin';\n\n// ── Public types ──────────────────────────────────────────\n\nexport interface SlashCommandItem {\n /** Unique key; falls back to `title` if omitted. */\n id?: string;\n title: string;\n description?: string;\n /** Optional icon node rendered to the left of the title. */\n icon?: React.ReactNode;\n /**\n * Execute this command.\n *\n * @param view - Live EditorView; use `view.state` / `view.dispatch`.\n * @param range - Positions of the full `/query` text in the document.\n * Delete this range before inserting your content.\n */\n command: (props: { view: EditorView; range: { from: number; to: number } }) => void;\n}\n\nexport interface SlashCommandMenuProps {\n view: EditorView | null;\n editorState: EditorState | null;\n /** Full item list. Filtered by the current query automatically. */\n items: SlashCommandItem[];\n}\n\n// ── Filtering ─────────────────────────────────────────────\n\nfunction filterItems(items: SlashCommandItem[], query: string): SlashCommandItem[] {\n if (!query) return items;\n const q = query.toLowerCase();\n return items.filter(\n ({ title, description }) =>\n title.toLowerCase().includes(q) ||\n (description?.toLowerCase().includes(q) ?? false),\n );\n}\n\n// ── Shared styles ─────────────────────────────────────────\n\nconst POPUP_SHADOW =\n '0 0 0 1px rgba(0,0,0,0.07), 0 4px 20px rgba(0,0,0,0.11), 0 1px 4px rgba(0,0,0,0.05)';\n\nconst BTN_RESET: React.CSSProperties = {\n border: 'none',\n padding: 0,\n margin: 0,\n background: 'transparent',\n fontFamily: 'inherit',\n cursor: 'pointer',\n lineHeight: 1,\n textAlign: 'left',\n width: '100%',\n};\n\nconst VPORT_MARGIN = 8;\nconst MENU_WIDTH = 280;\nconst MAX_MENU_H = 320;\n\n// ── Menu component ────────────────────────────────────────\n\nexport function SlashCommandMenu({ view, editorState, items }: SlashCommandMenuProps) {\n const [selectedIndex, setSelectedIndex] = useState(0);\n const listRef = useRef<HTMLDivElement>(null);\n\n // Read plugin state\n const pluginState = editorState\n ? (slashCommandKey.getState(editorState) as SlashCommandState | undefined)\n : undefined;\n\n const active = pluginState?.active ?? false;\n const range = pluginState?.range ?? null;\n const query = pluginState?.query ?? '';\n\n const filtered = filterItems(items, query);\n\n // Reset selection when query or active state changes\n useEffect(() => {\n setSelectedIndex(0);\n }, [query, active]);\n\n // Scroll selected item into view\n useEffect(() => {\n const list = listRef.current;\n if (!list) return;\n const item = list.children[selectedIndex] as HTMLElement | undefined;\n item?.scrollIntoView({ block: 'nearest' });\n }, [selectedIndex]);\n\n // Keyboard handler — captures Arrow/Enter before ProseMirror sees them\n useEffect(() => {\n if (!active || !view) return;\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n e.stopPropagation();\n setSelectedIndex((i) => Math.min(i + 1, filtered.length - 1));\n return;\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n e.stopPropagation();\n setSelectedIndex((i) => Math.max(i - 1, 0));\n return;\n }\n if (e.key === 'Enter') {\n e.preventDefault();\n e.stopPropagation();\n if (filtered[selectedIndex] && range) {\n filtered[selectedIndex].command({ view, range });\n view.focus();\n }\n }\n };\n\n document.addEventListener('keydown', onKeyDown, true);\n return () => document.removeEventListener('keydown', onKeyDown, true);\n }, [active, view, filtered, selectedIndex, range]);\n\n if (!active || !view || !range) return null;\n\n // Position below the slash trigger character\n const coords = view.coordsAtPos(range.from);\n let top = coords.bottom + 4;\n let left = coords.left;\n\n // Clamp to viewport\n left = Math.max(VPORT_MARGIN, Math.min(left, window.innerWidth - MENU_WIDTH - VPORT_MARGIN));\n if (top + MAX_MENU_H > window.innerHeight - VPORT_MARGIN) {\n top = coords.top - MAX_MENU_H - 4;\n }\n\n return createPortal(\n <div\n style={{\n position: 'fixed',\n top,\n left,\n width: MENU_WIDTH,\n maxHeight: MAX_MENU_H,\n overflowY: 'auto',\n background: '#fff',\n borderRadius: 10,\n boxShadow: POPUP_SHADOW,\n padding: 6,\n zIndex: 1100,\n animation: 'ab-float-in 0.12s ease',\n }}\n >\n <div ref={listRef}>\n {filtered.length === 0 ? (\n <div\n style={{\n padding: '8px 12px',\n fontSize: 13,\n color: '#9ca3af',\n }}\n >\n No results\n </div>\n ) : (\n filtered.map((item, i) => (\n <SlashMenuItem\n key={item.id ?? item.title}\n item={item}\n selected={i === selectedIndex}\n onMouseEnter={() => setSelectedIndex(i)}\n onMouseDown={(e) => {\n e.preventDefault();\n if (range) {\n item.command({ view, range });\n view.focus();\n }\n }}\n />\n ))\n )}\n </div>\n </div>,\n document.body,\n );\n}\n\n// ── SlashMenuItem ─────────────────────────────────────────\n\ninterface SlashMenuItemProps {\n item: SlashCommandItem;\n selected: boolean;\n onMouseEnter: () => void;\n onMouseDown: (e: React.MouseEvent) => void;\n}\n\nfunction SlashMenuItem({ item, selected, onMouseEnter, onMouseDown }: SlashMenuItemProps) {\n return (\n <button\n style={{\n ...BTN_RESET,\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n padding: '7px 10px',\n borderRadius: 7,\n background: selected ? 'rgba(99,102,241,0.07)' : 'transparent',\n transition: 'background 0.08s',\n }}\n onMouseEnter={onMouseEnter}\n onMouseDown={onMouseDown}\n >\n {/* Icon */}\n {item.icon !== undefined && (\n <span\n style={{\n width: 28,\n height: 28,\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 6,\n background: 'rgba(0,0,0,0.04)',\n fontSize: 13,\n fontWeight: 700,\n color: '#6366f1',\n fontFamily: 'monospace',\n }}\n >\n {item.icon}\n </span>\n )}\n\n {/* Text */}\n <span style={{ display: 'flex', flexDirection: 'column', gap: 1, minWidth: 0 }}>\n <span\n style={{\n fontSize: 13,\n fontWeight: 500,\n color: '#171717',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {item.title}\n </span>\n {item.description && (\n <span\n style={{\n fontSize: 11,\n color: '#9ca3af',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {item.description}\n </span>\n )}\n </span>\n </button>\n );\n}\n","import React, { useState, type ReactElement } from 'react';\nimport type { DocumentNode } from '../../ast/types';\nimport { textContent } from '../../ast/traverse';\nimport { analyzeJinjaBlocks, type JinjaVisualStructure, type JinjaVisualBranch } from '../../jinja/analyzer';\n\nexport interface JinjaTreeViewProps {\n doc: DocumentNode;\n className?: string;\n}\n\nconst BRANCH_COLORS: Record<string, string> = {\n if: '#6366f1',\n elif: '#f59e0b',\n else: '#8b5cf6',\n};\n\nfunction getBlockPreview(doc: DocumentNode, startIdx: number, endIdx: number): string {\n const blocks = doc.content.slice(startIdx, endIdx);\n const text = blocks.map((b) => textContent(b)).join(' ').trim();\n return text.length > 40 ? text.slice(0, 40) + '...' : text;\n}\n\nfunction BranchNode({\n branch,\n doc,\n isLast,\n}: {\n branch: JinjaVisualBranch;\n doc: DocumentNode;\n isLast: boolean;\n}): ReactElement {\n const color = BRANCH_COLORS[branch.type] || '#6366f1';\n const blockCount = branch.blockEndIndex - branch.blockStartIndex;\n const preview = getBlockPreview(doc, branch.blockStartIndex, branch.blockEndIndex);\n const connector = isLast ? '\\u2514\\u2500' : '\\u251C\\u2500';\n\n return (\n <div className=\"jinja-tree-branch\">\n <span className=\"jinja-tree-connector\">{connector} </span>\n <span className=\"jinja-tree-badge\" style={{ color, borderColor: color }}>\n [{branch.type}]\n </span>\n {branch.condition && (\n <span className=\"jinja-tree-condition\"> {branch.condition}</span>\n )}\n <span className=\"jinja-tree-meta\">\n {' '}{blockCount} block{blockCount !== 1 ? 's' : ''}\n {preview && `: \"${preview}\"`}\n </span>\n </div>\n );\n}\n\nfunction StructureNode({ structure, doc }: { structure: JinjaVisualStructure; doc: DocumentNode }): ReactElement {\n const [expanded, setExpanded] = useState(true);\n const firstBranch = structure.branches[0];\n const label = firstBranch?.condition ? `if ${firstBranch.condition}` : 'if';\n\n return (\n <div className=\"jinja-tree-structure\">\n <button\n className=\"jinja-tree-toggle\"\n onClick={() => setExpanded(!expanded)}\n type=\"button\"\n >\n <span className=\"jinja-tree-arrow\">{expanded ? '\\u25BC' : '\\u25B6'}</span>\n <span className=\"jinja-tree-label\">{label}</span>\n </button>\n {expanded && (\n <div className=\"jinja-tree-branches\">\n {structure.branches.map((branch, i) => (\n <BranchNode\n key={`${structure.id}-${i}`}\n branch={branch}\n doc={doc}\n isLast={i === structure.branches.length - 1}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nexport function JinjaTreeView({ doc, className }: JinjaTreeViewProps): ReactElement | null {\n const structures = analyzeJinjaBlocks(doc);\n if (structures.length === 0) return null;\n\n return (\n <div className={`jinja-tree ${className || ''}`}>\n {structures.map((structure) => (\n <StructureNode key={structure.id} structure={structure} doc={doc} />\n ))}\n </div>\n );\n}\n","/**\n * Floating UI for the Actionbook editor.\n *\n * Two interaction patterns:\n *\n * 1. SelectionToolbar — appears above a non-empty text selection.\n * Buttons: Bold · Italic · Underline · Strikethrough · Code · Link · ─ · Block type ▾\n *\n * 2. EmptyParaHandle — appears to the left of an empty paragraph/heading\n * after the cursor has dwelled there for DWELL_MS (600 ms).\n * A small \"+\" button opens a block-type picker menu.\n *\n * Both are rendered into document.body via React portals so they never\n * get clipped by overflow:hidden ancestors.\n */\n\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport type { EditorView } from 'prosemirror-view';\nimport type { EditorState } from 'prosemirror-state';\nimport { setBlockType, toggleMark, wrapIn } from 'prosemirror-commands';\nimport { wrapInList } from 'prosemirror-schema-list';\nimport { actionbookSchema } from '../schema';\n\n// ── Schema refs ───────────────────────────────────────────\n\nconst { paragraph, heading, bulletList, orderedList, blockquote } = actionbookSchema.nodes;\nconst {\n bold,\n italic,\n underline,\n strikethrough,\n code,\n link: linkMark,\n} = actionbookSchema.marks;\n\n// ── Constants ─────────────────────────────────────────────\n\nconst DWELL_MS = 600;\nconst TOOLBAR_H = 36;\nconst TOOLBAR_GAP = 8;\nconst VPORT_MARGIN = 8;\n// attribute used to detect clicks inside any floating element\nconst FLOAT_ATTR = 'data-ab-float';\n\n// ── Editor state helpers ──────────────────────────────────\n\nfunction hasMark(state: EditorState, type: typeof bold): boolean {\n const { from, to, empty } = state.selection;\n if (empty) return false;\n return state.doc.rangeHasMark(from, to, type);\n}\n\nfunction activeHeadingLevel(state: EditorState): number | null {\n const { $from } = state.selection;\n const node = $from.parent;\n if (node.type === heading) return node.attrs.level as number;\n return null;\n}\n\n/** Returns 'bullet' | 'ordered' | null depending on whether the cursor is inside a list. */\nfunction activeListType(state: EditorState): 'bullet' | 'ordered' | null {\n const { $from } = state.selection;\n for (let d = $from.depth; d > 0; d--) {\n const t = $from.node(d).type;\n if (t === bulletList) return 'bullet';\n if (t === orderedList) return 'ordered';\n }\n return null;\n}\n\n/** Convert the nearest ancestor list to `toType`. */\nfunction convertList(\n state: EditorState,\n dispatch: EditorView['dispatch'] | undefined,\n toType: typeof bulletList | typeof orderedList,\n): boolean {\n const { $from } = state.selection;\n for (let d = $from.depth; d > 0; d--) {\n const node = $from.node(d);\n if (node.type === bulletList || node.type === orderedList) {\n if (node.type === toType) return false;\n if (dispatch) {\n dispatch(state.tr.setNodeMarkup($from.before(d), toType, node.attrs));\n }\n return true;\n }\n }\n return false;\n}\n\nfunction currentBlockLabel(state: EditorState): string {\n const hl = activeHeadingLevel(state);\n if (hl) return `H${hl}`;\n const lt = activeListType(state);\n if (lt === 'bullet') return '• List';\n if (lt === 'ordered') return '1. List';\n const { $from } = state.selection;\n for (let d = $from.depth; d > 0; d--) {\n if ($from.node(d).type === blockquote) return 'Quote';\n }\n return 'Text';\n}\n\nfunction emptyBlockCursorPos(state: EditorState): number | null {\n const { selection } = state;\n if (!selection.empty) return null;\n const { $from } = selection;\n const parent = $from.parent;\n if (\n (parent.type === paragraph || parent.type === heading) &&\n parent.content.size === 0\n ) {\n return selection.from;\n }\n return null;\n}\n\n/** Get the bounding rect of the current DOM selection (viewport-relative). */\nfunction getSelectionDOMRect(): DOMRect | null {\n const sel = window.getSelection();\n if (!sel || sel.rangeCount === 0 || sel.isCollapsed) return null;\n const rect = sel.getRangeAt(0).getBoundingClientRect();\n if (rect.width === 0 && rect.height === 0) return null;\n return rect;\n}\n\n// ── Shared styles ─────────────────────────────────────────\n\nconst POPUP_SHADOW =\n '0 0 0 1px rgba(0,0,0,0.07), 0 4px 20px rgba(0,0,0,0.11), 0 1px 4px rgba(0,0,0,0.05)';\n\nconst BTN_RESET: React.CSSProperties = {\n border: 'none',\n padding: 0,\n background: 'transparent',\n fontFamily: 'inherit',\n cursor: 'pointer',\n lineHeight: 1,\n};\n\n// ── ToolbarButton ─────────────────────────────────────────\n\ninterface TBtnProps {\n children: React.ReactNode;\n active?: boolean;\n title?: string;\n onMouseDown: (e: React.MouseEvent) => void;\n style?: React.CSSProperties;\n}\n\nfunction TBtn({ children, active, title, onMouseDown, style }: TBtnProps) {\n const [hover, setHover] = useState(false);\n return (\n <button\n {...{ [FLOAT_ATTR]: '' }}\n title={title}\n onMouseDown={(e) => { e.preventDefault(); onMouseDown(e); }}\n onMouseEnter={() => setHover(true)}\n onMouseLeave={() => setHover(false)}\n style={{\n ...BTN_RESET,\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n width: 28, height: 28, borderRadius: 6,\n fontSize: 13, fontWeight: 600, color: active ? '#6366f1' : '#3f3f46',\n background: active\n ? 'rgba(99,102,241,0.1)'\n : hover ? 'rgba(0,0,0,0.05)' : 'transparent',\n transition: 'background 0.1s, color 0.1s',\n ...style,\n }}\n >\n {children}\n </button>\n );\n}\n\n// ── Divider ───────────────────────────────────────────────\n\nfunction Divider() {\n return (\n <div style={{ width: 1, height: 18, background: 'rgba(0,0,0,0.07)', margin: '0 2px', flexShrink: 0 }} />\n );\n}\n\n// ── BlockTypeDropdown ─────────────────────────────────────\n\ninterface BlockTypeDropdownProps {\n view: EditorView;\n state: EditorState;\n label: string;\n}\n\nfunction BlockTypeDropdown({ view, state, label }: BlockTypeDropdownProps) {\n const [open, setOpen] = useState(false);\n const btnRef = useRef<HTMLButtonElement>(null);\n const [hover, setHover] = useState(false);\n\n useEffect(() => {\n if (!open) return;\n const onDown = (e: MouseEvent) => {\n if (!(e.target as HTMLElement).closest(`[${FLOAT_ATTR}]`)) {\n setOpen(false);\n }\n };\n document.addEventListener('mousedown', onDown, true);\n return () => document.removeEventListener('mousedown', onDown, true);\n }, [open]);\n\n const headingLevel = activeHeadingLevel(state);\n const listType = activeListType(state);\n\n const items: { label: string; shortLabel: string; active: boolean; run: () => void }[] = [\n { label: 'Text', shortLabel: '¶', active: !headingLevel && !listType, run: () => { setBlockType(paragraph)(view.state, view.dispatch); view.focus(); } },\n { label: 'Heading 1', shortLabel: 'H1', active: headingLevel === 1, run: () => { setBlockType(heading, { level: 1 })(view.state, view.dispatch); view.focus(); } },\n { label: 'Heading 2', shortLabel: 'H2', active: headingLevel === 2, run: () => { setBlockType(heading, { level: 2 })(view.state, view.dispatch); view.focus(); } },\n { label: 'Heading 3', shortLabel: 'H3', active: headingLevel === 3, run: () => { setBlockType(heading, { level: 3 })(view.state, view.dispatch); view.focus(); } },\n { label: 'Bullet List', shortLabel: '•', active: listType === 'bullet', run: () => {\n if (listType === 'bullet') return;\n if (listType === 'ordered') { convertList(view.state, view.dispatch, bulletList); }\n else { wrapInList(bulletList)(view.state, view.dispatch); }\n view.focus();\n }},\n { label: 'Ordered List', shortLabel: '1.', active: listType === 'ordered', run: () => {\n if (listType === 'ordered') return;\n if (listType === 'bullet') { convertList(view.state, view.dispatch, orderedList); }\n else { wrapInList(orderedList)(view.state, view.dispatch); }\n view.focus();\n }},\n { label: 'Quote', shortLabel: '>', active: false, run: () => { wrapIn(blockquote)(view.state, view.dispatch); view.focus(); } },\n ];\n\n const btnRect = btnRef.current?.getBoundingClientRect();\n\n return (\n <>\n <button\n ref={btnRef}\n {...{ [FLOAT_ATTR]: '' }}\n onMouseDown={(e) => { e.preventDefault(); setOpen((v) => !v); }}\n onMouseEnter={() => setHover(true)}\n onMouseLeave={() => setHover(false)}\n style={{\n ...BTN_RESET,\n display: 'flex', alignItems: 'center', gap: 3,\n height: 28, padding: '0 6px', borderRadius: 6,\n fontSize: 11, fontWeight: 600, color: open ? '#6366f1' : '#3f3f46',\n background: open ? 'rgba(99,102,241,0.1)' : hover ? 'rgba(0,0,0,0.05)' : 'transparent',\n transition: 'background 0.1s, color 0.1s',\n whiteSpace: 'nowrap',\n }}\n >\n {label}\n <span style={{ fontSize: 8, opacity: 0.6 }}>▾</span>\n </button>\n {open && btnRect && createPortal(\n <div\n {...{ [FLOAT_ATTR]: '' }}\n style={{\n position: 'fixed', zIndex: 1001,\n left: btnRect.left, top: btnRect.bottom + 4,\n background: '#fff', borderRadius: 10, boxShadow: POPUP_SHADOW,\n padding: 6, minWidth: 168,\n animation: 'ab-float-in 0.12s ease',\n }}\n >\n {items.map((item) => (\n <DropdownItem key={item.label} item={item} onRun={() => setOpen(false)} />\n ))}\n </div>,\n document.body,\n )}\n </>\n );\n}\n\nfunction DropdownItem({ item, onRun }: { item: { label: string; shortLabel: string; active: boolean; run: () => void }; onRun: () => void }) {\n const [hover, setHover] = useState(false);\n return (\n <button\n {...{ [FLOAT_ATTR]: '' }}\n onMouseDown={(e) => { e.preventDefault(); item.run(); onRun(); }}\n onMouseEnter={() => setHover(true)}\n onMouseLeave={() => setHover(false)}\n style={{\n ...BTN_RESET,\n display: 'flex', alignItems: 'center', gap: 10,\n width: '100%', padding: '6px 8px',\n borderRadius: 6, textAlign: 'left',\n fontSize: 13, color: item.active ? '#6366f1' : '#3f3f46',\n fontWeight: item.active ? 600 : 400,\n background: hover ? 'rgba(0,0,0,0.04)' : 'transparent',\n transition: 'background 0.1s',\n }}\n >\n <span style={{ width: 24, flexShrink: 0, textAlign: 'center', fontWeight: 700, fontSize: 12, fontFamily: 'monospace', color: '#6366f1' }}>\n {item.shortLabel}\n </span>\n {item.label}\n </button>\n );\n}\n\n// ── SelectionToolbar ──────────────────────────────────────\n\ninterface SelectionToolbarProps {\n view: EditorView;\n state: EditorState;\n selectionRect: DOMRect;\n}\n\nfunction SelectionToolbar({ view, state, selectionRect }: SelectionToolbarProps) {\n const [linkMode, setLinkMode] = useState(false);\n const [linkHref, setLinkHref] = useState('');\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Derived state\n const isBold = hasMark(state, bold);\n const isItalic = hasMark(state, italic);\n const isUnderline = hasMark(state, underline);\n const isStrike = hasMark(state, strikethrough);\n const isCode = hasMark(state, code);\n const isLink = hasMark(state, linkMark);\n const blockLabel = currentBlockLabel(state);\n\n const toolbarW = linkMode ? 300 : 380;\n const toolbarH = TOOLBAR_H;\n\n let left = selectionRect.left + selectionRect.width / 2 - toolbarW / 2;\n let top = selectionRect.top - toolbarH - TOOLBAR_GAP;\n // Flip below selection when there's no space above\n if (top < VPORT_MARGIN) top = selectionRect.bottom + TOOLBAR_GAP;\n // Clamp to viewport\n left = Math.max(VPORT_MARGIN, Math.min(left, window.innerWidth - toolbarW - VPORT_MARGIN));\n top = Math.max(VPORT_MARGIN, Math.min(top, window.innerHeight - toolbarH - VPORT_MARGIN));\n\n const run = useCallback(\n (cmd: (s: EditorState, d?: typeof view.dispatch) => boolean) => {\n cmd(view.state, view.dispatch);\n view.focus();\n },\n [view],\n );\n\n const openLinkInput = () => {\n // Pre-fill with the first href found in the selection (if any)\n const { from, to } = view.state.selection;\n let existingHref = '';\n view.state.doc.nodesBetween(from, to, (node) => {\n if (!existingHref) {\n const lm = node.marks.find((m) => m.type === linkMark);\n if (lm) existingHref = lm.attrs.href as string;\n }\n });\n setLinkHref(existingHref);\n setLinkMode(true);\n setTimeout(() => inputRef.current?.focus(), 0);\n };\n\n const applyLink = () => {\n const href = linkHref.trim();\n if (href) {\n const finalHref =\n href.startsWith('#') || href.startsWith('/') || /^https?:\\/\\//i.test(href)\n ? href\n : `https://${href}`;\n const { from, to } = view.state.selection;\n const tr = view.state.tr.addMark(from, to, linkMark.create({ href: finalHref }));\n view.dispatch(tr);\n }\n view.focus();\n setLinkMode(false);\n setLinkHref('');\n };\n\n const removeLink = () => {\n const { from, to } = view.state.selection;\n view.dispatch(view.state.tr.removeMark(from, to, linkMark));\n view.focus();\n };\n\n return (\n <div\n {...{ [FLOAT_ATTR]: '' }}\n style={{\n position: 'fixed', left, top, width: toolbarW, height: toolbarH,\n zIndex: 1000,\n display: 'flex', alignItems: 'center', gap: 2, padding: '0 6px',\n background: '#fff', borderRadius: 10, boxShadow: POPUP_SHADOW,\n userSelect: 'none',\n animation: 'ab-float-in 0.12s ease',\n }}\n >\n {linkMode ? (\n /* ── Link input mode ── */\n <>\n <span style={{ fontSize: 13, color: '#9ca3af', paddingLeft: 4, flexShrink: 0 }}>↗</span>\n <input\n ref={inputRef}\n value={linkHref}\n onChange={(e) => setLinkHref(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') { e.preventDefault(); applyLink(); }\n if (e.key === 'Escape') { e.preventDefault(); setLinkMode(false); view.focus(); }\n }}\n placeholder=\"Paste link...\"\n style={{\n flex: 1, border: 'none', outline: 'none',\n fontSize: 13, fontFamily: 'inherit', color: '#171717',\n padding: '0 6px', background: 'transparent',\n minWidth: 0,\n }}\n />\n <TBtn\n title=\"Apply (Enter)\"\n onMouseDown={(e) => { e.preventDefault(); applyLink(); }}\n style={{ color: '#6366f1', width: 24, fontSize: 14 }}\n >↵</TBtn>\n <TBtn\n title=\"Cancel (Esc)\"\n onMouseDown={(e) => { e.preventDefault(); setLinkMode(false); view.focus(); }}\n style={{ color: '#9ca3af', width: 24, fontSize: 14 }}\n >✕</TBtn>\n </>\n ) : (\n /* ── Normal toolbar mode ── */\n <>\n {/* Marks */}\n <TBtn active={isBold} title=\"Bold (Cmd+B)\" onMouseDown={() => run(toggleMark(bold))}\n style={{ fontWeight: 700 }}>B</TBtn>\n <TBtn active={isItalic} title=\"Italic (Cmd+I)\" onMouseDown={() => run(toggleMark(italic))}\n style={{ fontStyle: 'italic' }}>I</TBtn>\n <TBtn active={isUnderline} title=\"Underline (Cmd+U)\" onMouseDown={() => run(toggleMark(underline))}\n style={{ textDecoration: 'underline' }}>U</TBtn>\n <TBtn active={isStrike} title=\"Strikethrough (Cmd+Shift+X)\" onMouseDown={() => run(toggleMark(strikethrough))}\n style={{ textDecoration: 'line-through' }}>S</TBtn>\n <TBtn active={isCode} title=\"Code (Cmd+E)\" onMouseDown={() => run(toggleMark(code))}\n style={{ fontFamily: 'monospace', fontSize: 11 }}>`·`</TBtn>\n <TBtn active={isLink} title={isLink ? 'Remove link' : 'Add link (Cmd+K)'}\n onMouseDown={() => isLink ? removeLink() : openLinkInput()}\n style={{ fontSize: 14 }}>↗</TBtn>\n\n <Divider />\n\n {/* Block type dropdown */}\n <BlockTypeDropdown view={view} state={state} label={blockLabel} />\n </>\n )}\n </div>\n );\n}\n\n// ── Block menu items ──────────────────────────────────────\n\ninterface BlockItem {\n shortLabel: string;\n label: string;\n run: (view: EditorView) => void;\n}\n\nconst BLOCK_ITEMS: BlockItem[] = [\n {\n shortLabel: '¶',\n label: 'Text',\n run: (v) => { setBlockType(paragraph)(v.state, v.dispatch); v.focus(); },\n },\n {\n shortLabel: 'H1',\n label: 'Heading 1',\n run: (v) => { setBlockType(heading, { level: 1 })(v.state, v.dispatch); v.focus(); },\n },\n {\n shortLabel: 'H2',\n label: 'Heading 2',\n run: (v) => { setBlockType(heading, { level: 2 })(v.state, v.dispatch); v.focus(); },\n },\n {\n shortLabel: 'H3',\n label: 'Heading 3',\n run: (v) => { setBlockType(heading, { level: 3 })(v.state, v.dispatch); v.focus(); },\n },\n {\n shortLabel: '•',\n label: 'Bullet List',\n run: (v) => { wrapInList(bulletList)(v.state, v.dispatch); v.focus(); },\n },\n {\n shortLabel: '1.',\n label: 'Ordered List',\n run: (v) => { wrapInList(orderedList)(v.state, v.dispatch); v.focus(); },\n },\n {\n shortLabel: '☐',\n label: 'Todo List',\n run: (v) => {\n const { listItem: liType, bulletList: blType, paragraph: pType } = actionbookSchema.nodes;\n const li = liType.create({ checked: false }, pType.create());\n const list = blType.create(null, li);\n v.dispatch(v.state.tr.replaceSelectionWith(list));\n v.focus();\n },\n },\n {\n shortLabel: '❝',\n label: 'Quote',\n run: (v) => { wrapIn(blockquote)(v.state, v.dispatch); v.focus(); },\n },\n {\n shortLabel: '▦',\n label: 'Table',\n run: (v) => {\n const { table: tblType, tableRow: trType, tableHeader: thType, tableCell: tdType } = actionbookSchema.nodes;\n const headerCells = [thType.create(), thType.create(), thType.create()];\n const bodyCells = [tdType.create(), tdType.create(), tdType.create()];\n const headerRow = trType.create(null, headerCells);\n const bodyRow = trType.create(null, bodyCells);\n const tbl = tblType.create(null, [headerRow, bodyRow]);\n v.dispatch(v.state.tr.replaceSelectionWith(tbl));\n v.focus();\n },\n },\n];\n\n// ── EmptyParaHandle ───────────────────────────────────────\n\ninterface EmptyParaHandleProps {\n view: EditorView;\n cursorPos: number;\n}\n\nfunction EmptyParaHandle({ view, cursorPos }: EmptyParaHandleProps) {\n const [menuOpen, setMenuOpen] = useState(false);\n\n const coords = view.coordsAtPos(cursorPos);\n const lineH = Math.max(coords.bottom - coords.top, 18);\n const btnSize = 22;\n const btnLeft = coords.left - btnSize - 32;\n const btnTop = coords.top + (lineH - btnSize) / 2;\n const menuLeft = Math.max(VPORT_MARGIN, btnLeft);\n const menuTop = btnTop + btnSize + 4;\n\n // Close block menu when clicking outside floating elements\n useEffect(() => {\n if (!menuOpen) return;\n const onDown = (e: MouseEvent) => {\n if (!(e.target as HTMLElement).closest(`[${FLOAT_ATTR}]`)) {\n setMenuOpen(false);\n }\n };\n document.addEventListener('mousedown', onDown, true);\n return () => document.removeEventListener('mousedown', onDown, true);\n }, [menuOpen]);\n\n return (\n <>\n {/* + button */}\n <button\n {...{ [FLOAT_ATTR]: '' }}\n title=\"Add block\"\n onMouseDown={(e) => { e.preventDefault(); setMenuOpen((v) => !v); }}\n style={{\n ...BTN_RESET,\n position: 'fixed', zIndex: 999,\n left: btnLeft < VPORT_MARGIN ? VPORT_MARGIN : btnLeft,\n top: btnTop,\n width: btnSize, height: btnSize,\n border: '1px solid rgba(0,0,0,0.1)',\n borderRadius: 5,\n background: menuOpen ? 'rgba(99,102,241,0.08)' : '#fff',\n boxShadow: '0 1px 3px rgba(0,0,0,0.06)',\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n color: menuOpen ? '#6366f1' : '#9ca3af',\n fontSize: 16,\n animation: 'ab-float-in 0.15s ease',\n transition: 'color 0.1s, background 0.1s, border-color 0.1s',\n }}\n >\n +\n </button>\n\n {/* Block picker menu */}\n {menuOpen && (\n <div\n {...{ [FLOAT_ATTR]: '' }}\n style={{\n position: 'fixed', zIndex: 1000,\n left: menuLeft, top: menuTop,\n background: '#fff',\n borderRadius: 10,\n boxShadow: POPUP_SHADOW,\n padding: 6,\n minWidth: 168,\n animation: 'ab-float-in 0.12s ease',\n }}\n >\n {BLOCK_ITEMS.map((item) => (\n <BlockMenuItem\n key={item.label}\n item={item}\n view={view}\n onRun={() => setMenuOpen(false)}\n />\n ))}\n </div>\n )}\n </>\n );\n}\n\nfunction BlockMenuItem({\n item,\n view,\n onRun,\n}: {\n item: BlockItem;\n view: EditorView;\n onRun: () => void;\n}) {\n const [hover, setHover] = useState(false);\n return (\n <button\n {...{ [FLOAT_ATTR]: '' }}\n onMouseDown={(e) => { e.preventDefault(); item.run(view); onRun(); }}\n onMouseEnter={() => setHover(true)}\n onMouseLeave={() => setHover(false)}\n style={{\n ...BTN_RESET,\n display: 'flex', alignItems: 'center', gap: 10,\n width: '100%', padding: '6px 8px',\n borderRadius: 6, textAlign: 'left',\n fontSize: 13, color: '#3f3f46',\n background: hover ? 'rgba(0,0,0,0.04)' : 'transparent',\n transition: 'background 0.1s',\n }}\n >\n <span\n style={{\n width: 24, flexShrink: 0, textAlign: 'center',\n fontWeight: 700, fontSize: 12,\n fontFamily: 'monospace',\n color: '#6366f1',\n }}\n >\n {item.shortLabel}\n </span>\n {item.label}\n </button>\n );\n}\n\n// ── FloatingMenu (root) ───────────────────────────────────\n\nexport interface FloatingMenuProps {\n view: EditorView | null;\n editorState: EditorState | null;\n}\n\nexport function FloatingMenu({ view, editorState }: FloatingMenuProps) {\n // ── Dwell timer for empty paragraph ──\n const [showEmptyHandle, setShowEmptyHandle] = useState(false);\n const dwellTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const lastEmptyPosRef = useRef<number | null>(null);\n\n // ── Re-render on editor container scroll (position recalculation) ──\n const [, setScrollTick] = useState(0);\n useEffect(() => {\n const editorDom = view?.dom;\n if (!editorDom) return;\n const container = editorDom.closest('.editor-shell') ?? editorDom.parentElement;\n if (!container) return;\n const onScroll = () => setScrollTick((n) => n + 1);\n container.addEventListener('scroll', onScroll, { passive: true });\n return () => container.removeEventListener('scroll', onScroll);\n }, [view]);\n\n // ── Inject keyframe animation once ──\n useEffect(() => {\n const id = 'ab-float-keyframes';\n if (document.getElementById(id)) return;\n const style = document.createElement('style');\n style.id = id;\n style.textContent = `\n @keyframes ab-float-in {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n }\n `;\n document.head.appendChild(style);\n }, []);\n\n if (!view || !editorState) return null;\n\n const emptyPos = emptyBlockCursorPos(editorState);\n const hasSelection = !editorState.selection.empty;\n\n // Manage dwell timer\n if (emptyPos !== lastEmptyPosRef.current) {\n lastEmptyPosRef.current = emptyPos;\n\n if (dwellTimerRef.current) {\n clearTimeout(dwellTimerRef.current);\n dwellTimerRef.current = null;\n }\n\n if (emptyPos !== null) {\n dwellTimerRef.current = setTimeout(() => setShowEmptyHandle(true), DWELL_MS);\n } else {\n setShowEmptyHandle(false);\n }\n }\n\n const selectionRect = hasSelection ? getSelectionDOMRect() : null;\n\n return createPortal(\n <>\n {/* Selection toolbar */}\n {hasSelection && selectionRect && (\n <SelectionToolbar\n view={view}\n state={editorState}\n selectionRect={selectionRect}\n />\n )}\n\n {/* Empty paragraph handle */}\n {!hasSelection && showEmptyHandle && emptyPos !== null && (\n <EmptyParaHandle view={view} cursorPos={emptyPos} />\n )}\n </>,\n document.body,\n );\n}\n","/**\n * Inline suggestion (ghost text) plugin.\n *\n * Debounces after the cursor stops moving, calls an LLM endpoint via a\n * user-supplied `InlineSuggestProvider`, then renders the response as gray\n * ghost text after the cursor using a ProseMirror widget decoration.\n *\n * Accepts:\n * Tab → insert the suggestion at the cursor\n * Escape → dismiss the suggestion\n *\n * Fully detachable: just omit `createInlineSuggestPlugin()` from the plugins\n * array to disable the feature entirely.\n */\n\nimport { Plugin, PluginKey } from 'prosemirror-state';\nimport type { EditorState } from 'prosemirror-state';\nimport { Decoration, DecorationSet } from 'prosemirror-view';\nimport type { EditorView } from 'prosemirror-view';\nimport type { ActionbookPlugin } from './types';\nimport type { LlmCompletionEndpoint } from '../../lint/types';\n\n// ── Public types ──────────────────────────────────────────\n\n/**\n * Cursor context passed to the provider's `buildPrompt`.\n */\nexport type InlineSuggestContext = {\n /** Text before the cursor — current paragraph plus up to 2 preceding paragraphs. */\n textBefore: string;\n /** Text in the current paragraph after the cursor (up to 100 chars). */\n textAfter: string;\n};\n\n/**\n * Extensible provider interface, analogous to `LlmLintRule`.\n *\n * Implement this to customize what gets sent to the LLM and how the\n * response is parsed into a suggestion string.\n */\nexport type InlineSuggestProvider = {\n /** Unique identifier for this provider. */\n id: string;\n /**\n * Build the prompt string sent to the LLM endpoint.\n * Return an empty string to suppress the request entirely.\n */\n buildPrompt: (ctx: InlineSuggestContext) => string;\n /**\n * Parse the raw LLM response into the text to insert at the cursor.\n * Return an empty string to suppress the decoration.\n * `ctx` is the same context that was passed to `buildPrompt`.\n */\n parseResponse: (response: string, ctx: InlineSuggestContext) => string;\n};\n\nexport interface InlineSuggestState {\n /** Ghost text currently shown, or null if nothing is active. */\n suggestion: string | null;\n /** Document position the suggestion is anchored to. */\n anchorPos: number | null;\n}\n\nexport const inlineSuggestKey = new PluginKey<InlineSuggestState>('inlineSuggest');\n\n// ── Constants ─────────────────────────────────────────────\n\nconst DEBOUNCE_MS = 600;\nconst CONTEXT_CHARS = 500;\n\n// ── Factory ───────────────────────────────────────────────\n\nexport function createInlineSuggestPlugin(\n provider: InlineSuggestProvider,\n endpoint: LlmCompletionEndpoint,\n options?: {\n /**\n * Called when the user accepts a suggestion (Tab) or the cursor moves to\n * a new context. Use this to pre-create a fresh completion session so it's\n * ready by the time the next debounce fires.\n */\n onContextChange?: () => void;\n },\n): ActionbookPlugin {\n const { onContextChange } = options ?? {};\n return {\n name: 'inlineSuggest',\n\n plugins: () => [\n new Plugin<InlineSuggestState>({\n key: inlineSuggestKey,\n\n state: {\n init: (): InlineSuggestState => ({ suggestion: null, anchorPos: null }),\n\n apply(tr, prev): InlineSuggestState {\n const meta = tr.getMeta(inlineSuggestKey) as InlineSuggestState | null | undefined;\n if (meta !== undefined) return meta ?? { suggestion: null, anchorPos: null };\n // Any document edit or cursor move clears the current ghost text\n if (tr.docChanged || tr.selectionSet) {\n return { suggestion: null, anchorPos: null };\n }\n return prev;\n },\n },\n\n props: {\n decorations(state: EditorState) {\n const ps = inlineSuggestKey.getState(state);\n if (!ps?.suggestion || !state.selection.empty) return DecorationSet.empty;\n\n const ghost = document.createElement('span');\n ghost.textContent = ps.suggestion;\n ghost.style.cssText =\n 'color: rgba(0,0,0,0.3); pointer-events: none; user-select: none;';\n ghost.setAttribute('aria-hidden', 'true');\n\n return DecorationSet.create(state.doc, [\n Decoration.widget(state.selection.from, ghost, {\n side: 1,\n key: 'inline-suggest',\n }),\n ]);\n },\n },\n\n view(editorView: EditorView) {\n // Capture Tab / Escape before the browser handles them (Tab moves\n // focus, Escape might bubble to parent dialogs).\n function onKeydown(event: KeyboardEvent) {\n if (event.key !== 'Tab' && event.key !== 'Escape') return;\n const ps = inlineSuggestKey.getState(editorView.state);\n console.debug('[inline-suggest] key pressed:', event.key, 'suggestion:', ps?.suggestion);\n if (!ps?.suggestion) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n if (event.key === 'Tab') {\n // Context changes after accept — pre-clone now so the next\n // fetch gets a fresh session without waiting for clone().\n onContextChange?.();\n const tr = editorView.state.tr.insertText(\n ps.suggestion,\n editorView.state.selection.from,\n );\n tr.setMeta(inlineSuggestKey, { suggestion: null, anchorPos: null });\n editorView.dispatch(tr);\n } else {\n const tr = editorView.state.tr;\n tr.setMeta(inlineSuggestKey, { suggestion: null, anchorPos: null });\n editorView.dispatch(tr);\n }\n }\n\n editorView.dom.addEventListener('keydown', onKeydown, { capture: true });\n\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n let abortController: AbortController | null = null;\n\n function cancel() {\n if (debounceTimer != null) {\n clearTimeout(debounceTimer);\n debounceTimer = null;\n }\n abortController?.abort();\n abortController = null;\n }\n\n function schedule(view: EditorView) {\n cancel();\n debounceTimer = setTimeout(() => {\n debounceTimer = null;\n void fetchSuggestion(view);\n }, DEBOUNCE_MS);\n }\n\n async function fetchSuggestion(view: EditorView) {\n const { state } = view;\n if (!state.selection.empty) return;\n\n const cursorPos = state.selection.from;\n const $from = state.doc.resolve(cursorPos);\n const paraStart = $from.start();\n const paraEnd = $from.end();\n\n // Collect up to 3 block nodes ending at the cursor's block.\n const nearbyStart = (() => {\n const $cursor = state.doc.resolve(cursorPos);\n const depth = $cursor.depth; // depth of the paragraph node\n let blockStart = $cursor.before(depth); // pos of current block's opening token\n let count = 1;\n while (count < 3 && blockStart > 0) {\n const $prev = state.doc.resolve(blockStart - 1);\n blockStart = $prev.before($prev.depth);\n count++;\n }\n return blockStart;\n })();\n\n const textBefore = state.doc.textBetween(nearbyStart, cursorPos, '\\n', '');\n const textAfter = state.doc.textBetween(\n cursorPos,\n Math.min(paraEnd, cursorPos + 100),\n '\\n',\n '',\n );\n\n if (!textBefore.trim()) return;\n\n const ctx = { textBefore, textAfter };\n const prompt = provider.buildPrompt(ctx);\n if (!prompt) return;\n\n console.debug(`[inline-suggest] fetching (provider=${provider.id}) prompt=`, prompt);\n\n abortController = new AbortController();\n try {\n const response = await endpoint(prompt, { signal: abortController.signal });\n console.debug(`[inline-suggest] response=`, response);\n\n const suggestion = provider.parseResponse(response, ctx).trimEnd();\n console.debug(`[inline-suggest] parsed suggestion=`, JSON.stringify(suggestion));\n\n if (!suggestion) {\n console.debug('[inline-suggest] empty suggestion — skipping');\n return;\n }\n\n // Discard if cursor moved while we were waiting\n if (!view.state.selection.empty) return;\n if (view.state.selection.from !== cursorPos) {\n console.debug('[inline-suggest] cursor moved — discarding');\n return;\n }\n\n const tr = view.state.tr;\n tr.setMeta(inlineSuggestKey, { suggestion, anchorPos: cursorPos });\n view.dispatch(tr);\n console.debug('[inline-suggest] suggestion applied');\n } catch (err) {\n if ((err as Error)?.name === 'AbortError') {\n console.debug('[inline-suggest] request aborted');\n } else {\n console.warn('[inline-suggest] endpoint error:', err);\n }\n }\n }\n\n return {\n update(view: EditorView, prevState: EditorState) {\n const docChanged = view.state.doc !== prevState.doc;\n const selChanged = view.state.selection !== prevState.selection;\n if (!docChanged && !selChanged) return;\n\n // A suggestion was just set (meta transaction) — don't reschedule\n const ps = inlineSuggestKey.getState(view.state);\n if (ps?.suggestion) return;\n\n if (!view.state.selection.empty) {\n cancel();\n return;\n }\n\n // Context changed — pre-clone before the debounce fires so the\n // session is fresh and ready when the fetch runs.\n onContextChange?.();\n schedule(view);\n },\n\n destroy() {\n cancel();\n editorView.dom.removeEventListener('keydown', onKeydown, { capture: true });\n },\n };\n },\n }),\n ],\n };\n}\n"],"mappings":"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","names":["code","key","jsx","jsxs","key","text","doc","jsx","EditorShell","blocks","defaultHandlers","exit","exit","table","row","sizes","columnIndex","code","exit","defaultHandlers","text","text","MAX_DEPTH","ALLOWED_URL_PROTOCOLS","linkMark","doc","defaultHandlers","doc","ALLOWED_URL_PROTOCOLS","convertInline","convertBlock","doc","doc","JUMP_POINT_RE","textContent","MAX_DEPTH","MAX_DEPTH","code","code","constructs","ok","code","markdownSpace","ok","code","markdownLineEndingOrSpace","ok","code","markdownLineEndingOrSpace","strikethrough","text","ok","code","markdownLineEnding","markdownLineEndingOrSpace","markdownSpace","ok","code","markdownLineEnding","markdownSpace","markdownLineEndingOrSpace","map","table","markdownLineEnding","markdownLineEndingOrSpace","markdownSpace","ok","code","MAX_DEPTH","text","MAX_DEPTH","MAX_DEPTH","doc","text","doc","text","doc","Plugin","PluginKey","text","jsx","jsxs","Plugin","PluginKey","Decoration","DecorationSet","doc","jsx","jsxs","RESOURCE_TAG_COLORS","RESOURCE_TAG_ICONS","text","Plugin","PluginKey","Decoration","DecorationSet","PluginKey","doc","text","Decoration","buildDecorations","DecorationSet","Plugin","useEffect","useRef","useState","createRoot","text","Fragment","jsx","jsxs","doc","useState","useRef","useEffect","createRoot","InputRule","inputRules","Plugin","PluginKey","TextSelection","doc","text","Plugin","PluginKey","StyleManager","doc","key","Plugin","PluginKey","derived","useEffect","useRef","useState","jsx","jsxs","useState","useRef","useEffect","useState","jsx","jsxs","doc","text","useState","useCallback","useEffect","useRef","useState","createPortal","toggleMark","wrapInList","Fragment","jsx","jsxs","paragraph","heading","bulletList","orderedList","blockquote","bold","italic","underline","strikethrough","code","VPORT_MARGIN","POPUP_SHADOW","BTN_RESET","useState","useRef","useEffect","wrapInList","createPortal","useCallback","toggleMark","Plugin","PluginKey","Decoration","DecorationSet","Plugin","DecorationSet","Decoration"]}