@damiro/stylo 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +144 -0
  3. package/dist/InPlaceView-Ba7JCZ2Y.js +2346 -0
  4. package/dist/InPlaceView-Ba7JCZ2Y.js.map +1 -0
  5. package/dist/Preview-Dxb9zPVv.js +93 -0
  6. package/dist/Preview-Dxb9zPVv.js.map +1 -0
  7. package/dist/SplitView.d.ts +23 -0
  8. package/dist/SplitView.d.ts.map +1 -0
  9. package/dist/Stylo.d.ts +15 -0
  10. package/dist/Stylo.d.ts.map +1 -0
  11. package/dist/callout-oLE630ZP.js +37 -0
  12. package/dist/callout-oLE630ZP.js.map +1 -0
  13. package/dist/callout.d.ts +18 -0
  14. package/dist/callout.d.ts.map +1 -0
  15. package/dist/config-DTBxVhtH.js +101 -0
  16. package/dist/config-DTBxVhtH.js.map +1 -0
  17. package/dist/editor/SourceView.d.ts +17 -0
  18. package/dist/editor/SourceView.d.ts.map +1 -0
  19. package/dist/editor/extensions.d.ts +20 -0
  20. package/dist/editor/extensions.d.ts.map +1 -0
  21. package/dist/editor/highlight.d.ts +19 -0
  22. package/dist/editor/highlight.d.ts.map +1 -0
  23. package/dist/editor/save.d.ts +12 -0
  24. package/dist/editor/save.d.ts.map +1 -0
  25. package/dist/editor/theme.d.ts +3 -0
  26. package/dist/editor/theme.d.ts.map +1 -0
  27. package/dist/editor/useCodeMirror.d.ts +26 -0
  28. package/dist/editor/useCodeMirror.d.ts.map +1 -0
  29. package/dist/frontmatter.d.ts +21 -0
  30. package/dist/frontmatter.d.ts.map +1 -0
  31. package/dist/index.d.ts +4 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/inplace/InPlaceView.d.ts +30 -0
  34. package/dist/inplace/InPlaceView.d.ts.map +1 -0
  35. package/dist/inplace/autoformat.d.ts +23 -0
  36. package/dist/inplace/autoformat.d.ts.map +1 -0
  37. package/dist/inplace/config.d.ts +57 -0
  38. package/dist/inplace/config.d.ts.map +1 -0
  39. package/dist/inplace/context-menu-actions.d.ts +53 -0
  40. package/dist/inplace/context-menu-actions.d.ts.map +1 -0
  41. package/dist/inplace/context-menu.d.ts +50 -0
  42. package/dist/inplace/context-menu.d.ts.map +1 -0
  43. package/dist/inplace/decorate.d.ts +17 -0
  44. package/dist/inplace/decorate.d.ts.map +1 -0
  45. package/dist/inplace/edit-boundaries.d.ts +59 -0
  46. package/dist/inplace/edit-boundaries.d.ts.map +1 -0
  47. package/dist/inplace/edit-insert-assoc.d.ts +17 -0
  48. package/dist/inplace/edit-insert-assoc.d.ts.map +1 -0
  49. package/dist/inplace/edit-line-prefix.d.ts +23 -0
  50. package/dist/inplace/edit-line-prefix.d.ts.map +1 -0
  51. package/dist/inplace/extension.d.ts +21 -0
  52. package/dist/inplace/extension.d.ts.map +1 -0
  53. package/dist/inplace/frontmatter.d.ts +13 -0
  54. package/dist/inplace/frontmatter.d.ts.map +1 -0
  55. package/dist/inplace/inline-md.d.ts +13 -0
  56. package/dist/inplace/inline-md.d.ts.map +1 -0
  57. package/dist/inplace/lazyInPlace.d.ts +7 -0
  58. package/dist/inplace/lazyInPlace.d.ts.map +1 -0
  59. package/dist/inplace/link-click.d.ts +24 -0
  60. package/dist/inplace/link-click.d.ts.map +1 -0
  61. package/dist/inplace/link-hover.d.ts +11 -0
  62. package/dist/inplace/link-hover.d.ts.map +1 -0
  63. package/dist/inplace/list-guides.d.ts +16 -0
  64. package/dist/inplace/list-guides.d.ts.map +1 -0
  65. package/dist/inplace/long-press.d.ts +39 -0
  66. package/dist/inplace/long-press.d.ts.map +1 -0
  67. package/dist/inplace/math.d.ts +16 -0
  68. package/dist/inplace/math.d.ts.map +1 -0
  69. package/dist/inplace/menu-plugin.d.ts +30 -0
  70. package/dist/inplace/menu-plugin.d.ts.map +1 -0
  71. package/dist/inplace/nodes.d.ts +24 -0
  72. package/dist/inplace/nodes.d.ts.map +1 -0
  73. package/dist/inplace/plugin.d.ts +21 -0
  74. package/dist/inplace/plugin.d.ts.map +1 -0
  75. package/dist/inplace/reveal.d.ts +8 -0
  76. package/dist/inplace/reveal.d.ts.map +1 -0
  77. package/dist/inplace/scan.d.ts +11 -0
  78. package/dist/inplace/scan.d.ts.map +1 -0
  79. package/dist/inplace/selection-bar.d.ts +38 -0
  80. package/dist/inplace/selection-bar.d.ts.map +1 -0
  81. package/dist/inplace/table-cell-dom.d.ts +30 -0
  82. package/dist/inplace/table-cell-dom.d.ts.map +1 -0
  83. package/dist/inplace/table-enter.d.ts +22 -0
  84. package/dist/inplace/table-enter.d.ts.map +1 -0
  85. package/dist/inplace/table-gizmos.d.ts +55 -0
  86. package/dist/inplace/table-gizmos.d.ts.map +1 -0
  87. package/dist/inplace/table-structure.d.ts +23 -0
  88. package/dist/inplace/table-structure.d.ts.map +1 -0
  89. package/dist/inplace/table-widget.d.ts +81 -0
  90. package/dist/inplace/table-widget.d.ts.map +1 -0
  91. package/dist/inplace/tables.d.ts +8 -0
  92. package/dist/inplace/tables.d.ts.map +1 -0
  93. package/dist/inplace/theme.d.ts +14 -0
  94. package/dist/inplace/theme.d.ts.map +1 -0
  95. package/dist/inplace/widgets.d.ts +25 -0
  96. package/dist/inplace/widgets.d.ts.map +1 -0
  97. package/dist/inplace/wikilinks.d.ts +10 -0
  98. package/dist/inplace/wikilinks.d.ts.map +1 -0
  99. package/dist/katex-BfiLlqfN.js +21979 -0
  100. package/dist/katex-BfiLlqfN.js.map +1 -0
  101. package/dist/katex.css +3 -0
  102. package/dist/markdown-N3lRmU2n.js +8524 -0
  103. package/dist/markdown-N3lRmU2n.js.map +1 -0
  104. package/dist/render/Preview.d.ts +10 -0
  105. package/dist/render/Preview.d.ts.map +1 -0
  106. package/dist/render/lazyPreview.d.ts +8 -0
  107. package/dist/render/lazyPreview.d.ts.map +1 -0
  108. package/dist/render/remark-callout.d.ts +10 -0
  109. package/dist/render/remark-callout.d.ts.map +1 -0
  110. package/dist/render/remark-wikilink.d.ts +8 -0
  111. package/dist/render/remark-wikilink.d.ts.map +1 -0
  112. package/dist/styles.css +2 -0
  113. package/dist/stylo.js +293 -0
  114. package/dist/stylo.js.map +1 -0
  115. package/dist/toolbar/Toolbar.d.ts +28 -0
  116. package/dist/toolbar/Toolbar.d.ts.map +1 -0
  117. package/dist/toolbar/block.d.ts +56 -0
  118. package/dist/toolbar/block.d.ts.map +1 -0
  119. package/dist/toolbar/cell-inline.d.ts +16 -0
  120. package/dist/toolbar/cell-inline.d.ts.map +1 -0
  121. package/dist/toolbar/commands.d.ts +25 -0
  122. package/dist/toolbar/commands.d.ts.map +1 -0
  123. package/dist/toolbar/config.d.ts +21 -0
  124. package/dist/toolbar/config.d.ts.map +1 -0
  125. package/dist/toolbar/fence.d.ts +28 -0
  126. package/dist/toolbar/fence.d.ts.map +1 -0
  127. package/dist/toolbar/floating-watchdog.d.ts +18 -0
  128. package/dist/toolbar/floating-watchdog.d.ts.map +1 -0
  129. package/dist/toolbar/icon-paths.d.ts +10 -0
  130. package/dist/toolbar/icon-paths.d.ts.map +1 -0
  131. package/dist/toolbar/icons.d.ts +10 -0
  132. package/dist/toolbar/icons.d.ts.map +1 -0
  133. package/dist/toolbar/inline-ops.d.ts +101 -0
  134. package/dist/toolbar/inline-ops.d.ts.map +1 -0
  135. package/dist/toolbar/inline.d.ts +38 -0
  136. package/dist/toolbar/inline.d.ts.map +1 -0
  137. package/dist/toolbar/keyboard-inset.d.ts +10 -0
  138. package/dist/toolbar/keyboard-inset.d.ts.map +1 -0
  139. package/dist/toolbar/keymap.d.ts +8 -0
  140. package/dist/toolbar/keymap.d.ts.map +1 -0
  141. package/dist/toolbar/labels.d.ts +16 -0
  142. package/dist/toolbar/labels.d.ts.map +1 -0
  143. package/dist/toolbar/table-grid.d.ts +23 -0
  144. package/dist/toolbar/table-grid.d.ts.map +1 -0
  145. package/dist/toolbar/table.d.ts +35 -0
  146. package/dist/toolbar/table.d.ts.map +1 -0
  147. package/dist/toolbar-settings/SortableRow.d.ts +15 -0
  148. package/dist/toolbar-settings/SortableRow.d.ts.map +1 -0
  149. package/dist/toolbar-settings/StyloToolbarSettings.d.ts +29 -0
  150. package/dist/toolbar-settings/StyloToolbarSettings.d.ts.map +1 -0
  151. package/dist/toolbar-settings/index.d.ts +3 -0
  152. package/dist/toolbar-settings/index.d.ts.map +1 -0
  153. package/dist/toolbar-settings/items.d.ts +24 -0
  154. package/dist/toolbar-settings/items.d.ts.map +1 -0
  155. package/dist/toolbar-settings.js +269 -0
  156. package/dist/toolbar-settings.js.map +1 -0
  157. package/dist/types.d.ts +264 -0
  158. package/dist/types.d.ts.map +1 -0
  159. package/dist/useCodeMirror-YnIFkvKn.js +1361 -0
  160. package/dist/useCodeMirror-YnIFkvKn.js.map +1 -0
  161. package/dist/wikilink-BFpTehto.js +42 -0
  162. package/dist/wikilink-BFpTehto.js.map +1 -0
  163. package/dist/wikilink.d.ts +11 -0
  164. package/dist/wikilink.d.ts.map +1 -0
  165. package/package.json +122 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InPlaceView-Ba7JCZ2Y.js","names":[],"sources":["../src/inplace/config.ts","../src/inplace/frontmatter.ts","../src/inplace/list-guides.ts","../src/inplace/reveal.ts","../src/inplace/scan.ts","../src/inplace/math.ts","../src/inplace/widgets.ts","../src/inplace/nodes.ts","../src/inplace/wikilinks.ts","../src/inplace/decorate.ts","../src/inplace/plugin.ts","../src/inplace/edit-boundaries.ts","../src/inplace/context-menu-actions.ts","../src/inplace/inline-md.ts","../src/inplace/long-press.ts","../src/inplace/context-menu.ts","../src/inplace/table-gizmos.ts","../src/inplace/table-structure.ts","../src/inplace/table-widget.ts","../src/inplace/autoformat.ts","../src/inplace/edit-insert-assoc.ts","../src/inplace/edit-line-prefix.ts","../src/inplace/link-click.ts","../src/inplace/link-hover.ts","../src/inplace/menu-plugin.ts","../src/inplace/selection-bar.ts","../src/inplace/tables.ts","../src/inplace/table-enter.ts","../src/inplace/theme.ts","../src/inplace/extension.ts","../src/inplace/InPlaceView.tsx"],"sourcesContent":["import { Facet } from \"@codemirror/state\"\nimport type {\n InPlaceConfig,\n InPlaceDecorationToggles,\n MenuGroupId,\n RevealMode,\n SelectionUI,\n TableEditing,\n ToolbarCommandId,\n} from \"../types\"\n\n/** `InPlaceDecorationToggles` with every key resolved to a concrete boolean. */\nexport type ResolvedToggles = Required<InPlaceDecorationToggles>\n\nconst DEFAULT_TOGGLES: ResolvedToggles = {\n headings: true,\n emphasis: true,\n links: true,\n wikilinks: true,\n math: true,\n lists: true,\n tasks: true,\n blockquote: true,\n horizontalRule: true,\n code: true,\n frontmatter: true,\n tables: true,\n}\n\nexport function resolveToggles(config?: InPlaceConfig): ResolvedToggles {\n return { ...DEFAULT_TOGGLES, ...config?.decorations }\n}\n\n/**\n * Carries the resolved decoration toggles to every producer (the view plugin\n * and the three state fields). Seeded once by `inPlaceExtension`; read, never\n * written, by `decorate.ts`, `math.ts`, `frontmatter.ts`, and `tables.ts`.\n */\nexport const inPlaceConfigFacet = Facet.define<ResolvedToggles, ResolvedToggles>({\n combine: (values) => values[0] ?? DEFAULT_TOGGLES,\n})\n\n/** Table editing mode, seeded once by `inPlaceExtension`; read by `tables.ts`. */\nexport const tableEditingFacet = Facet.define<TableEditing, TableEditing>({\n combine: (values) => values[0] ?? \"source\",\n})\n\n/**\n * Marker reveal behaviour (ADR-007). `\"never\"` makes `decorate.ts` hide every\n * inline marker regardless of the caret line. Seeded once by `inPlaceExtension`.\n */\nexport const revealModeFacet = Facet.define<RevealMode, RevealMode>({\n combine: (values) => values[0] ?? \"caret\",\n})\n\n/**\n * The host's `onLinkClick` (the \"Open link\" action in the right-click link\n * editor), or `null`. Seeded once by `inPlaceExtension`.\n */\nexport const linkOpenFacet = Facet.define<\n ((href: string) => void) | null,\n ((href: string) => void) | null\n>({\n combine: (values) => values[0] ?? null,\n})\n\n/**\n * Whether the right-click menu takes over from the browser's own context menu\n * in the canvas. Seeded once by `inPlaceExtension`; read by `menu-plugin.ts`.\n */\nexport const contextMenuEnabled = Facet.define<boolean, boolean>({\n combine: (values) => values[0] ?? true,\n})\n\n/** The menu's groups in their default order. */\nexport const DEFAULT_MENU_GROUPS: MenuGroupId[] = [\n \"link\",\n \"format\",\n \"paragraph\",\n \"insert\",\n \"clipboard\",\n]\n\n/** The selection bar's buttons in their default order. */\nexport const DEFAULT_SELECTION_BAR_ITEMS: ToolbarCommandId[] = [\n \"bold\",\n \"italic\",\n \"strike\",\n \"code\",\n \"link\",\n \"wikilink\",\n \"math\",\n]\n\n/** `enabled` false keeps the browser menu; `groups` is always a non-empty list. */\nexport function resolveContextMenu(c: InPlaceConfig[\"contextMenu\"]): {\n enabled: boolean\n groups: MenuGroupId[]\n} {\n if (c === false) return { enabled: false, groups: [] }\n if (c == null || c === true) return { enabled: true, groups: DEFAULT_MENU_GROUPS }\n return { enabled: true, groups: c.groups?.length ? c.groups : DEFAULT_MENU_GROUPS }\n}\n\n/**\n * Ordered right-click menu groups. Seeded once by `inPlaceExtension`; read by\n * `context-menu-actions.ts`.\n */\nexport const menuGroupsFacet = Facet.define<MenuGroupId[], MenuGroupId[]>({\n combine: (values) => values[0] ?? DEFAULT_MENU_GROUPS,\n})\n\n/** Selection-bar buttons, resolved to the known inline ids in the given order. */\nexport function resolveSelectionBarItems(ids?: ToolbarCommandId[]): ToolbarCommandId[] {\n if (!ids?.length) return DEFAULT_SELECTION_BAR_ITEMS\n const kept = ids.filter((id) => DEFAULT_SELECTION_BAR_ITEMS.includes(id))\n return kept.length ? kept : DEFAULT_SELECTION_BAR_ITEMS\n}\n\n/**\n * Ordered selection-bar button ids. Seeded once by `inPlaceExtension`; read by\n * `selection-bar.ts`.\n */\nexport const selectionBarItemsFacet = Facet.define<ToolbarCommandId[], ToolbarCommandId[]>({\n combine: (values) => values[0] ?? DEFAULT_SELECTION_BAR_ITEMS,\n})\n\n/**\n * What a non-empty selection offers (ADR-007). `\"bar\"` shows the floating\n * formatting bar; `\"menu\"` (default) keeps the inline group in the right-click\n * menu instead; `\"none\"` shows neither. Seeded once by `inPlaceExtension`; read\n * by `selection-bar.ts` and `context-menu-actions.ts`.\n */\nexport const selectionUIFacet = Facet.define<SelectionUI, SelectionUI>({\n combine: (values) => values[0] ?? \"menu\",\n})\n","import { type EditorState, StateField } from \"@codemirror/state\"\nimport { Decoration, type DecorationSet, EditorView } from \"@codemirror/view\"\nimport { frontmatterRange } from \"../frontmatter\"\nimport { inPlaceConfigFacet } from \"./config\"\n\nexport { frontmatterRange }\n\nfunction build(state: EditorState): DecorationSet {\n if (!state.facet(inPlaceConfigFacet).frontmatter) return Decoration.none\n const range = frontmatterRange(state.doc)\n if (!range) return Decoration.none\n\n const first = state.doc.lineAt(range.from).number\n const last = state.doc.lineAt(range.to).number\n const revealed = state.selection.ranges.some((r) => {\n const l = state.doc.lineAt(r.from).number\n return l >= first && l <= last\n })\n\n const out = []\n for (let n = first; n <= last; n++) {\n const line = state.doc.line(n)\n const cls = n === first ? \"cm-inplace-fm cm-inplace-fm-first\" : \"cm-inplace-fm\"\n out.push(Decoration.line({ class: cls }).range(line.from))\n // Hide the `---` fences off-caret; keep the row (no height collapse).\n if ((n === first || n === last) && !revealed && line.to > line.from) {\n out.push(Decoration.replace({}).range(line.from, line.to))\n }\n }\n return Decoration.set(out, true)\n}\n\n/**\n * Recesses the leading YAML block — muted, monospace, with a \"Frontmatter\"\n * label on the first line — without collapsing it. Line decorations only: the rows\n * keep their height, so click-to-position stays accurate (an earlier `block`\n * widget that folded the block to a one-line chip desynced it). A state field,\n * not the plugin, only because the region has no grammar node to hang off.\n */\nexport const frontmatterField = StateField.define<DecorationSet>({\n create: build,\n update: (value, tr) => (tr.docChanged || tr.selection ? build(tr.state) : value),\n provide: (field) => EditorView.decorations.from(field),\n})\n","/**\n * Vertical indent guides for nested lists on the in-place canvas — one faint\n * rule per nesting level, drawn from the list's left padding (Obsidian /\n * Notion). Purely decorative: a `.cm-inplace-li` line decoration carrying the\n * nesting depth in `--sl-li-depth`, which the theme turns into that many guide\n * rules via a background gradient.\n *\n * Only a list item's *own* lines are decorated — the range stops before its\n * first nested list — so each line's depth is its innermost item's.\n */\n\nimport type { Range, Text } from \"@codemirror/state\"\nimport { Decoration } from \"@codemirror/view\"\nimport type { SyntaxNodeRef } from \"@lezer/common\"\nimport type { ResolvedToggles } from \"./config\"\nimport type { Tree } from \"./scan\"\n\n/** Nesting depth of a `ListItem` node: 1 at the top level, 2 once nested, … */\nfunction depthOf(node: SyntaxNodeRef): number {\n let depth = 1\n for (let p = node.node.parent; p; p = p.parent) {\n if (p.name === \"ListItem\") depth++\n }\n return depth\n}\n\nexport function scanListGuides(\n from: number,\n to: number,\n tree: Tree,\n doc: Text,\n toggles: ResolvedToggles,\n out: Range<Decoration>[],\n): void {\n if (!toggles.lists) return\n const seen = new Set<number>()\n\n tree.iterate({\n from,\n to,\n enter: (node) => {\n if (node.name !== \"ListItem\") return\n const guides = depthOf(node) - 1\n if (guides < 1) return\n\n const firstLine = doc.lineAt(node.from).number\n const nested = node.node.getChild(\"BulletList\") ?? node.node.getChild(\"OrderedList\")\n const lastLine = doc.lineAt(nested ? nested.from - 1 : Math.min(node.to, doc.length)).number\n\n for (let n = firstLine; n <= lastLine; n++) {\n if (seen.has(n)) continue\n seen.add(n)\n out.push(\n Decoration.line({\n class: \"cm-inplace-li\",\n attributes: { style: `--sl-li-depth:${guides}` },\n }).range(doc.line(n).from),\n )\n }\n },\n })\n}\n","import type { EditorState } from \"@codemirror/state\"\n\n/**\n * Line numbers (1-based) that a selection range currently touches. A node whose\n * line is in this set keeps its raw Markdown markers visible for editing;\n * elsewhere the decoration builder hides them.\n */\nexport function revealedLines(state: EditorState): Set<number> {\n const lines = new Set<number>()\n for (const range of state.selection.ranges) {\n const first = state.doc.lineAt(range.from).number\n const last = state.doc.lineAt(range.to).number\n for (let n = first; n <= last; n++) lines.add(n)\n }\n return lines\n}\n","import type { Tree } from \"@lezer/common\"\nimport type { Text } from \"@codemirror/state\"\n\nexport type { Tree }\n\nconst CODE_NODES = new Set([\"InlineCode\", \"FencedCode\", \"CodeBlock\", \"CodeText\"])\n\n/**\n * Is `pos` inside a code span or code block? Regex-scanned syntax (`[[…]]`,\n * `$…$`) is left literal in those contexts.\n */\nexport function inCodeContext(tree: Tree, pos: number): boolean {\n let node = tree.resolveInner(pos, 1)\n for (;;) {\n if (CODE_NODES.has(node.name)) return true\n const parent = node.parent\n if (!parent) return false\n node = parent\n }\n}\n\n/** Does any line spanned by `[from, to]` currently hold part of a selection? */\nexport function rangeRevealed(revealed: Set<number>, doc: Text, from: number, to: number): boolean {\n const first = doc.lineAt(from).number\n const last = doc.lineAt(to).number\n for (let n = first; n <= last; n++) if (revealed.has(n)) return true\n return false\n}\n","import { syntaxTree } from \"@codemirror/language\"\nimport { type EditorState, type Range, StateField } from \"@codemirror/state\"\nimport { Decoration, type DecorationSet, EditorView, WidgetType } from \"@codemirror/view\"\nimport katex from \"katex\"\nimport { inPlaceConfigFacet } from \"./config\"\nimport { revealedLines } from \"./reveal\"\nimport { inCodeContext, rangeRevealed, type Tree } from \"./scan\"\n\n// The `\\w` / whitespace guards keep \"$100 and $200\" from reading as math.\nconst INLINE_MATH = /(?<![\\w$])\\$(?!\\s)([^\\n$]+?)(?<!\\s)\\$(?![\\w$])/g\nconst ONE_LINE_BLOCK = /(?<![\\w$])\\$\\$([^\\n$]+?)\\$\\$(?![\\w$])/g\nconst ANY_BLOCK = /(?<![\\w$])\\$\\$([^]+?)\\$\\$/g\n\nclass MathWidget extends WidgetType {\n constructor(\n readonly src: string,\n readonly block: boolean,\n ) {\n super()\n }\n\n override eq(other: MathWidget) {\n return other.src === this.src && other.block === this.block\n }\n\n toDOM() {\n const el = document.createElement(this.block ? \"div\" : \"span\")\n el.className = this.block ? \"cm-inplace-math cm-inplace-math-block\" : \"cm-inplace-math\"\n try {\n katex.render(this.src, el, { displayMode: this.block, throwOnError: false })\n } catch {\n el.textContent = this.block ? `$$${this.src}$$` : `$${this.src}$`\n }\n return el\n }\n\n override ignoreEvent() {\n return false\n }\n}\n\n/**\n * Viewport pass for `$…$` and single-line `$$…$$` — the CodeMirror grammar has\n * no math node. Off-caret matches become KaTeX widgets. Multi-line `$$` blocks\n * are handled by `blockMathField` instead (a plugin may not replace line breaks).\n */\nexport function scanInlineMath(\n view: EditorView,\n from: number,\n to: number,\n revealed: Set<number>,\n tree: Tree,\n out: Range<Decoration>[],\n): void {\n const text = view.state.doc.sliceString(from, to)\n if (!text.includes(\"$\")) return\n const { doc } = view.state\n const claimed: Array<[number, number]> = []\n\n for (const m of text.matchAll(ONE_LINE_BLOCK)) {\n const src = (m[1] ?? \"\").trim()\n const start = from + (m.index ?? 0)\n const end = start + (m[0] ?? \"\").length\n if (!src || inCodeContext(tree, start + 2)) continue\n claimed.push([start, end])\n if (rangeRevealed(revealed, doc, start, end)) continue\n out.push(Decoration.replace({ widget: new MathWidget(src, true) }).range(start, end))\n }\n\n for (const m of text.matchAll(INLINE_MATH)) {\n const src = (m[1] ?? \"\").trim()\n const start = from + (m.index ?? 0)\n const end = start + (m[0] ?? \"\").length\n if (!src || inCodeContext(tree, start + 1)) continue\n if (claimed.some(([s, e]) => start >= s && end <= e)) continue\n if (rangeRevealed(revealed, doc, start, end)) continue\n out.push(Decoration.replace({ widget: new MathWidget(src, false) }).range(start, end))\n }\n}\n\n/**\n * Multi-line `$$…$$` blocks, whose delimiters sit alone on their own lines.\n * A state field (not a plugin) because the replacement spans line breaks. Not\n * viewport-scoped — the whole document is scanned — but `$$` blocks are few.\n */\nexport const blockMathField = StateField.define<DecorationSet>({\n create: buildBlockMath,\n update(value, tr) {\n return tr.docChanged || tr.selection ? buildBlockMath(tr.state) : value\n },\n provide: (field) => [\n EditorView.decorations.from(field),\n EditorView.atomicRanges.of((view) => view.state.field(field)),\n ],\n})\n\nfunction buildBlockMath(state: EditorState): DecorationSet {\n if (!state.facet(inPlaceConfigFacet).math) return Decoration.none\n const text = state.doc.toString()\n if (!text.includes(\"$$\")) return Decoration.none\n\n const out: Range<Decoration>[] = []\n const revealed = revealedLines(state)\n const tree = syntaxTree(state)\n\n for (const m of text.matchAll(ANY_BLOCK)) {\n const raw = m[0] ?? \"\"\n const src = (m[1] ?? \"\").trim()\n if (!src || !raw.includes(\"\\n\")) continue\n\n const start = m.index ?? 0\n const end = start + raw.length\n const startLine = state.doc.lineAt(start)\n const endLine = state.doc.lineAt(end)\n const before = state.doc.sliceString(startLine.from, start).trim()\n const after = state.doc.sliceString(end, endLine.to).trim()\n if (before !== \"\" || after !== \"\") continue\n if (inCodeContext(tree, start + 2)) continue\n if (rangeRevealed(revealed, state.doc, start, end)) continue\n\n out.push(\n Decoration.replace({ widget: new MathWidget(src, true), block: true }).range(start, end),\n )\n }\n\n return Decoration.set(out, true)\n}\n","import { type EditorView, WidgetType } from \"@codemirror/view\"\n\n/** Rendered `<hr>` replacing a `---` / `***` / `___` line. */\nexport class HrWidget extends WidgetType {\n override eq() {\n return true\n }\n\n toDOM() {\n const el = document.createElement(\"hr\")\n el.className = \"cm-inplace-hr\"\n return el\n }\n\n override ignoreEvent() {\n return false\n }\n}\n\n/** `•` glyph replacing a `-` / `*` / `+` list marker. */\nexport class BulletWidget extends WidgetType {\n override eq() {\n return true\n }\n\n toDOM() {\n const el = document.createElement(\"span\")\n el.className = \"cm-inplace-bullet\"\n el.textContent = \"•\"\n return el\n }\n\n override ignoreEvent() {\n return false\n }\n}\n\n/**\n * Interactive checkbox replacing a `[ ]` / `[x]` task marker. Toggling it\n * dispatches a one-character change to the source (`\" \"` ⇄ `\"x\"`).\n */\nexport class CheckboxWidget extends WidgetType {\n constructor(readonly checked: boolean) {\n super()\n }\n\n override eq(other: CheckboxWidget) {\n return other.checked === this.checked\n }\n\n toDOM(view: EditorView) {\n const input = document.createElement(\"input\")\n input.type = \"checkbox\"\n input.checked = this.checked\n input.className = \"cm-inplace-checkbox\"\n input.addEventListener(\"mousedown\", (event) => event.stopPropagation())\n input.addEventListener(\"change\", () => {\n const at = view.posAtDOM(input) + 1 // the char between the brackets\n view.dispatch({ changes: { from: at, to: at + 1, insert: this.checked ? \" \" : \"x\" } })\n })\n return input\n }\n\n override ignoreEvent() {\n return true\n }\n}\n","import type { Range, Text } from \"@codemirror/state\"\nimport { Decoration } from \"@codemirror/view\"\nimport type { SyntaxNodeRef } from \"@lezer/common\"\nimport { CALLOUT_HEAD_LINE, calloutBucket } from \"../callout\"\nimport type { ResolvedToggles } from \"./config\"\nimport { BulletWidget, CheckboxWidget, HrWidget } from \"./widgets\"\n\nconst HEADING = /^ATXHeading([1-6])$/\nconst SETEXT = /^SetextHeading([12])$/\nconst BULLET = /^[-*+]$/\n\n/** Inline spans: style the text between the markers, hide the markers off-caret. */\nconst INLINE: Record<string, { mark: string; className: string; toggle: \"emphasis\" | \"code\" }> = {\n StrongEmphasis: { mark: \"EmphasisMark\", className: \"cm-inplace-strong\", toggle: \"emphasis\" },\n Emphasis: { mark: \"EmphasisMark\", className: \"cm-inplace-em\", toggle: \"emphasis\" },\n Strikethrough: { mark: \"StrikethroughMark\", className: \"cm-inplace-strike\", toggle: \"emphasis\" },\n // Grouped with fenced/indented code under the `code` toggle, not `emphasis`.\n InlineCode: { mark: \"CodeMark\", className: \"cm-inplace-code\", toggle: \"code\" },\n}\n\nexport interface NodeCtx {\n doc: Text\n revealed: Set<number>\n /** Lines the caret actually touches. Equals `revealed` except under\n * `reveal: \"never\"`, where `revealed` is empty but this is not — a few\n * constructs (fenced code) still reveal their delimiters on caret entry\n * because there is no other way to see or remove them. */\n caretRevealed: Set<number>\n out: Range<Decoration>[]\n toggles: ResolvedToggles\n /** End of the frontmatter block, or -1. Nodes within are left to `frontmatterField`. */\n fmEnd: number\n /** Lines of a blockquote / callout whose block the caret is in — its `> ` and\n * `[!type]` markers show raw, like a fenced code / `$$` block. Filled by the\n * `Blockquote` handler before its `QuoteMark` children are visited. */\n quoteRevealed: Set<number>\n}\n\n/** Decorate one syntax node. Returns `false` to stop descent, `undefined` to continue. */\nexport function decorateNode(node: SyntaxNodeRef, ctx: NodeCtx): boolean | undefined {\n const { doc, revealed, caretRevealed, out, toggles, fmEnd, quoteRevealed } = ctx\n if (node.to <= fmEnd) return false\n\n const heading = HEADING.exec(node.name)\n if (heading) {\n if (toggles.headings) {\n const line = doc.lineAt(node.from)\n out.push(\n Decoration.line({\n class: `cm-inplace-heading cm-inplace-h${heading[1]}`,\n // Expose the heading to assistive tech and outline tools. Under\n // `reveal: \"never\"` the `#` markers are never in the DOM, so the ARIA\n // role is the only structural cue left. A `role`/`aria-level` on the\n // line stands in for an `<hN>` tag, which CodeMirror's line rendering\n // does not let us emit.\n attributes: { role: \"heading\", \"aria-level\": heading[1]! },\n }).range(line.from),\n )\n if (!revealed.has(line.number)) {\n const hm = node.node.firstChild\n if (hm?.name === \"HeaderMark\") {\n out.push(Decoration.replace({}).range(hm.from, Math.min(hm.to + 1, line.to)))\n }\n }\n }\n return // descend: emphasis / links inside the heading still get decorated\n }\n\n // A Setext heading is text with `===` / `---` on the next line (what you get\n // by typing `---` directly under a line, no blank between). Style the text\n // line like an ATX heading; hide the underline and collapse its row so it\n // reads as one heading, not \"text then a rule\". `caretRevealed`, not\n // `revealed`: the underline shows again whenever the caret is on either line,\n // even under `reveal: \"never\"`, so it stays editable and the caret is visible.\n const setext = SETEXT.exec(node.name)\n if (setext) {\n if (toggles.headings) {\n const textLine = doc.lineAt(node.from)\n out.push(\n Decoration.line({\n class: `cm-inplace-heading cm-inplace-h${setext[1]}`,\n attributes: { role: \"heading\", \"aria-level\": setext[1]! },\n }).range(textLine.from),\n )\n const hm = node.node.getChild(\"HeaderMark\")\n if (hm) {\n const underline = doc.lineAt(hm.from)\n if (!caretRevealed.has(textLine.number) && !caretRevealed.has(underline.number)) {\n out.push(Decoration.line({ class: \"cm-inplace-setext-rule\" }).range(underline.from))\n out.push(Decoration.replace({}).range(hm.from, hm.to))\n }\n }\n }\n return // descend: inline emphasis inside the heading text\n }\n\n const rule = INLINE[node.name]\n if (rule) {\n if (!toggles[rule.toggle]) return\n const marks = node.node.getChildren(rule.mark)\n const open = marks[0]\n const close = marks[marks.length - 1]\n const paired = open && close && open !== close\n const from = paired ? open.to : node.from\n const to = paired ? close.from : node.to\n if (to > from) {\n out.push(Decoration.mark({ class: rule.className }).range(from, to))\n }\n if (paired && !revealed.has(doc.lineAt(node.from).number)) {\n out.push(Decoration.replace({}).range(open.from, open.to))\n out.push(Decoration.replace({}).range(close.from, close.to))\n }\n return\n }\n\n if (node.name === \"Link\") {\n const before = doc.sliceString(Math.max(0, node.from - 1), node.from)\n const after = doc.sliceString(node.to, node.to + 1)\n if (before === \"[\" && after === \"]\") return false // inner of a [[wikilink]]\n if (!toggles.links) return false\n\n // `[!type]` in a callout head parses as a shortcut Link — it belongs to the\n // Blockquote / QuoteMark handling, so don't hide its brackets here.\n const linkLine = doc.lineAt(node.from)\n const calloutHead = CALLOUT_HEAD_LINE.exec(linkLine.text)\n if (\n calloutHead &&\n node.from - linkLine.from < calloutHead[1]!.length + calloutHead[2]!.length\n ) {\n return false\n }\n\n const marks = node.node.getChildren(\"LinkMark\")\n if (marks.length >= 2) {\n const open = marks[0]!\n const shut = marks[1]!\n if (shut.from > open.to) {\n out.push(Decoration.mark({ class: \"cm-inplace-link\" }).range(open.to, shut.from))\n }\n if (!revealed.has(doc.lineAt(node.from).number)) {\n out.push(Decoration.replace({}).range(node.from, open.to))\n out.push(Decoration.replace({}).range(shut.from, node.to))\n }\n }\n return // descend: emphasis / code inside the label still gets its marks hidden\n }\n\n if (node.name === \"HorizontalRule\") {\n if (!toggles.horizontalRule) return false\n const line = doc.lineAt(node.from)\n // `caretRevealed`, not `revealed`: with the caret on the rule line the raw\n // `---` shows again (even under `reveal: \"never\"`), so there is a visible\n // caret to sit on and the marker is editable — the same exception fenced\n // code and `$$` math make.\n if (!caretRevealed.has(line.number)) {\n // Zero the line's own text-row strut; the widget alone sets the height.\n out.push(Decoration.line({ class: \"cm-inplace-hr-line\" }).range(line.from))\n out.push(Decoration.replace({ widget: new HrWidget() }).range(line.from, line.to))\n }\n return false\n }\n\n if (node.name === \"Blockquote\") {\n if (toggles.blockquote) {\n const first = doc.lineAt(node.from).number\n const last = doc.lineAt(Math.min(node.to, doc.length)).number\n const headLine = doc.line(first)\n // `> [!type]` turns the blockquote into a callout: a coloured box, the\n // `[!type]` token hidden off-caret (a `data-callout` label takes its\n // place), the rest of the head line read as the title.\n const head = CALLOUT_HEAD_LINE.exec(headLine.text)\n const kind = head ? calloutBucket(head[3]!) : null\n\n // Caret anywhere in the block → show every `> ` and the `[!type]` token\n // raw for the whole block, the way a fenced code / `$$` block reveals its\n // delimiters. Recorded for the `QuoteMark` children visited next.\n let blockRevealed = false\n for (let n = first; n <= last; n++) if (caretRevealed.has(n)) blockRevealed = true\n if (blockRevealed) for (let n = first; n <= last; n++) quoteRevealed.add(n)\n\n for (let n = first; n <= last; n++) {\n let cls = kind ? `cm-inplace-callout cm-inplace-callout-${kind}` : \"cm-inplace-quote\"\n if (kind && n === first) cls += \" cm-inplace-callout-head\"\n if (kind && n === last) cls += \" cm-inplace-callout-foot\"\n const attributes: Record<string, string> = {}\n if (kind) attributes[\"data-callout\"] = head![3]!.toLowerCase()\n if (kind && blockRevealed) attributes[\"data-revealed\"] = \"\"\n out.push(Decoration.line({ class: cls, attributes }).range(doc.line(n).from))\n }\n if (kind && !blockRevealed && !revealed.has(first)) {\n const tokenFrom = headLine.from + head![1]!.length\n out.push(Decoration.replace({}).range(tokenFrom, tokenFrom + head![2]!.length))\n }\n }\n return // descend for the quoted inline content and each line's QuoteMark\n }\n\n if (node.name === \"QuoteMark\") {\n if (!toggles.blockquote) return false\n const line = doc.lineAt(node.from)\n if (!revealed.has(line.number) && !quoteRevealed.has(line.number)) {\n // Hide `> ` including its trailing space — unless nothing else on the line\n // is visible (an empty quote line, or a callout head with no title). Then\n // hide only `>`, leaving the space as a landable caret home: a fully\n // hidden line has no spot to click or land a vertical arrow on.\n const withSpace = Math.min(node.to + 1, line.to)\n const head = CALLOUT_HEAD_LINE.exec(line.text)\n const rest = head\n ? line.text.slice(head[1]!.length + head[2]!.length)\n : line.text.slice(withSpace - line.from)\n out.push(Decoration.replace({}).range(node.from, rest.trim() === \"\" ? node.to : withSpace))\n }\n return false\n }\n\n if (node.name === \"ListMark\") {\n const text = doc.sliceString(node.from, node.to)\n const line = doc.lineAt(node.from)\n const item = node.node.parent\n const isTask = Boolean(item?.getChild(\"Task\") ?? item?.getChild(\"TaskMarker\"))\n if (revealed.has(line.number)) return false\n if (isTask) {\n // Hide \"- \" so the row reads as just the checkbox and its text.\n if (toggles.tasks) {\n out.push(Decoration.replace({}).range(node.from, Math.min(node.to + 1, line.to)))\n }\n } else if (toggles.lists && BULLET.test(text)) {\n out.push(Decoration.replace({ widget: new BulletWidget() }).range(node.from, node.to))\n }\n return false\n }\n\n if (node.name === \"TaskMarker\") {\n if (!toggles.tasks) return false\n if (!revealed.has(doc.lineAt(node.from).number)) {\n const checked = doc.sliceString(node.from + 1, node.to - 1).toLowerCase() === \"x\"\n out.push(\n Decoration.replace({ widget: new CheckboxWidget(checked) }).range(node.from, node.to),\n )\n }\n return false\n }\n\n if (node.name === \"FencedCode\" || node.name === \"CodeBlock\") {\n if (!toggles.code) return false\n const fenced = node.name === \"FencedCode\"\n const first = doc.lineAt(node.from).number\n const last = doc.lineAt(node.to > node.from ? node.to - 1 : node.to).number\n\n // `caretRevealed`, not `revealed`: a fenced block shows its ``` on caret\n // entry even under `reveal: \"never\"`, because the fence has no on-screen\n // affordance for editing — hiding it for good would trap the block (you\n // could never delete a fence to unwrap it). Parallels the `$$` math block.\n let blockRevealed = false\n for (let n = first; n <= last && !blockRevealed; n++) {\n if (caretRevealed.has(n)) blockRevealed = true\n }\n // Off-caret, a fence line's ``` text is replaced with nothing and the row\n // collapsed to zero line-height, so the container reads as just its padding\n // and the code. Safe for click-to-position because the padding lives on the\n // same line decoration CodeMirror measures — no margin escapes its height map.\n const emptyFences = fenced && last > first && !blockRevealed\n\n for (let n = first; n <= last; n++) {\n const isFence = fenced && (n === first || n === last)\n let cls = \"cm-inplace-mono\"\n if (n === first) cls += \" cm-inplace-code-top\"\n if (n === last) cls += \" cm-inplace-code-bottom\"\n if (isFence) cls += emptyFences ? \" cm-inplace-code-pad\" : \" cm-inplace-fence\"\n const line = doc.line(n)\n out.push(Decoration.line({ class: cls }).range(line.from))\n if (isFence && emptyFences && line.to > line.from) {\n out.push(Decoration.replace({}).range(line.from, line.to))\n }\n }\n return false\n }\n\n return\n}\n","import type { Range } from \"@codemirror/state\"\nimport { Decoration, type EditorView } from \"@codemirror/view\"\nimport { WIKILINK_PATTERN } from \"../wikilink\"\nimport { inCodeContext, type Tree } from \"./scan\"\n\n/**\n * Regex pass for `[[wikilinks]]` — the CodeMirror grammar has no node for them.\n * Collapses each match to its label and tags it with `data-stylo-wikilink`\n * (the delegated click handler in `inPlaceExtension` reads that attribute).\n */\nexport function scanWikilinks(\n view: EditorView,\n from: number,\n to: number,\n revealed: Set<number>,\n tree: Tree,\n out: Range<Decoration>[],\n): void {\n const text = view.state.doc.sliceString(from, to)\n if (!text.includes(\"[[\")) return\n\n for (const match of text.matchAll(WIKILINK_PATTERN)) {\n const [raw = \"\", rawTarget = \"\", rawLabel] = match\n const target = rawTarget.trim()\n const start = from + (match.index ?? 0)\n if (!target || inCodeContext(tree, start + 1)) continue\n\n const end = start + raw.length\n const labelStart = rawLabel != null ? start + 2 + rawTarget.length + 1 : start + 2\n const labelEnd = end - 2\n\n out.push(\n Decoration.mark({\n class: \"cm-inplace-link cm-inplace-wikilink\",\n attributes: { \"data-stylo-wikilink\": target },\n }).range(labelStart, labelEnd),\n )\n if (!revealed.has(view.state.doc.lineAt(start).number)) {\n out.push(Decoration.replace({}).range(start, labelStart))\n out.push(Decoration.replace({}).range(labelEnd, end))\n }\n }\n}\n","import { syntaxTree } from \"@codemirror/language\"\nimport type { Range } from \"@codemirror/state\"\nimport { Decoration, type DecorationSet, type EditorView } from \"@codemirror/view\"\nimport { inPlaceConfigFacet, revealModeFacet } from \"./config\"\nimport { frontmatterRange } from \"./frontmatter\"\nimport { scanListGuides } from \"./list-guides\"\nimport { scanInlineMath } from \"./math\"\nimport { decorateNode } from \"./nodes\"\nimport { revealedLines } from \"./reveal\"\nimport { scanWikilinks } from \"./wikilinks\"\n\n/** Shared empty set for `reveal: \"never\"` — no line ever counts as revealed. */\nconst NO_LINES: Set<number> = new Set()\n\n/** Value carried by the coalesced atomic ranges — never rendered, only its span matters. */\nconst ATOMIC = Decoration.replace({})\n\nexport interface InPlaceDecorations {\n decorations: DecorationSet\n /** Every replacing decoration — the caret steps over these rather than into them. */\n atomic: DecorationSet\n}\n\n/**\n * Build the in-place decoration set for the visible viewport only — the syntax\n * tree is walked across `view.visibleRanges`, never the whole document, so the\n * cost stays bounded on long notes. Decorations are collected unordered and\n * sorted by `Decoration.set`, which tolerates the overlaps that nested emphasis\n * and marker-inside-styled-span produce. Multi-line `$$` blocks and the\n * frontmatter block are handled by their own state fields (a plugin may not\n * replace line breaks).\n */\nexport function buildDecorations(view: EditorView): InPlaceDecorations {\n const out: Range<Decoration>[] = []\n // `reveal: \"never\"` (ADR-007) — no line reveals its markers. Inline / one-line\n // `$…$` math is the deliberate exception: the widget replaces the whole span,\n // so the LaTeX source has no on-screen home, and the caret line is the only\n // way to reach it. It keeps the real reveal set until a dedicated math-source\n // affordance lands (the parallel of the Stage 4 link field). Tracked in\n // ADR-007's rollout log.\n const caretRevealed = revealedLines(view.state)\n const revealed = view.state.facet(revealModeFacet) === \"never\" ? NO_LINES : caretRevealed\n const tree = syntaxTree(view.state)\n const { doc } = view.state\n const toggles = view.state.facet(inPlaceConfigFacet)\n const ctx = {\n doc,\n revealed,\n caretRevealed,\n out,\n toggles,\n fmEnd: frontmatterRange(doc)?.to ?? -1,\n quoteRevealed: new Set<number>(),\n }\n\n for (const range of view.visibleRanges) {\n tree.iterate({\n from: range.from,\n to: range.to,\n enter: (node) => decorateNode(node, ctx),\n })\n if (toggles.wikilinks) scanWikilinks(view, range.from, range.to, revealed, tree, out)\n if (toggles.math) scanInlineMath(view, range.from, range.to, caretRevealed, tree, out)\n scanListGuides(range.from, range.to, tree, doc, toggles, out)\n }\n\n // Every replacing decoration (marker-hiding and widgets) is atomic, so the\n // caret steps over hidden syntax instead of into invisible positions.\n // `EditorView.atomicRanges` only skips a range the caret sits *strictly*\n // inside, so two touching ranges — a `***word***` prefix is `**` then `*` —\n // leave a landable seam between them where arrow keys stop and typing splits\n // the marks. Coalescing touching ranges into one closes that seam.\n const replaces = out\n .filter((r) => r.from < r.to && !r.value.spec.class)\n .sort((a, b) => a.from - b.from || a.to - b.to)\n const atomic: Range<Decoration>[] = []\n for (const r of replaces) {\n // A non-widget replace that covers an entire line (a bare `>` callout line)\n // would leave the caret nowhere to land — clicks bounce and a vertical\n // arrow skips the line. Keep it hidden but not atomic so both edges stay\n // reachable.\n if (!r.value.spec.widget) {\n const line = doc.lineAt(r.from)\n if (r.from === line.from && r.to === line.to) continue\n }\n const last = atomic[atomic.length - 1]\n if (last && r.from <= last.to) {\n if (r.to > last.to) atomic[atomic.length - 1] = ATOMIC.range(last.from, r.to)\n } else {\n atomic.push(ATOMIC.range(r.from, r.to))\n }\n }\n\n return {\n decorations: Decoration.set(out, true),\n atomic: Decoration.set(atomic, true),\n }\n}\n","import type { Extension } from \"@codemirror/state\"\nimport {\n Decoration,\n type DecorationSet,\n EditorView,\n ViewPlugin,\n type ViewUpdate,\n} from \"@codemirror/view\"\nimport { buildDecorations } from \"./decorate\"\n\n/**\n * Owns the in-place decoration set and rebuilds it when the document, the\n * viewport, or the selection changes. Selection is a trigger because the\n * cursor-reveal behaviour depends on where the caret sits.\n *\n * Also provides `EditorView.atomicRanges` covering every replacing decoration —\n * hidden markers and widgets alike — so the caret steps over hidden syntax\n * instead of into invisible positions.\n *\n * Exported (not just the factory) so tests can read the live sets via\n * `view.plugin(inPlacePlugin)`.\n */\nexport const inPlacePlugin = ViewPlugin.fromClass(\n class {\n decorations: DecorationSet\n atomic: DecorationSet\n\n constructor(view: EditorView) {\n const built = buildDecorations(view)\n this.decorations = built.decorations\n this.atomic = built.atomic\n }\n\n update(update: ViewUpdate) {\n if (update.docChanged || update.viewportChanged || update.selectionSet) {\n const built = buildDecorations(update.view)\n this.decorations = built.decorations\n this.atomic = built.atomic\n }\n }\n },\n {\n decorations: (plugin) => plugin.decorations,\n provide: (plugin) =>\n EditorView.atomicRanges.of((view) => view.plugin(plugin)?.atomic ?? Decoration.none),\n },\n)\n\nexport function inPlaceDecorations(): Extension {\n return inPlacePlugin\n}\n","/**\n * ADR-007 Stage 2 (first slice): editing at a hidden marker's edge.\n *\n * Under `reveal: \"never\"` (or off-caret under `\"caret\"`) an inline construct's\n * markers are hidden and atomic. The stock Backspace/Delete skips the whole\n * atomic range and eats the marker itself, stranding its partner — and for a\n * nested `***word***` it strips a level of formatting per keypress.\n *\n * Here the key steps *over* the run of hidden markers and removes the real\n * character beyond them instead: Backspace at the front of a bold word deletes\n * the space before it, the bold stays. The one exception is deleting the last\n * character *inside* a wrapper — the now-empty markers go with it.\n *\n * Arrow keys get the same treatment: `atomicRanges` leaves both edges of a\n * hidden run as caret stops that render at the same point, so a press can look\n * like it did nothing — when a step only crossed hidden markers, take one more.\n * This covers both a plain caret move and `Shift`-extending a selection, which\n * the stock `select*` commands park on the near edge just the same.\n */\n\nimport { syntaxTree } from \"@codemirror/language\"\nimport { EditorSelection, type EditorState, Prec, type Extension } from \"@codemirror/state\"\nimport { type Command, type EditorView, keymap } from \"@codemirror/view\"\nimport type { SyntaxNode } from \"@lezer/common\"\nimport { WIKILINK_PATTERN } from \"../wikilink\"\nimport { activeTableCell } from \"../toolbar/cell-inline\"\nimport { inPlaceConfigFacet, revealModeFacet } from \"./config\"\nimport { inPlacePlugin } from \"./plugin\"\nimport { revealedLines } from \"./reveal\"\n\n/** Paired-marker inline nodes whose markers `decorate.ts` hides. */\nconst WRAP: Record<string, { markType: string; toggle: \"emphasis\" | \"code\" }> = {\n StrongEmphasis: { markType: \"EmphasisMark\", toggle: \"emphasis\" },\n Emphasis: { markType: \"EmphasisMark\", toggle: \"emphasis\" },\n Strikethrough: { markType: \"StrikethroughMark\", toggle: \"emphasis\" },\n InlineCode: { markType: \"CodeMark\", toggle: \"code\" },\n}\n\nexport interface Wrap {\n from: number\n to: number\n contentFrom: number\n contentTo: number\n /** `\"mark\"` — a paired inline mark (`**`, `*`, `~~`, `` ` ``); `\"link\"` — a\n * link or wikilink, whose label is not itself a Markdown context, so a\n * right-click formats the *whole* construct rather than the label. */\n kind: \"mark\" | \"link\"\n}\n\n/** Are inline markers on this line hidden right now? */\nexport function markersHidden(state: EditorState, lineNumber: number): boolean {\n return state.facet(revealModeFacet) === \"never\" || !revealedLines(state).has(lineNumber)\n}\n\n/**\n * Slide `pos` across an unbroken run of hidden inline markers in direction\n * `dir`. A `***word***` prefix (two adjacent hidden replace ranges) is crossed\n * in one step; a solid character or a widget stops it.\n */\nfunction skipHiddenMarkers(view: EditorView, pos: number, dir: -1 | 1): number {\n const set = view.plugin(inPlacePlugin)?.decorations\n if (!set) return pos\n const end = dir < 0 ? 0 : view.state.doc.length\n let p = pos\n for (let moved = true; moved;) {\n moved = false\n set.between(Math.min(p, end), Math.max(p, end), (from, to, deco) => {\n if (from >= to || deco.spec.widget || deco.spec.class) return\n if (dir < 0 ? to === p : from === p) {\n p = dir < 0 ? from : to\n moved = true\n }\n })\n }\n return p\n}\n\n/**\n * The hidden-marker inline construct enclosing `pos`, or `null`. With\n * `emphasisOnly`, only the paired-mark constructs whose *both* delimiters are\n * hidden count (strong / emphasis / strike / inline code) — links and wikilinks\n * keep a directly editable label, so their edges are not boundary-escaped.\n *\n * By default the construct's markers must be hidden right now (boundary editing\n * only applies then); `ignoreReveal` drops that check for callers that just want\n * the span — the right-click menu selecting the whole phrase, which should work\n * whether or not the caret has revealed the line.\n */\nexport function wrapAt(\n state: EditorState,\n pos: number,\n emphasisOnly = false,\n ignoreReveal = false,\n): Wrap | null {\n const line = state.doc.lineAt(pos)\n if (!ignoreReveal && !markersHidden(state, line.number)) return null\n const toggles = state.facet(inPlaceConfigFacet)\n const tree = syntaxTree(state)\n\n for (const bias of [-1, 1] as const) {\n for (let node: SyntaxNode | null = tree.resolveInner(pos, bias); node; node = node.parent) {\n const rule = WRAP[node.name]\n if (rule) {\n if (!toggles[rule.toggle]) break\n const marks = node.getChildren(rule.markType)\n const open = marks[0]\n const close = marks[marks.length - 1]\n if (!open || !close || open === close) break\n return {\n from: node.from,\n to: node.to,\n contentFrom: open.to,\n contentTo: close.from,\n kind: \"mark\",\n }\n }\n if (node.name === \"Link\") {\n if (emphasisOnly) break\n if (state.doc.sliceString(Math.max(0, node.from - 1), node.from) === \"[\") break // [[wiki]] inner\n if (!toggles.links) break\n const marks = node.getChildren(\"LinkMark\")\n if (marks.length < 2) break\n return {\n from: node.from,\n to: node.to,\n contentFrom: marks[0]!.to,\n contentTo: marks[1]!.from,\n kind: \"link\",\n }\n }\n }\n }\n\n // Wikilinks have no grammar node — scan the caret line.\n if (toggles.wikilinks && !emphasisOnly) {\n for (const m of line.text.matchAll(WIKILINK_PATTERN)) {\n const from = line.from + (m.index ?? 0)\n const to = from + m[0].length\n if (pos < from || pos > to) continue\n const target = m[1] ?? \"\"\n const labelled = m[2] != null\n return {\n from,\n to,\n contentFrom: from + 2 + (labelled ? target.length + 1 : 0),\n contentTo: to - 2,\n kind: \"link\",\n }\n }\n }\n return null\n}\n\n/** Backspace/Delete that steps over hidden markers instead of eating them. */\nconst deleteAcrossMarkers =\n (dir: -1 | 1): Command =>\n (view: EditorView): boolean => {\n if (activeTableCell(view)) return false\n const sel = view.state.selection.main\n if (!sel.empty) return false\n const { state } = view\n if (!markersHidden(state, state.doc.lineAt(sel.head).number)) return false\n\n const solid = skipHiddenMarkers(view, sel.head, dir)\n if (solid === sel.head) return false // no hidden marker in the way — let the default run\n\n const doc = state.doc\n if (dir < 0 ? solid <= 0 : solid >= doc.length) return true // nothing beyond — swallow\n\n let from = dir < 0 ? solid - 1 : solid\n let to = dir < 0 ? solid : solid + 1\n\n // Removing the last character inside a wrapper leaves empty markers — take\n // the wrapper with it, then keep walking out: a nested `***x***` empties its\n // outer `**…**` too, and stopping after one level would strand a bare\n // `****` / ``` `` ``` / `[]()`. Probing at `from` (once it is the run's outer\n // edge) is what lets `resolveInner` climb to the enclosing construct.\n for (\n let w = wrapAt(state, from);\n w && from <= w.contentFrom && to >= w.contentTo && w.contentTo > w.contentFrom;\n w = wrapAt(state, from)\n ) {\n if (w.from >= from && w.to <= to) break // no growth — the run is fully covered\n from = Math.min(from, w.from)\n to = Math.max(to, w.to)\n }\n\n view.dispatch({\n changes: { from, to, insert: \"\" },\n selection: { anchor: from },\n userEvent: dir < 0 ? \"delete.backward\" : \"delete.forward\",\n scrollIntoView: true,\n })\n return true\n }\n\n/** Backspace that steps over a hidden marker rather than stranding it. */\nexport const deleteAcrossMarkerBackward: Command = deleteAcrossMarkers(-1)\n/** Delete — the forward mirror. */\nexport const deleteAcrossMarkerForward: Command = deleteAcrossMarkers(1)\n\n/** Is `[from, to)` covered entirely by hidden marker replacements (so the two\n * ends render at the same screen point)? */\nfunction onlyHiddenMarkers(view: EditorView, from: number, to: number): boolean {\n if (to <= from) return false\n const set = view.plugin(inPlacePlugin)?.decorations\n if (!set) return false\n let covered = from\n set.between(from, to, (a, b, deco) => {\n if (deco.spec.widget || deco.spec.class || b <= a) return\n if (a <= covered) covered = Math.max(covered, b)\n })\n return covered >= to\n}\n\n/**\n * Arrow-key motion that doesn't \"stick\" on a hidden marker run. `atomicRanges`\n * leaves *both* edges of a run as caret stops, and they render at the same\n * point, so one arrow press looks like it did nothing. When a step only crossed\n * hidden markers, take one more so every press moves the caret visibly — even\n * when that extra step leaves the line, which is what a bold word at column 0\n * needs (the run sits against the line start, so the only visible landing is the\n * end of the line above). `onlyHiddenMarkers` never spans a line break — a\n * newline is not a hidden marker — so the guard there is enough.\n *\n * With `extend` the selection head moves and the anchor stays put — the same\n * fix for `Shift`-arrow, whose stock command also parks on the near edge.\n */\nconst arrowAcrossMarkers =\n (forward: boolean, extend: boolean): Command =>\n (view: EditorView): boolean => {\n if (activeTableCell(view)) return false\n const sel = view.state.selection.main\n if (!extend && !sel.empty) return false\n if (!markersHidden(view.state, view.state.doc.lineAt(sel.head).number)) return false\n\n let moved = view.moveByChar(sel, forward)\n const lo = Math.min(sel.head, moved.head)\n const hi = Math.max(sel.head, moved.head)\n if (onlyHiddenMarkers(view, lo, hi)) moved = view.moveByChar(moved, forward)\n if (moved.head === sel.head) return false\n const range = extend\n ? EditorSelection.range(sel.anchor, moved.head)\n : EditorSelection.cursor(moved.head)\n view.dispatch({ selection: range, userEvent: \"select\" })\n return true\n }\n\n/** Plain caret step across a hidden marker run (leftward). */\nexport const arrowAcrossMarkerLeft: Command = arrowAcrossMarkers(false, false)\n/** Plain caret step — the forward mirror. */\nexport const arrowAcrossMarkerRight: Command = arrowAcrossMarkers(true, false)\n/** `Shift`-extend the selection head across a hidden marker run (leftward). */\nexport const selectAcrossMarkerLeft: Command = arrowAcrossMarkers(false, true)\n/** `Shift`-extend — the forward mirror. */\nexport const selectAcrossMarkerRight: Command = arrowAcrossMarkers(true, true)\n\nexport const inPlaceEditBoundaries: Extension = Prec.high(\n keymap.of([\n { key: \"Backspace\", run: deleteAcrossMarkerBackward },\n { key: \"Delete\", run: deleteAcrossMarkerForward },\n { key: \"ArrowLeft\", run: arrowAcrossMarkerLeft },\n { key: \"ArrowRight\", run: arrowAcrossMarkerRight },\n { key: \"Shift-ArrowLeft\", run: selectAcrossMarkerLeft },\n { key: \"Shift-ArrowRight\", run: selectAcrossMarkerRight },\n ]),\n)\n","/**\n * Maps the shared toolbar command set onto rows for the in-place right-click\n * menu. One shape everywhere (Obsidian style): the link rows, then Format /\n * Paragraph / Insert submenus, then clipboard. Every command already carries\n * its own `run` / `isActive` / `disabled`, so an item that can't apply where\n * the caret sits is greyed, not hidden — the menu shape stays put.\n */\n\nimport type { EditorState } from \"@codemirror/state\"\nimport type { EditorView } from \"@codemirror/view\"\nimport type { MenuGroupId, ToolbarCommandId } from \"../types\"\nimport { activeTableCell } from \"../toolbar/cell-inline\"\nimport { BUILTIN_BY_ID } from \"../toolbar/commands\"\nimport { fenceInfoAt, fencedCodeActive } from \"../toolbar/fence\"\nimport { ICON_PATHS } from \"../toolbar/icon-paths\"\nimport { linkPartsIn, wikiLinkAtIn, wikiLinkPartsIn } from \"../toolbar/inline-ops\"\nimport { linkOpenFacet, menuGroupsFacet, selectionUIFacet } from \"./config\"\nimport type { MenuAction, MenuField, MenuRow, MenuSubmenu } from \"./context-menu\"\nimport { selectionOffsets } from \"./table-cell-dom\"\n\n/** Menu glyph for a command id — headings share one, the rest map by id. */\nconst iconFor = (id: ToolbarCommandId): string | undefined =>\n id === \"h1\" || id === \"h2\" || id === \"h3\" ? ICON_PATHS.heading : ICON_PATHS[id]\n\n/** Obsidian's three grouped submenus, adapted to the commands Stylo has. */\nconst FORMAT_MARK_IDS: ToolbarCommandId[] = [\"bold\", \"italic\", \"strike\"]\nconst FORMAT_CODE_IDS: ToolbarCommandId[] = [\"code\", \"math\"]\nconst PARA_LIST_IDS: ToolbarCommandId[] = [\"bulletList\", \"orderedList\", \"task\"]\nconst PARA_HEADING_IDS: ToolbarCommandId[] = [\"h1\", \"h2\", \"h3\"]\nconst INSERT_INLINE_IDS: ToolbarCommandId[] = [\"table\", \"hr\"]\nconst INSERT_BLOCK_IDS: ToolbarCommandId[] = [\"codeBlock\", \"mathBlock\", \"frontmatter\"]\n\n/**\n * A non-empty text selection inside a focused editable table cell. The cell is a\n * `contenteditable` surface, so this selection lives in the DOM, not in\n * `state.selection` — but the inline commands route through `runInlineInCell`,\n * so the Format group still applies.\n */\nexport function cellHasSelection(view: EditorView): boolean {\n const cell = activeTableCell(view)\n if (!cell) return false\n const { from, to } = selectionOffsets(cell)\n return to > from\n}\n\n/**\n * `inCell`: the selection is a table cell's DOM range, not `state.selection`, so\n * `cmd.disabled` / `cmd.isActive` (which read `state.selection`, collapsed here)\n * would grey every item out. The inline commands route through `runInlineInCell`\n * regardless, so force them live — same call the floating selection bar makes.\n */\nconst toAction = (view: EditorView, id: ToolbarCommandId, inCell = false): MenuAction | null => {\n const cmd = BUILTIN_BY_ID[id]\n if (!cmd) return null\n return {\n label: cmd.title,\n icon: iconFor(id),\n active: inCell ? false : Boolean(cmd.isActive?.(view.state)),\n disabled: inCell ? false : Boolean(cmd.disabled?.(view.state)),\n onSelect: () => {\n cmd.run(view)\n view.focus()\n },\n }\n}\n\nconst actions = (\n view: EditorView,\n ids: ToolbarCommandId[],\n dropDisabled = false,\n inCell = false,\n): MenuAction[] => {\n const out: MenuAction[] = []\n for (const id of ids) {\n const a = toAction(view, id, inCell)\n if (a && !(dropDisabled && a.disabled)) out.push(a)\n }\n return out\n}\n\nconst clipboardRows = (view: EditorView): MenuRow[] => {\n const doc = view.contentDOM.ownerDocument\n const exec = (cmd: \"cut\" | \"copy\") => () => {\n view.focus()\n try {\n doc.execCommand(cmd)\n } catch {\n /* not permitted — the keyboard shortcut still works */\n }\n }\n // Menu Paste needs async clipboard read; without it there is no user-gesture\n // path from a button. Rather than a live row that silently no-ops, show it\n // disabled and point at the shortcut, which always works.\n const clipboard = view.dom.ownerDocument.defaultView?.navigator?.clipboard\n const canPaste = typeof clipboard?.readText === \"function\"\n const paste = () => {\n const cell = activeTableCell(view)\n if (!cell) view.focus()\n clipboard\n ?.readText()\n .then((text) => {\n if (!text) return\n if (cell) doc.execCommand(\"insertText\", false, text)\n else view.dispatch(view.state.replaceSelection(text))\n })\n .catch(() => {\n /* clipboard read denied — the keyboard shortcut still works */\n })\n }\n return [\n { label: \"Cut\", icon: ICON_PATHS.cut, onSelect: exec(\"cut\") },\n { label: \"Copy\", icon: ICON_PATHS.copy, onSelect: exec(\"copy\") },\n canPaste\n ? { label: \"Paste\", icon: ICON_PATHS.paste, onSelect: paste }\n : {\n label: \"Paste\",\n icon: ICON_PATHS.paste,\n disabled: true,\n title: \"Paste with the keyboard shortcut\",\n onSelect: () => {},\n },\n ]\n}\n\n/** The `(...)` destination for a link — angle-bracketed when it has whitespace\n * or parens, so `[a](b c)` (invalid Markdown) becomes `[a](<b c>)`. */\nconst linkDest = (url: string): string => {\n const bare = url.trim().replace(/^<([^]*)>$/, \"$1\")\n return /[\\s()]/.test(bare) ? `<${bare.replace(/[<>]/g, \"\")}>` : bare\n}\n/** Strip angle brackets for display in the URL input. */\nconst bareUrl = (url: string): string => url.replace(/^<([^]*)>$/, \"$1\")\n\n/**\n * The `[text](url)` or `[[target|label]]` that the selection sits in, with its\n * display text and full span. Applying a link or wikilink to such a selection\n * then *replaces* that construct instead of nesting a new one inside it (which\n * produces malformed Markdown). `null` when the selection is in neither.\n */\nfunction inlineLinkHost(\n state: EditorState,\n sel: { from: number; to: number },\n): { from: number; to: number; text: string } | null {\n const line = state.doc.lineAt(sel.from)\n if (state.doc.lineAt(sel.to).number !== line.number) return null\n const a = sel.from - line.from\n const b = sel.to - line.from\n const link = linkPartsIn(line.text, a) ?? linkPartsIn(line.text, b)\n if (link) return { from: line.from + link.from, to: line.from + link.to, text: link.label }\n const wiki = wikiLinkAtIn(line.text, a) ?? wikiLinkAtIn(line.text, b)\n if (wiki) return { from: line.from + wiki.from, to: line.from + wiki.to, text: wiki.label }\n return null\n}\n\n/**\n * The \"Add external link\" row — an editable `[text](url)` URL field. Prefilled,\n * with Open / Remove and the label \"Edit external link\", when the caret sits in\n * an existing `[text](url)`; otherwise an empty field that wraps the selection\n * (or the word the menu just selected) on submit.\n */\nexport function linkRow(view: EditorView): MenuField {\n const { state } = view\n const sel = state.selection.main\n const line = state.doc.lineAt(sel.head)\n const parts = linkPartsIn(line.text, sel.head - line.from)\n\n if (parts) {\n const from = line.from + parts.from\n const to = line.from + parts.to\n const urlFrom = line.from + parts.urlFrom\n const urlTo = line.from + parts.urlTo\n const openHref = state.facet(linkOpenFacet)\n const rowActions: MenuAction[] = []\n if (openHref && parts.url) {\n rowActions.push({\n label: \"Open link\",\n icon: ICON_PATHS.link,\n onSelect: () => openHref(parts.url),\n })\n }\n rowActions.push({\n label: \"Remove link\",\n onSelect: () => {\n view.dispatch({\n changes: { from, to, insert: parts.label },\n selection: { anchor: from, head: from + parts.label.length },\n })\n view.focus()\n },\n })\n return {\n field: true,\n label: \"Edit external link\",\n icon: ICON_PATHS.link,\n value: bareUrl(parts.url),\n placeholder: \"https://…\",\n onSubmit: (url) => {\n view.dispatch({ changes: { from: urlFrom, to: urlTo, insert: linkDest(url) } })\n view.focus()\n },\n actions: rowActions,\n }\n }\n\n // A selection already inside a link / wikilink: swap that whole construct for\n // the new link rather than nesting one inside it.\n const host = inlineLinkHost(state, sel)\n const from = host ? host.from : sel.from\n const to = host ? host.to : sel.to\n const label = (host ? host.text : state.sliceDoc(sel.from, sel.to)) || \"link\"\n return {\n field: true,\n label: \"Add external link\",\n icon: ICON_PATHS.link,\n value: \"\",\n placeholder: \"https://…\",\n onSubmit: (url) => {\n view.dispatch({\n changes: { from, to, insert: `[${label}](${linkDest(url)})` },\n selection: { anchor: from + 1, head: from + 1 + label.length },\n })\n view.focus()\n },\n }\n}\n\n/**\n * The \"Add link\" row — an editable `[[target]]` field for an internal link.\n * Prefilled, with Remove and the label \"Edit link\", when the caret sits in an\n * existing `[[target|label]]`; otherwise an empty field that wraps the\n * selection (or the word the menu just selected) on submit.\n */\nexport function wikiLinkRow(view: EditorView): MenuField {\n const { state } = view\n const sel = state.selection.main\n const line = state.doc.lineAt(sel.head)\n const parts = wikiLinkPartsIn(line.text, sel.head - line.from)\n\n if (parts) {\n const from = line.from + parts.from\n const to = line.from + parts.to\n const targetFrom = line.from + parts.targetFrom\n const targetTo = line.from + parts.targetTo\n const display = parts.label || parts.target\n return {\n field: true,\n label: \"Edit link\",\n icon: ICON_PATHS.wikilink,\n value: parts.target,\n placeholder: \"note or path\",\n onSubmit: (target) => {\n if (target) {\n view.dispatch({ changes: { from: targetFrom, to: targetTo, insert: target } })\n }\n view.focus()\n },\n actions: [\n {\n label: \"Remove link\",\n onSelect: () => {\n view.dispatch({\n changes: { from, to, insert: display },\n selection: { anchor: from, head: from + display.length },\n })\n view.focus()\n },\n },\n ],\n }\n }\n\n // A selection already inside a link / wikilink: swap that whole construct\n // rather than nesting a `[[…]]` inside it.\n const host = inlineLinkHost(state, sel)\n const from = host ? host.from : sel.from\n const to = host ? host.to : sel.to\n const label = host ? host.text : state.sliceDoc(sel.from, sel.to)\n return {\n field: true,\n label: \"Add link\",\n icon: ICON_PATHS.wikilink,\n value: \"\",\n placeholder: \"note or path\",\n onSubmit: (target) => {\n const t = target || label || \"target\"\n const insert = !target || target === label ? `[[${t}]]` : `[[${target}|${label}]]`\n view.dispatch({\n changes: { from, to, insert },\n selection: { anchor: from + 2, head: from + 2 + (target || t).length },\n })\n view.focus()\n },\n }\n}\n\nconst submenu = (\n label: string,\n icon: string | undefined,\n rows: MenuRow[],\n disabled = false,\n): MenuSubmenu => ({ label, icon, rows, disabled })\n\n/**\n * The \"Language\" row shown when the caret is in a fenced code block: an\n * editable info string (` ```ts `), plus **Remove code block** to unwrap it.\n * The opening fence line is hidden in the seamless canvas, so this is the way\n * to reach the language at all.\n */\nexport function codeBlockRow(view: EditorView): MenuField {\n const info = fenceInfoAt(view.state)\n return {\n field: true,\n label: \"Language\",\n icon: ICON_PATHS.codeBlock,\n value: info?.lang ?? \"\",\n placeholder: \"ts, python, …\",\n onSubmit: (lang) => {\n if (info) view.dispatch({ changes: { from: info.from, to: info.to, insert: lang.trim() } })\n view.focus()\n },\n actions: [\n {\n label: \"Remove code block\",\n onSelect: () => {\n BUILTIN_BY_ID.codeBlock?.run(view)\n view.focus()\n },\n },\n ],\n }\n}\n\n/** Bold / Italic / Strikethrough, then inline code + inline math. */\nconst formatGroup = (view: EditorView, inCell = false): MenuRow[] => [\n ...actions(view, FORMAT_MARK_IDS, false, inCell),\n \"separator\",\n ...actions(view, FORMAT_CODE_IDS, false, inCell),\n]\n\n/**\n * Rows for a non-empty selection inside an editable table cell: the Format\n * submenu (forced live — see `toAction`) and clipboard, gated by `menuGroups`.\n * Shared by the canvas menu and the table widget's own structural menu, which\n * appends these under its row / column / align actions.\n */\nexport function cellSelectionRows(view: EditorView): MenuRow[] {\n const groups = view.state.facet(menuGroupsFacet)\n const rows: MenuRow[] = []\n if (groups.includes(\"format\")) {\n pushGroup(rows, [submenu(\"Format\", ICON_PATHS.format, formatGroup(view, true))])\n }\n if (groups.includes(\"clipboard\")) pushGroup(rows, clipboardRows(view))\n return rows\n}\n\n/** List types, then heading levels + Body, then quote. Obsidian's \"Paragraph\". */\nconst paragraphGroup = (view: EditorView): MenuRow[] => [\n ...actions(view, PARA_LIST_IDS),\n \"separator\",\n ...actions(view, [...PARA_HEADING_IDS, \"body\"]),\n \"separator\",\n ...actions(view, [\"quote\"]),\n]\n\n/** New-block actions. Each still carries its own enabled state. */\nconst insertGroup = (view: EditorView): MenuRow[] => [\n ...actions(view, INSERT_INLINE_IDS),\n \"separator\",\n ...actions(view, INSERT_BLOCK_IDS),\n]\n\n/** Append `add` as its own separator-delimited group. */\nfunction pushGroup(rows: MenuRow[], add: MenuRow[]): void {\n if (!add.length) return\n if (rows.length) rows.push(\"separator\")\n rows.push(...add)\n}\n\n/**\n * The right-click menu. `menuGroupsFacet` picks and orders the top-level groups\n * (`link` / `format` / `paragraph` / `insert` / `clipboard`); `selectionUI`\n * independently decides whether `link` and `format` live here or on the floating\n * bar. A table-cell selection and a fenced-code caret are focused contexts that\n * ignore the ordering and offer only what applies.\n */\nexport function menuRows(view: EditorView): MenuRow[] {\n const { state } = view\n const groups = state.facet(menuGroupsFacet)\n const has = (g: MenuGroupId) => groups.includes(g)\n\n // A table cell only supports inline formatting — no block or insert there.\n // (The editable-table widget shows these under its own structural rows; this\n // path stands in for a cell selection reaching the canvas menu directly.)\n if (cellHasSelection(view)) return cellSelectionRows(view)\n\n // A fenced code block is a literal context — offer only its language and an\n // unwrap, plus clipboard.\n if (fencedCodeActive(state)) {\n const rows: MenuRow[] = [codeBlockRow(view)]\n if (has(\"clipboard\")) pushGroup(rows, clipboardRows(view))\n return rows\n }\n\n const sel = state.selection.main\n const line = state.doc.lineAt(sel.head)\n // Insert drops a brand-new block — the whole submenu is disabled off an empty\n // line (a table mid-paragraph would split it) rather than every item greyed.\n const insertOk = line.text.trim() === \"\"\n // Nothing to format at a bare caret with no word — wrapping there just drops\n // an empty `****`, which shows as literal marks. The right-click menu selects\n // the word first, so this only bites on a blank line or in whitespace.\n const formatOk = !sel.empty || Boolean(state.wordAt(sel.head))\n // `link` / `format` are on the floating bar / toolbar unless the menu owns them.\n const marksHere = state.facet(selectionUIFacet) === \"menu\"\n\n const rows: MenuRow[] = []\n for (const g of groups) {\n if (g === \"link\" && marksHere) pushGroup(rows, [wikiLinkRow(view), linkRow(view)])\n else if (g === \"format\" && marksHere)\n pushGroup(rows, [submenu(\"Format\", ICON_PATHS.format, formatGroup(view), !formatOk)])\n else if (g === \"paragraph\")\n pushGroup(rows, [submenu(\"Paragraph\", ICON_PATHS.paragraph, paragraphGroup(view))])\n else if (g === \"insert\")\n pushGroup(rows, [submenu(\"Insert\", ICON_PATHS.insert, insertGroup(view), !insertOk)])\n else if (g === \"clipboard\") pushGroup(rows, clipboardRows(view))\n }\n return rows\n}\n","import katex from \"katex\"\nimport { WIKILINK_PATTERN } from \"../wikilink\"\n\n/**\n * Render a single line of inline Markdown to DOM nodes — the subset that can\n * appear in a table cell: `` `code` ``, `$math$`, `[[wiki]]`, `[text](url)`,\n * `***both***`, `**bold**`, `*em*`, `~~strike~~`. Block constructs are out of\n * scope (a cell is one line). Reuses the `.cm-inplace-*` classes so cell text\n * matches the rest of the canvas, and tags wikilinks with `data-stylo-wikilink`\n * so the existing delegated click handler picks them up.\n *\n * `code` and `math` win first and keep their contents literal; everything else\n * recurses so `**a `code` b**` styles the bold and the code.\n */\nexport function renderInline(text: string): DocumentFragment {\n const frag = document.createDocumentFragment()\n fill(frag, text)\n return frag\n}\n\ninterface Rule {\n re: RegExp\n build: (m: RegExpMatchArray) => Node\n}\n\nconst RULES: Rule[] = [\n {\n re: /`([^`\\n]+)`/,\n build: (m) => el(\"code\", \"cm-inplace-code\", document.createTextNode(m[1]!)),\n },\n {\n // inline math: no digit/`$` touching the fences, no space just inside them\n re: /(?<![\\d$])\\$(?!\\s)([^$\\n]+?)(?<!\\s)\\$(?![\\d$])/,\n build: (m) => {\n const span = el(\"span\", \"cm-inplace-math\")\n katex.render(m[1]!, span as HTMLElement, { throwOnError: false })\n return span\n },\n },\n {\n // a non-global copy — the shared pattern carries `g` and its own lastIndex\n re: new RegExp(WIKILINK_PATTERN.source),\n build: (m) => {\n const span = el(\"span\", \"cm-inplace-wikilink\", document.createTextNode(m[2] || m[1] || \"\"))\n ;(span as HTMLElement).dataset.styloWikilink = m[1] ?? \"\"\n return span\n },\n },\n {\n re: /\\[([^\\]\\n]*)\\]\\(([^)\\n]*)\\)/,\n build: (m) => {\n const a = el(\"a\", \"cm-inplace-link\") as HTMLAnchorElement\n a.href = m[2] ?? \"\"\n a.append(inlineFrag(m[1] ?? \"\"))\n return a\n },\n },\n {\n re: /\\*\\*\\*([^*\\n]+?)\\*\\*\\*/,\n build: (m) => el(\"strong\", \"cm-inplace-strong\", el(\"em\", \"cm-inplace-em\", inlineFrag(m[1]!))),\n },\n {\n re: /\\*\\*([^\\n]+?)\\*\\*/,\n build: (m) => el(\"strong\", \"cm-inplace-strong\", inlineFrag(m[1]!)),\n },\n {\n re: /~~([^\\n]+?)~~/,\n build: (m) => el(\"span\", \"cm-inplace-strike\", inlineFrag(m[1]!)),\n },\n {\n re: /(?<!\\*)\\*(?!\\*|\\s)([^\\n]+?)(?<!\\s)\\*(?!\\*)/,\n build: (m) => el(\"em\", \"cm-inplace-em\", inlineFrag(m[1]!)),\n },\n]\n\nfunction el(tag: string, className: string, ...children: Node[]): Element {\n const node = document.createElement(tag)\n node.className = className\n node.append(...children)\n return node\n}\n\nfunction inlineFrag(text: string): DocumentFragment {\n const frag = document.createDocumentFragment()\n fill(frag, text)\n return frag\n}\n\n/** Tokenise `text` into `parent`, honouring the earliest-matching rule. */\nfunction fill(parent: Node, text: string): void {\n while (text) {\n let at = -1\n let hit: { rule: Rule; m: RegExpMatchArray } | null = null\n for (const rule of RULES) {\n const m = rule.re.exec(text)\n if (m && (at < 0 || m.index! < at)) {\n at = m.index!\n hit = { rule, m }\n }\n }\n if (!hit) {\n parent.appendChild(document.createTextNode(text))\n return\n }\n if (at > 0) parent.appendChild(document.createTextNode(text.slice(0, at)))\n parent.appendChild(hit.rule.build(hit.m))\n text = text.slice(at + hit.m[0].length)\n }\n}\n","/**\n * Touch / pen long-press detection.\n *\n * A mouse gets the context menu from the native `contextmenu` event on\n * right-click. A touch device has no dependable equivalent — iOS Safari in\n * particular races its own selection callout on a long-press and usually wins,\n * so `contextmenu` never arrives. This runs a plain timer instead: pointer\n * down, hold still for `delay` ms, and `onLongPress` fires with the contact\n * point.\n *\n * Mouse pointers are ignored — they already have `contextmenu`. Moving past\n * `slop` pixels, or lifting / cancelling before the timer, aborts the press.\n * `cancel()` aborts a pending press without detaching — the caller uses it when\n * a real `contextmenu` lands first (Android synthesises one from the same\n * gesture) so the two paths can't both open the menu.\n *\n * The defaults are tuned for a fingertip, not a stylus: a finger cannot hold a\n * contact point to within a few pixels for half a second, so `slop` is generous\n * and `delay` sits just under the ~500 ms where iOS Safari commits to its own\n * long-press selection.\n */\n\nexport interface LongPressOptions {\n /** Hold time before the press completes. Default 450 ms. */\n delay?: number\n /** Movement (from the contact point, on either axis) that aborts it. Default 20 px. */\n slop?: number\n /** Fired when the hold completes: viewport coordinates and the element the\n * finger first landed on. */\n onLongPress: (x: number, y: number, target: EventTarget | null) => void\n}\n\nexport interface LongPressHandle {\n /** Abort a press in progress; keeps the listeners attached. */\n cancel: () => void\n /** Abort and detach every listener. */\n dispose: () => void\n}\n\n/** Attach long-press detection to `el`. */\nexport function attachLongPress(el: HTMLElement, opts: LongPressOptions): LongPressHandle {\n const delay = opts.delay ?? 450\n const slop = opts.slop ?? 20\n let timer: ReturnType<typeof setTimeout> | null = null\n let startX = 0\n let startY = 0\n\n const cancel = () => {\n if (timer != null) {\n clearTimeout(timer)\n timer = null\n }\n }\n\n const onDown = (e: PointerEvent) => {\n if (e.pointerType === \"mouse\") return\n cancel()\n startX = e.clientX\n startY = e.clientY\n const target = e.target\n timer = setTimeout(() => {\n timer = null\n opts.onLongPress(startX, startY, target)\n }, delay)\n }\n\n const onMove = (e: PointerEvent) => {\n if (timer == null) return\n if (Math.abs(e.clientX - startX) > slop || Math.abs(e.clientY - startY) > slop) cancel()\n }\n\n el.addEventListener(\"pointerdown\", onDown)\n el.addEventListener(\"pointermove\", onMove)\n el.addEventListener(\"pointerup\", cancel)\n el.addEventListener(\"pointercancel\", cancel)\n\n return {\n cancel,\n dispose: () => {\n cancel()\n el.removeEventListener(\"pointerdown\", onDown)\n el.removeEventListener(\"pointermove\", onMove)\n el.removeEventListener(\"pointerup\", cancel)\n el.removeEventListener(\"pointercancel\", cancel)\n },\n }\n}\n","/**\n * A pointer-positioned menu shell for the in-place canvas. It owns the popup\n * element, its placement, one level of flyout submenu, and dismissal (outside\n * press, Escape, scroll). It knows nothing about editor commands; the caller\n * passes plain rows with `onSelect` callbacks.\n */\n\nimport { iconSvg } from \"../toolbar/icon-paths\"\n\nexport interface MenuAction {\n label: string\n /** Stroke-path data for a leading glyph (see `toolbar/icon-paths`). */\n icon?: string\n /** Rendered with emphasis when true. */\n active?: boolean\n /** Shown greyed and not selectable. */\n disabled?: boolean\n /** Native `title` tooltip — e.g. why a disabled row is disabled. */\n title?: string\n onSelect: () => void\n}\n\nexport interface MenuSubmenu {\n label: string\n icon?: string\n rows: MenuRow[]\n /** Greyed, and its flyout never opens. */\n disabled?: boolean\n}\n\n/** A row whose flyout is a single text input plus optional action buttons. */\nexport interface MenuField {\n field: true\n label: string\n icon?: string\n value: string\n placeholder?: string\n onSubmit: (value: string) => void\n actions?: MenuAction[]\n}\n\nexport type MenuRow = MenuAction | MenuSubmenu | MenuField | \"separator\"\n\nexport interface ContextMenu {\n /** Append once to a stable container (typically `document.body`). */\n readonly el: HTMLElement\n readonly isOpen: boolean\n /** Render `rows` and show the menu at a viewport point, clamped on-screen. */\n show: (rows: MenuRow[], x: number, y: number) => void\n /** Show a single field panel directly, with no wrapping menu row. */\n showField: (field: MenuField, x: number, y: number) => void\n hide: () => void\n /** Remove the element and drop document listeners. */\n destroy: () => void\n}\n\nconst isSubmenu = (r: MenuRow): r is MenuSubmenu => typeof r !== \"string\" && \"rows\" in r\nconst isField = (r: MenuRow): r is MenuField => typeof r !== \"string\" && \"field\" in r\n\nexport function createContextMenu(doc: Document, className = \"cm-inplace-menu\"): ContextMenu {\n const win = doc.defaultView\n // A non-interactive full-viewport layer; the panels inside it take pointers.\n const root = doc.createElement(\"div\")\n root.className = className\n root.setAttribute(\"contenteditable\", \"false\")\n root.hidden = true\n\n let flyout: HTMLElement | null = null\n let unbind: (() => void) | null = null\n\n // A flyout is sticky: once open it stays until a different flyout row opens,\n // a plain row is hovered, or the whole menu is dismissed. No hover-out timer\n // — that made the panel close mid-approach on a real mouse path.\n const clearFlyout = () => {\n flyout?.remove()\n flyout = null\n }\n\n const hide = () => {\n if (root.hidden) return\n clearFlyout()\n root.hidden = true\n root.replaceChildren()\n unbind?.()\n unbind = null\n }\n\n // A mousedown inside the menu must not blur the editor before the click fires.\n const holdFocus = (el: HTMLElement) =>\n el.addEventListener(\"mousedown\", (e) => {\n e.preventDefault()\n e.stopPropagation()\n })\n\n const label = (el: HTMLElement, text: string, icon?: string) => {\n if (icon) el.appendChild(iconSvg(doc, icon))\n const span = doc.createElement(\"span\")\n span.textContent = text\n el.appendChild(span)\n }\n\n const actionButton = (a: MenuAction): HTMLElement => {\n const b = doc.createElement(\"button\")\n b.type = \"button\"\n b.className = `${className}-item`\n label(b, a.label, a.icon)\n if (a.title) b.title = a.title\n if (a.active) b.dataset.active = \"\"\n if (a.disabled) {\n b.disabled = true\n } else {\n holdFocus(b)\n // Hovering a plain row dismisses any open flyout (but not one it belongs\n // to — a flyout's own rows call this too and must be ignored).\n b.addEventListener(\"pointerenter\", () => {\n if (!b.closest(`.${className}-panel[data-for]`)) clearFlyout()\n })\n b.addEventListener(\"click\", (e) => {\n e.stopPropagation()\n hide()\n a.onSelect()\n })\n }\n return b\n }\n\n // A row that opens a flyout panel — used by both submenus and field rows. The\n // flyout is sticky (opens on hover or click, no auto-close timer).\n const flyoutRow = (\n text: string,\n icon: string | undefined,\n build: () => HTMLElement,\n disabled = false,\n ) => {\n const b = doc.createElement(\"button\")\n b.type = \"button\"\n b.className = `${className}-item ${className}-parent`\n label(b, text, icon)\n if (disabled) {\n b.disabled = true\n return b\n }\n holdFocus(b)\n const open = () => {\n if (flyout?.dataset.for === text) return\n clearFlyout()\n const panel = build()\n panel.dataset.for = text\n root.appendChild(panel)\n placeFlyout(panel, b.getBoundingClientRect())\n flyout = panel\n // `preventScroll` — a focus-induced scroll would trip the menu's own\n // dismiss-on-scroll handler and close it the instant the field opens.\n ;(panel.querySelector(\"input\") as HTMLInputElement | null)?.focus({ preventScroll: true })\n }\n b.addEventListener(\"pointerenter\", open)\n b.addEventListener(\"click\", (e) => {\n e.stopPropagation()\n open()\n })\n return b\n }\n\n const fieldPanel = (f: MenuField): HTMLElement => {\n const panel = doc.createElement(\"div\")\n panel.className = `${className}-panel`\n const input = doc.createElement(\"input\")\n input.type = \"text\"\n input.className = `${className}-input`\n input.value = f.value\n if (f.placeholder) input.placeholder = f.placeholder\n input.addEventListener(\"keydown\", (e) => {\n if (e.key !== \"Enter\") return\n e.preventDefault()\n const v = input.value.trim()\n hide()\n f.onSubmit(v)\n })\n panel.appendChild(input)\n for (const a of f.actions ?? []) panel.appendChild(actionButton(a))\n return panel\n }\n\n const buildPanel = (rows: MenuRow[]): HTMLElement => {\n const panel = doc.createElement(\"div\")\n panel.className = `${className}-panel`\n for (const r of rows) {\n if (r === \"separator\") {\n const sep = doc.createElement(\"div\")\n sep.className = `${className}-sep`\n panel.appendChild(sep)\n } else if (isSubmenu(r)) {\n panel.appendChild(flyoutRow(r.label, r.icon, () => buildPanel(r.rows), r.disabled))\n } else if (isField(r)) {\n panel.appendChild(flyoutRow(r.label, r.icon, () => fieldPanel(r)))\n } else {\n panel.appendChild(actionButton(r))\n }\n }\n return panel\n }\n\n // Place a fixed-position panel at (x, y), nudged back on-screen on overflow.\n const place = (panel: HTMLElement, x: number, y: number) => {\n const vw = win?.innerWidth ?? 0\n const vh = win?.innerHeight ?? 0\n panel.style.left = \"0\"\n panel.style.top = \"0\"\n const { width, height } = panel.getBoundingClientRect()\n panel.style.left = `${Math.max(4, Math.min(x, vw - width - 4))}px`\n panel.style.top = `${Math.max(4, Math.min(y, vh - height - 4))}px`\n }\n\n // A flyout sits to the right of its parent row; if it would run off-screen it\n // flips to the left instead of being shoved back over the menu (which would\n // leave a gap the pointer has to cross, closing it mid-approach).\n const placeFlyout = (panel: HTMLElement, host: DOMRect) => {\n const vw = win?.innerWidth ?? 0\n const vh = win?.innerHeight ?? 0\n panel.style.left = \"0\"\n panel.style.top = \"0\"\n const { width, height } = panel.getBoundingClientRect()\n const right = host.right - 4\n const left = right + width > vw - 4 ? host.left - width + 4 : right\n panel.style.left = `${Math.max(4, left)}px`\n panel.style.top = `${Math.max(4, Math.min(host.top - 4, vh - height - 4))}px`\n }\n\n const armDismiss = () => {\n const armedAt = Date.now()\n const outside = (e: Event) => !root.contains(e.target as Node)\n const onDown = (e: Event) => {\n if (outside(e)) hide()\n }\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") hide()\n }\n // A scroll dismisses the menu — but not one in the first moments after it\n // opens. A touch long-press is one continuous gesture that routinely emits\n // an incidental scroll (iOS's own long-press handling, a hair of finger\n // drift, a focus-driven viewport shift) in the frames right after the menu\n // appears; without this grace it is gone before the finger lifts. A\n // deliberate scroll-away lands well after the window. Also skips scrolls\n // from inside the menu — e.g. the URL input scrolling its own text.\n const onScroll = (e: Event) => {\n if (Date.now() - armedAt < 350) return\n if (outside(e)) hide()\n }\n // `pointerdown` as well as `mousedown` — a touch tap outside fires only the\n // former, and without it the menu could not be dismissed on a touch device.\n doc.addEventListener(\"pointerdown\", onDown, true)\n doc.addEventListener(\"mousedown\", onDown, true)\n doc.addEventListener(\"keydown\", onKey, true)\n doc.addEventListener(\"scroll\", onScroll, true)\n unbind = () => {\n doc.removeEventListener(\"pointerdown\", onDown, true)\n doc.removeEventListener(\"mousedown\", onDown, true)\n doc.removeEventListener(\"keydown\", onKey, true)\n doc.removeEventListener(\"scroll\", onScroll, true)\n }\n }\n\n const show = (rows: MenuRow[], x: number, y: number) => {\n hide()\n const main = buildPanel(rows)\n root.appendChild(main)\n root.hidden = false\n place(main, x, y)\n armDismiss()\n }\n\n // Show one field panel directly (no wrapping menu) — the selection bar's link\n // button opens the URL editor this way.\n const showField = (f: MenuField, x: number, y: number) => {\n hide()\n const panel = fieldPanel(f)\n root.appendChild(panel)\n root.hidden = false\n place(panel, x, y)\n ;(panel.querySelector(\"input\") as HTMLInputElement | null)?.focus({ preventScroll: true })\n armDismiss()\n }\n\n return {\n el: root,\n get isOpen() {\n return !root.hidden\n },\n show,\n showField,\n hide,\n destroy: () => {\n hide()\n root.remove()\n },\n }\n}\n","import type { Align } from \"../toolbar/table-grid\"\nimport { createContextMenu, type ContextMenu, type MenuRow } from \"./context-menu\"\n\n/** A structural edit requested from an edge `+` or the cell context menu. */\nexport type StructOp =\n | { kind: \"insertColumn\"; at: number; focus: [number, number] }\n | { kind: \"deleteColumn\"; at: number; focus: [number, number] }\n | { kind: \"insertRow\"; at: number; focus: [number, number] }\n | { kind: \"deleteRow\"; at: number; focus: [number, number] }\n | { kind: \"align\"; at: number; value: Align }\n\nexport interface GizmoHost {\n /** Current grid shape, read when the menu opens. */\n dims: () => { cols: number; rows: number; alignAt: (c: number) => Align }\n /** Apply a structural edit to the model and reserialise. */\n run: (op: StructOp) => void\n}\n\nexport interface TableGizmos {\n /** Overlay to append inside the positioned table wrapper. */\n el: HTMLElement\n /** Re-place the edge `+` buttons against the current `<table>` layout. */\n layout: (table: HTMLTableElement) => void\n /** Open the structural menu for `cell` at a screen point. `extra` rows (the\n * Format group for a cell selection) are appended below the structural set. */\n openFor: (cell: HTMLElement, x: number, y: number, extra?: MenuRow[]) => void\n /** Drop the document-level menu listeners. */\n destroy: () => void\n}\n\n/**\n * Editable-table affordances, Obsidian style: a `+` on the right edge (append\n * column) and the bottom edge (append row), shown on hover, plus a right-click /\n * long-press context menu on any cell for the full structural set. No persistent\n * per-row / per-column chrome — the menu is contextual to the clicked cell, so it\n * stays in reach on a table of any height. The menu reuses the canvas's shared\n * `ContextMenu` shell (`context-menu.ts`); only the edge strips are bespoke.\n */\nexport function createTableGizmos(doc: Document, host: GizmoHost): TableGizmos {\n const el = doc.createElement(\"div\")\n el.className = \"cm-inplace-table-gizmos\"\n el.setAttribute(\"contenteditable\", \"false\")\n\n const menu: ContextMenu = createContextMenu(doc)\n\n const button = (className: string, label: string, onClick: () => void) => {\n const b = doc.createElement(\"button\")\n b.type = \"button\"\n b.className = className\n b.setAttribute(\"aria-label\", label)\n b.addEventListener(\"mousedown\", (e) => {\n e.preventDefault()\n e.stopPropagation()\n })\n b.addEventListener(\"click\", (e) => {\n e.stopPropagation()\n onClick()\n })\n return b\n }\n\n /**\n * A full-edge hit strip: the whole right edge adds a column, the whole bottom\n * edge adds a row — click anywhere along it, Obsidian style. The strip is\n * invisible until the pointer is over it; a CSS-drawn `+` cross is its only\n * mark (a font glyph never sits at the optical centre of its box).\n */\n const edge = (axis: \"col\" | \"row\", label: string, onClick: () => void) => {\n const strip = button(`cm-inplace-tg-edge cm-inplace-tg-add${axis}`, label, onClick)\n const plus = doc.createElement(\"span\")\n plus.className = \"cm-inplace-tg-plus\"\n strip.appendChild(plus)\n return strip\n }\n\n const addCol = edge(\"col\", \"Add column\", () =>\n host.run({ kind: \"insertColumn\", at: host.dims().cols, focus: [1, host.dims().cols] }),\n )\n const addRow = edge(\"row\", \"Add row\", () =>\n host.run({ kind: \"insertRow\", at: host.dims().rows, focus: [host.dims().rows, 0] }),\n )\n el.append(addCol, addRow, menu.el)\n\n const rows = (r: number, c: number, extra: MenuRow[] = []): MenuRow[] => {\n const { cols, rows: rowCount, alignAt } = host.dims()\n const item = (label: string, op: StructOp, active = false): MenuRow => ({\n label,\n active,\n onSelect: () => host.run(op),\n })\n const list: MenuRow[] = [\n item(\"Insert row above\", { kind: \"insertRow\", at: r, focus: [r, c] }),\n item(\"Insert row below\", { kind: \"insertRow\", at: r + 1, focus: [r + 1, c] }),\n item(\"Insert column left\", { kind: \"insertColumn\", at: c, focus: [r, c] }),\n item(\"Insert column right\", { kind: \"insertColumn\", at: c + 1, focus: [r, c + 1] }),\n ]\n if (r > 0 && rowCount > 2) {\n list.push(item(\"Delete row\", { kind: \"deleteRow\", at: r, focus: [r, c] }))\n }\n if (cols > 1) {\n list.push(item(\"Delete column\", { kind: \"deleteColumn\", at: c, focus: [r, c - 1] }))\n }\n list.push(\"separator\")\n for (const value of [\"left\", \"center\", \"right\"] as const) {\n list.push(item(`Align ${value}`, { kind: \"align\", at: c, value }, alignAt(c) === value))\n }\n if (extra.length) list.push(\"separator\", ...extra)\n return list\n }\n\n const openFor = (cell: HTMLElement, x: number, y: number, extra?: MenuRow[]) => {\n menu.show(rows(Number(cell.dataset.r), Number(cell.dataset.c), extra), x, y)\n }\n\n const layout = (table: HTMLTableElement) => {\n const trs = [...table.rows]\n if (!trs.length) return\n const base = el.getBoundingClientRect()\n const top = trs[0]!.getBoundingClientRect().top - base.top\n const bottom = trs[trs.length - 1]!.getBoundingClientRect().bottom - base.top\n const rect = table.getBoundingClientRect()\n const left = rect.left - base.left\n const right = rect.right - base.left\n // Identical clearance from the grid edge on both strips — the table's own\n // padding is asymmetric (`1em 0 1.4em`), so the gap is added here, not in CSS.\n const GAP = 3\n // right edge, spanning the grid height\n addCol.style.left = `${right + GAP}px`\n addCol.style.top = `${top}px`\n addCol.style.height = `${bottom - top}px`\n // bottom edge, spanning the grid width\n addRow.style.left = `${left}px`\n addRow.style.top = `${bottom + GAP}px`\n addRow.style.width = `${right - left}px`\n }\n\n return { el, layout, openFor, destroy: () => menu.destroy() }\n}\n","import type { Align } from \"../toolbar/table-grid\"\n\n/**\n * The editable table's grid model: `rows` is `[header, ...body]` as raw cell\n * strings, `aligns` is one entry per column. Every operation here mutates both\n * in place and keeps them dimensionally consistent, so the widget can hand the\n * result straight to `serializeGrid`. The guards keep the table well-formed —\n * always a header, at least one body row, at least one column.\n */\nexport interface GridModel {\n rows: string[][]\n aligns: Align[]\n}\n\nconst cols = (g: GridModel): number => g.aligns.length\n\n/** Insert a blank column before index `at` (`at === cols` appends). */\nexport function insertColumn(g: GridModel, at: number): void {\n const i = Math.max(0, Math.min(at, cols(g)))\n for (const row of g.rows) row.splice(i, 0, \"\")\n g.aligns.splice(i, 0, \"\")\n}\n\n/** Remove column `at`, unless it is the only one. */\nexport function deleteColumn(g: GridModel, at: number): void {\n if (cols(g) <= 1 || at < 0 || at >= cols(g)) return\n for (const row of g.rows) row.splice(at, 1)\n g.aligns.splice(at, 1)\n}\n\n/** Insert a blank body row before index `at` (`at === rows.length` appends). */\nexport function insertRow(g: GridModel, at: number): void {\n const i = Math.max(1, Math.min(at, g.rows.length)) // never above the header\n g.rows.splice(i, 0, new Array(cols(g)).fill(\"\"))\n}\n\n/** Remove row `at`, unless it is the header or the last remaining body row. */\nexport function deleteRow(g: GridModel, at: number): void {\n if (at <= 0 || at >= g.rows.length || g.rows.length <= 2) return\n g.rows.splice(at, 1)\n}\n\n/** Set column `c`'s alignment (`\"\"` clears it back to default). */\nexport function setAlign(g: GridModel, c: number, align: Align): void {\n if (c >= 0 && c < cols(g)) g.aligns[c] = align\n}\n","import { Annotation } from \"@codemirror/state\"\nimport { EditorView, WidgetType } from \"@codemirror/view\"\nimport { handleCellShortcut } from \"../toolbar/cell-inline\"\nimport { type Align, serializeGrid } from \"../toolbar/table-grid\"\nimport { cellHasSelection, cellSelectionRows } from \"./context-menu-actions\"\nimport { renderInline } from \"./inline-md\"\nimport {\n gridOf,\n offsetFromPoint,\n placeCaret,\n renderedCaretOffset,\n selectWordAtPoint,\n trimGrid,\n unescapePipe,\n} from \"./table-cell-dom\"\nimport { attachLongPress, type LongPressHandle } from \"./long-press\"\nimport { createTableGizmos, type StructOp, type TableGizmos } from \"./table-gizmos\"\nimport {\n deleteColumn,\n deleteRow,\n type GridModel,\n insertColumn,\n insertRow,\n setAlign,\n} from \"./table-structure\"\n\n/** Marks a transaction that came from an editable table widget's own DOM. */\nexport const fromTableWidget = Annotation.define<boolean>()\n\nexport interface ParsedTable {\n head: string[]\n body: string[][]\n aligns: Align[]\n}\n\n/**\n * A GFM table rendered as an editable `<table>` (`inPlace.table === \"cells\"`).\n * The widget owns its DOM while mounted and keeps `rows` — the raw cell strings —\n * as its source of truth. A cell shows its Markdown **rendered** (`renderInline`)\n * while unfocused and swaps to the **raw source** as a plain text node while it\n * has focus, mirroring the per-line reveal on the main canvas. Every edit\n * re-serializes `rows` into the document with the `fromTableWidget` annotation\n * so `tableField` remaps rather than rebuilds and DOM focus survives.\n *\n * The widget never stores its document range — a serialize dispatch shifts it —\n * so `bounds()` re-derives it from `posAtDOM` plus a scan of contiguous pipe\n * lines every time it is needed.\n */\nexport class EditableTableWidget extends WidgetType {\n private table: HTMLTableElement | null = null\n private rows: string[][]\n private editing: HTMLTableCellElement | null = null\n private syncing = false\n /** Rendered-text offset from the mousedown that is bringing a cell into edit. */\n private pendingOffset: number | null = null\n private current: string[][]\n private gizmos: TableGizmos | null = null\n private longPress: LongPressHandle | null = null\n /** When a long-press last opened the structural menu; a `contextmenu` the\n * browser synthesises from the same gesture and lands within the window is\n * swallowed rather than re-opening it. */\n private longPressAt = 0\n\n constructor(readonly data: ParsedTable) {\n super()\n this.rows = gridOf(data)\n this.current = trimGrid(this.rows)\n }\n\n override eq(other: EditableTableWidget) {\n // While this instance owns mounted DOM, force CodeMirror to run the new\n // instance's `toDOM` on a rebuild rather than swapping the instance behind\n // the live DOM (which leaves the new one un-initialised — `table` null).\n // Widget-originated edits use the `fromTableWidget` annotation path, which\n // never calls `eq`, so this only bites on a genuine external reload.\n if (this.table) return false\n return JSON.stringify(this.current) === JSON.stringify(other.current)\n }\n\n override ignoreEvent() {\n return true\n }\n\n private cols(): number {\n return this.data.aligns.length\n }\n\n /**\n * The table's current `[from, to]` in the document, derived from the DOM.\n * `posAtDOM` may land on any line of the widget, so the scan grows the span in\n * both directions across contiguous non-blank pipe lines.\n */\n private bounds(view: EditorView): { from: number; to: number } {\n const doc = view.state.doc\n const pipe = (n: number) => {\n const t = doc.line(n).text\n return t.trim() !== \"\" && t.includes(\"|\")\n }\n let first = doc.lineAt(view.posAtDOM(this.table!)).number\n let last = first\n while (first > 1 && pipe(first - 1)) first--\n while (last < doc.lines && pipe(last + 1)) last++\n return { from: doc.line(first).from, to: doc.line(last).to }\n }\n\n private cellAt(r: number, c: number): HTMLTableCellElement | null {\n if (!this.table) return null\n const row = r === 0 ? this.table.tHead!.rows[0]! : this.table.tBodies[0]!.rows[r - 1]\n return (row?.cells[c] as HTMLTableCellElement) ?? null\n }\n\n private coords(cell: HTMLTableCellElement): { r: number; c: number } {\n return { r: Number(cell.dataset.r), c: Number(cell.dataset.c) }\n }\n\n /** Draw `cell` from `rows[r][c]` — raw text when `raw`, rendered otherwise. */\n private paint(cell: HTMLTableCellElement, raw: boolean) {\n const { r, c } = this.coords(cell)\n const text = this.rows[r]?.[c] ?? \"\"\n cell.replaceChildren(\n raw ? cell.ownerDocument.createTextNode(text) : renderInline(unescapePipe(text)),\n )\n }\n\n private mkCell(r: number, c: number, header: boolean): HTMLTableCellElement {\n const el = document.createElement(header ? \"th\" : \"td\")\n el.className = \"cm-inplace-tcell\"\n // The attribute (not just the IDL prop) makes the cell a focus target, so\n // `document.activeElement` becomes the cell and CodeMirror's `updateSelection`\n // stops forcing the DOM caret back to the (atomic) widget boundary.\n el.setAttribute(\"contenteditable\", \"true\")\n el.dataset.r = String(r)\n el.dataset.c = String(c)\n const a = this.data.aligns[c]\n if (a) el.style.textAlign = a\n this.paint(el, false)\n return el\n }\n\n /** Rebuild `<thead>` / `<tbody>` from the current grid model. */\n private renderCells() {\n const table = this.table!\n table.replaceChildren()\n const hr = table.createTHead().insertRow()\n for (let c = 0; c < this.cols(); c++) hr.appendChild(this.mkCell(0, c, true))\n const tbody = table.createTBody()\n for (let r = 1; r < this.rows.length; r++) {\n const tr = tbody.insertRow()\n for (let c = 0; c < this.cols(); c++) tr.appendChild(this.mkCell(r, c, false))\n }\n }\n\n private appendRow() {\n insertRow(this.model(), this.rows.length)\n this.renderCells()\n this.gizmos?.layout(this.table!)\n }\n\n private model(): GridModel {\n return { rows: this.rows, aligns: this.data.aligns }\n }\n\n /** Apply a structural edit from a gizmo, rebuild, restore focus, reserialize. */\n private runOp(view: EditorView, op: StructOp) {\n if (!this.table) return // a destroyed instance whose menu is still on screen\n const g = this.model()\n if (op.kind === \"insertColumn\") insertColumn(g, op.at)\n else if (op.kind === \"deleteColumn\") deleteColumn(g, op.at)\n else if (op.kind === \"insertRow\") insertRow(g, op.at)\n else if (op.kind === \"deleteRow\") deleteRow(g, op.at)\n else setAlign(g, op.at, g.aligns[op.at] === op.value ? \"\" : op.value)\n\n // Reserialise first so the document is canonical, then rebuild our own DOM\n // from the settled model — no window where the two disagree.\n this.editing = null\n this.sync(view)\n this.renderCells()\n this.gizmos?.layout(this.table!)\n if (op.kind !== \"align\") {\n const r = Math.max(0, Math.min(op.focus[0], this.rows.length - 1))\n const c = Math.max(0, Math.min(op.focus[1], this.cols() - 1))\n this.cellAt(r, c)?.focus()\n }\n }\n\n /** Commit `cell`'s edited text into `rows` and, unless it keeps focus, re-render it. */\n private finish(cell: HTMLTableCellElement, keepRaw: boolean) {\n const { r, c } = this.coords(cell)\n if (this.rows[r]) this.rows[r]![c] = (cell.textContent ?? \"\").replace(/\\r?\\n/g, \" \")\n if (!keepRaw) this.paint(cell, false)\n }\n\n private onFocusIn(event: FocusEvent) {\n const cell = (event.target as HTMLElement).closest<HTMLTableCellElement>(\"td, th\")\n if (!cell || cell === this.editing) return\n // Prefer the offset from the mousedown that started this focus; the DOM\n // selection isn't placed yet when `focusin` fires from a click.\n const offset = this.pendingOffset ?? renderedCaretOffset(cell)\n this.pendingOffset = null\n if (this.editing) this.finish(this.editing, false)\n this.editing = cell\n this.paint(cell, true)\n placeCaret(cell, offset)\n }\n\n private onFocusOut(event: FocusEvent) {\n if (this.syncing || !this.editing) return\n const to = event.relatedTarget as Node | null\n if (to && this.table?.contains(to)) return // moving to another cell — its focusin handles it\n this.finish(this.editing, false)\n this.editing = null\n }\n\n /** The selection as (row, col, anchor offset, head offset) within the editing cell. */\n private readCaret(): { r: number; c: number; offset: number; head: number } | null {\n if (!this.editing) return null\n const { r, c } = this.coords(this.editing)\n const sel = this.editing.ownerDocument.getSelection()\n const text = this.editing.firstChild\n const end = (this.editing.textContent ?? \"\").length\n const offset = sel?.anchorNode === text ? (sel?.anchorOffset ?? 0) : end\n const head = sel?.focusNode === text ? (sel?.focusOffset ?? offset) : offset\n return { r, c, offset, head }\n }\n\n private writeCaret(caret: { r: number; c: number; offset: number; head: number }) {\n const cell = this.cellAt(caret.r, caret.c)\n if (cell) placeCaret(cell, caret.offset, caret.head)\n }\n\n /** Serialize `rows` into the document. */\n private sync(view: EditorView) {\n if (!this.table) return\n const caret = this.readCaret()\n const text = serializeGrid({ rows: this.rows, aligns: this.data.aligns })\n this.current = trimGrid(this.rows)\n const { from, to } = this.bounds(view)\n if (view.state.sliceDoc(from, to) === text) return\n\n // `syncing` is true only across the synchronous dispatch, so a blur that\n // CodeMirror's reconciliation triggers there is ignored, while a real user\n // focusout right after still re-renders the cell.\n this.syncing = true\n view.dispatch({\n changes: { from, to, insert: text },\n annotations: fromTableWidget.of(true),\n userEvent: \"input\",\n })\n this.syncing = false\n if (caret) {\n this.writeCaret(caret)\n requestAnimationFrame(() => {\n if (this.table && caret) this.writeCaret(caret)\n })\n }\n }\n\n private onKey(event: KeyboardEvent, view: EditorView) {\n const cell = (event.target as HTMLElement).closest<HTMLTableCellElement>(\"td, th\")\n if (!cell || !this.table) return\n // Mod-b / Mod-i / Mod-k never reach CodeMirror's keymap from inside a\n // widget (`ignoreEvent`), so the widget applies them to the cell itself.\n if (handleCellShortcut(event, cell)) {\n event.stopPropagation()\n return\n }\n const { r, c } = this.coords(cell)\n const lastRow = this.rows.length - 1\n\n if (event.key === \"Tab\") {\n event.preventDefault()\n event.stopPropagation()\n const flat = r * this.cols() + c + (event.shiftKey ? -1 : 1)\n if (flat < 0) return\n if (flat >= this.rows.length * this.cols()) {\n if (event.shiftKey) return\n this.appendRow()\n this.cellAt(lastRow + 1, 0)?.focus()\n this.sync(view)\n return\n }\n this.cellAt(Math.floor(flat / this.cols()), flat % this.cols())?.focus()\n return\n }\n if (event.key === \"Enter\") {\n event.preventDefault()\n event.stopPropagation()\n if (r < lastRow) return this.cellAt(r + 1, c)?.focus()\n this.appendRow()\n this.cellAt(lastRow + 1, c)?.focus()\n this.sync(view)\n return\n }\n const cols = this.cols()\n const exitBelow = () => {\n const { to } = this.bounds(view)\n view.focus()\n view.dispatch({ selection: { anchor: Math.min(to + 1, view.state.doc.length) } })\n }\n const exitAbove = () => {\n const { from } = this.bounds(view)\n view.focus()\n view.dispatch({ selection: { anchor: Math.max(from - 1, 0) } })\n }\n const enterCell = (flat: number, offset: number) => {\n const target = this.cellAt(Math.floor(flat / cols), flat % cols)\n if (!target) return\n this.pendingOffset = offset\n target.focus()\n }\n\n // Vertical arrows walk the column; past the first / last row they leave the\n // table. The caret's text offset rides along so a press feels continuous.\n if (event.key === \"ArrowDown\") {\n event.preventDefault()\n event.stopPropagation()\n if (r === lastRow) exitBelow()\n else enterCell((r + 1) * cols + c, this.readCaret()?.offset ?? 0)\n return\n }\n if (event.key === \"ArrowUp\") {\n event.preventDefault()\n event.stopPropagation()\n if (r === 0) exitAbove()\n else enterCell((r - 1) * cols + c, this.readCaret()?.offset ?? 0)\n return\n }\n // Left / Right cross into the neighbouring cell only from the text edge —\n // mid-text (or with a range selected) the browser moves within the cell.\n if (event.key === \"ArrowRight\" || event.key === \"ArrowLeft\") {\n const back = event.key === \"ArrowLeft\"\n const caret = this.readCaret()\n if (!caret || caret.offset !== caret.head) return\n if (back ? caret.offset > 0 : caret.offset < (cell.textContent ?? \"\").length) return\n event.preventDefault()\n event.stopPropagation()\n const flat = r * cols + c + (back ? -1 : 1)\n if (flat < 0) return exitAbove()\n if (flat >= this.rows.length * cols) return exitBelow()\n enterCell(flat, back ? (this.rows[Math.floor(flat / cols)]?.[flat % cols] ?? \"\").length : 0)\n return\n }\n }\n\n /**\n * Focus the first (top-left) or last (bottom-right) cell — keyboard entry into\n * the table from the line above or below. Returns `false` when the DOM isn't\n * mounted, so the caller can fall back to stock cursor motion.\n */\n focusEdge(edge: \"first\" | \"last\"): boolean {\n if (!this.table) return false\n const r = edge === \"first\" ? 0 : this.rows.length - 1\n const c = edge === \"first\" ? 0 : this.cols() - 1\n const cell = this.cellAt(r, c)\n if (!cell) return false\n this.pendingOffset = edge === \"first\" ? 0 : (this.rows[r]?.[c] ?? \"\").length\n cell.focus()\n return true\n }\n\n /** Open the structural menu for the cell at a screen point, from a right-click\n * or a long-press. */\n private openCellMenuAt(\n view: EditorView,\n clientX: number,\n clientY: number,\n target: HTMLElement | null,\n ) {\n const cell = target?.closest<HTMLTableCellElement>(\"td, th\")\n if (!cell) return\n if (this.editing === cell && !cellHasSelection(view)) {\n selectWordAtPoint(cell, clientX, clientY)\n }\n const extra = cellHasSelection(view) ? cellSelectionRows(view) : undefined\n this.gizmos?.openFor(cell, clientX, clientY, extra)\n }\n\n toDOM(view: EditorView) {\n const wrap = document.createElement(\"div\")\n wrap.className = \"cm-inplace-table-wrap\"\n const table = document.createElement(\"table\")\n this.table = table\n this.editing = null\n table.className = \"cm-inplace-table cm-inplace-table-edit\"\n this.renderCells()\n\n // Keep the pointer event away from CodeMirror's delegated handler: it would\n // snap the click to the atomic widget boundary and pull focus back to\n // `.cm-content`. Not `preventDefault` — the browser still focuses the cell.\n table.addEventListener(\"mousedown\", (e) => {\n e.stopPropagation()\n const cell = (e.target as HTMLElement).closest<HTMLTableCellElement>(\"td, th\")\n this.pendingOffset =\n cell && cell !== this.editing ? offsetFromPoint(cell, e.clientX, e.clientY) : null\n })\n table.addEventListener(\"focusin\", (e) => this.onFocusIn(e))\n table.addEventListener(\"focusout\", (e) => this.onFocusOut(e))\n const onEdit = (cell: HTMLTableCellElement | null) => {\n if (!cell) return\n // `focusin` normally sets `editing` first; adopt the cell if an `input`\n // somehow beat it (or a test dispatches one directly).\n this.editing = cell\n this.finish(cell, true)\n this.sync(view)\n }\n table.addEventListener(\"input\", (e) => {\n if ((e as InputEvent).isComposing) return\n onEdit((e.target as HTMLElement).closest<HTMLTableCellElement>(\"td, th\"))\n })\n table.addEventListener(\"compositionend\", (e) =>\n onEdit((e.target as HTMLElement).closest<HTMLTableCellElement>(\"td, th\")),\n )\n table.addEventListener(\"keydown\", (e) => this.onKey(e, view))\n table.addEventListener(\"paste\", (e) => {\n e.preventDefault()\n const text = (e.clipboardData?.getData(\"text/plain\") ?? \"\").replace(/\\r?\\n/g, \" \")\n document.execCommand(\"insertText\", false, text)\n })\n // Right-click, or a long-press on touch, opens the structural menu for the\n // cell under the pointer. In the cell being edited, a press with no\n // selection first selects the word under the pointer — the same affordance\n // the canvas menu gives — so the Format group (and clipboard) can be\n // appended below the row / column / align actions and one menu covers both\n // the table and the word.\n table.addEventListener(\"contextmenu\", (e) => {\n const cell = (e.target as HTMLElement).closest<HTMLTableCellElement>(\"td, th\")\n if (!cell) return\n e.preventDefault()\n e.stopPropagation()\n this.longPress?.cancel()\n if (Date.now() - this.longPressAt < 700) return\n this.openCellMenuAt(view, e.clientX, e.clientY, e.target as HTMLElement | null)\n })\n this.longPress = attachLongPress(table, {\n onLongPress: (x, y, t) => {\n this.longPressAt = Date.now()\n this.openCellMenuAt(view, x, y, t as HTMLElement | null)\n },\n })\n\n this.gizmos = createTableGizmos(document, {\n dims: () => ({\n cols: this.cols(),\n rows: this.rows.length,\n alignAt: (c) => this.data.aligns[c] ?? \"\",\n }),\n run: (op) => this.runOp(view, op),\n })\n wrap.append(table, this.gizmos.el)\n wrap.addEventListener(\"mouseenter\", () => this.gizmos?.layout(table))\n requestAnimationFrame(() => this.gizmos?.layout(table))\n return wrap\n }\n\n override destroy() {\n this.longPress?.dispose()\n this.longPress = null\n this.gizmos?.destroy()\n this.gizmos = null\n this.table = null\n this.editing = null\n }\n}\n","/**\n * ADR-007 Stage 5 — autoformat on type. After a single typed character at the\n * end of a line, expand a few shorthands the way Obsidian / Typora do:\n *\n * - `[] ` / `[ ] ` at the line start → `- [ ] ` (a task item)\n * - ` ``` ` alone on a line → a fenced block, caret on the line between\n * - `$$` alone on a line → a math block, caret between\n * - `---` typed directly under text → a blank line is inserted above it, so\n * Markdown reads it as a thematic break, not a Setext `<h2>` underline —\n * matching `***` / `___`, which have no Setext meaning and already do this\n * - a rule (`---` / `***` / `___`) completed as the last line → append `\\n`,\n * so the caret steps off the rule instead of being stranded on it\n *\n * Headings (`# `), bullets (`- `), and quotes (`> `) need nothing here — their\n * markers already hide as you type them.\n *\n * One `transactionFilter`: it appends its rewrite to the keystroke's own\n * transaction (`sequential`), so a single undo takes the shorthand back to the\n * literal text.\n */\n\nimport { EditorState, type Extension, type TransactionSpec } from \"@codemirror/state\"\nimport { fromTableWidget } from \"./table-widget\"\n\nconst RULE_CHAR = new Set([\"-\", \"*\", \"_\"])\n\nexport const inPlaceAutoformat: Extension = EditorState.transactionFilter.of((tr) => {\n if (!tr.docChanged || tr.isUserEvent(\"undo\") || tr.isUserEvent(\"redo\")) return tr\n if (tr.annotation(fromTableWidget)) return tr\n if (!tr.startState.selection.main.empty) return tr\n\n // Exactly one single-character insertion, at the caret.\n const startHead = tr.startState.selection.main.head\n let inserted = \"\"\n let changeCount = 0\n tr.changes.iterChanges((fromA, toA, _fromB, _toB, ins) => {\n changeCount += 1\n if (fromA === toA && fromA === startHead) inserted = ins.toString()\n })\n if (changeCount !== 1 || inserted.length !== 1) return tr\n\n const doc = tr.newDoc\n const head = tr.newSelection.main.head\n const line = doc.lineAt(head)\n if (head !== line.to) return tr // only at the end of the line\n const text = line.text\n\n let spec: { changes: TransactionSpec[\"changes\"]; anchor: number } | null = null\n\n if (inserted === \" \" && /^\\[ ?\\] $/.test(text)) {\n spec = { changes: { from: line.from, to: line.to, insert: \"- [ ] \" }, anchor: line.from + 6 }\n } else if (inserted === \"`\" && text === \"```\") {\n spec = { changes: { from: head, insert: \"\\n\\n```\" }, anchor: head + 1 }\n } else if (inserted === \"$\" && text === \"$$\") {\n spec = { changes: { from: head, insert: \"\\n\\n$$\" }, anchor: head + 1 }\n } else if (RULE_CHAR.has(inserted) && new RegExp(`^\\\\${inserted}{3,}$`).test(text)) {\n const prevBlank = line.number === 1 || doc.line(line.number - 1).text.trim() === \"\"\n // `---` under a non-blank line is a Setext `<h2>` underline in Markdown, not\n // a rule. Push a blank line above so it renders as a thematic break.\n const breakOut = inserted === \"-\" && !prevBlank\n const isLast = line.number === doc.lines\n if (breakOut || isLast) {\n const changes: { from: number; insert: string }[] = []\n if (breakOut) changes.push({ from: line.from, insert: \"\\n\" })\n if (isLast) changes.push({ from: line.to, insert: \"\\n\" })\n spec = { changes, anchor: line.to + (breakOut ? 1 : 0) + (isLast ? 1 : 0) }\n }\n }\n\n if (!spec) return tr\n return [\n tr,\n {\n changes: spec.changes,\n selection: { anchor: spec.anchor },\n sequential: true,\n scrollIntoView: true,\n userEvent: \"input.autoformat\",\n },\n ]\n})\n","/**\n * ADR-007 Stage 2 — insertion association at a hidden marker's edge.\n *\n * With a construct's markers hidden and atomic, the caret at the visual end of a\n * bold word actually sits *before* the hidden `**`, so a keystroke there lands\n * inside the markup: `**bold**` + \"x\" → `**boldx**`. This transaction filter\n * moves a single boundary insertion to the outer edge of the marker run, so it\n * lands on the side the user perceives: `**bold**x`. The mirror case at the\n * front of the word is handled the same way (`x**bold**`, never `**xbold**`).\n *\n * Scope: the paired-mark inline constructs whose *both* delimiters are hidden —\n * strong / emphasis / strikethrough / inline code. Links and wikilinks keep a\n * directly editable label, so typing at a label edge is left alone.\n */\n\nimport { syntaxTree } from \"@codemirror/language\"\nimport { EditorState, type Extension } from \"@codemirror/state\"\nimport { markersHidden, wrapAt } from \"./edit-boundaries\"\nimport type { Tree } from \"./scan\"\nimport { fromTableWidget } from \"./table-widget\"\n\n/** The paired inline-mark nodes `decorate.ts` hides (both delimiters). */\nconst MARK_NODES = new Set([\"EmphasisMark\", \"CodeMark\", \"StrikethroughMark\"])\n\n/** Slide across an unbroken run of inline-mark nodes from `pos` in `dir`. */\nfunction skipMarks(tree: Tree, pos: number, dir: -1 | 1): number {\n let p = pos\n for (;;) {\n const node = tree.resolveInner(p, dir)\n if (!MARK_NODES.has(node.name) || node.from >= node.to) return p\n const next = dir < 0 ? node.from : node.to\n if (next === p) return p\n p = next\n }\n}\n\n/**\n * The position a boundary insertion at `pos` should be redirected to, or `pos`\n * itself when it is not exactly at a hidden wrapper's content edge. A nested\n * `***word***` is escaped in full — the marker run at the edge is crossed as a\n * unit regardless of how many levels it stacks.\n */\nfunction associatedPos(state: EditorState, pos: number): number {\n const w = wrapAt(state, pos, true)\n if (!w) return pos\n const tree = syntaxTree(state)\n if (pos === w.contentTo) return skipMarks(tree, pos, 1)\n if (pos === w.contentFrom) return skipMarks(tree, pos, -1)\n return pos\n}\n\nexport const inPlaceInsertAssociation: Extension = EditorState.transactionFilter.of((tr) => {\n if (!tr.docChanged) return tr\n if (tr.isUserEvent(\"undo\") || tr.isUserEvent(\"redo\")) return tr\n if (tr.annotation(fromTableWidget)) return tr\n const start = tr.startState\n const sel = start.selection.main\n if (!sel.empty) return tr\n if (!markersHidden(start, start.doc.lineAt(sel.head).number)) return tr\n\n // Only a single pure insertion exactly at the caret.\n const inserts: string[] = []\n let count = 0\n tr.changes.iterChanges((fromA, toA, _fromB, _toB, inserted) => {\n count++\n if (fromA === toA && fromA === sel.head && inserted.length > 0) {\n inserts.push(inserted.toString())\n }\n })\n const insert = inserts[0]\n if (count !== 1 || insert === undefined) return tr\n\n const target = associatedPos(start, sel.head)\n if (target === sel.head) return tr\n\n return {\n changes: { from: target, insert },\n selection: { anchor: target + insert.length },\n scrollIntoView: true,\n userEvent: \"input.type\",\n }\n})\n","/**\n * ADR-007 Stage 3 — line-prefix backspace.\n *\n * With `## `, `> `, `- ` and friends hidden and atomic, the caret at the visual\n * start of a heading / quote / list line sits just past the hidden prefix.\n * Backspace there removes one level of prefix instead of joining the line to the\n * one above — the Notion \"backspace to unstyle\" gesture:\n *\n * - heading → paragraph (the whole `#{1,6} ` goes)\n * - quote → one `> ` level out (nested quotes step out one at a time)\n * - list → outdent one step, or drop the marker when already flush\n * - task → paragraph (`- [ ] ` goes)\n *\n * Only fires while that prefix is actually hidden (so `reveal: \"caret\"` with the\n * caret on the line is untouched — the prefix is visible there and a normal\n * backspace edits it).\n */\n\nimport { Prec, type Extension } from \"@codemirror/state\"\nimport { type Command, type EditorView, keymap } from \"@codemirror/view\"\nimport { activeTableCell } from \"../toolbar/cell-inline\"\nimport { markersHidden } from \"./edit-boundaries\"\n\ninterface PrefixEdit {\n /** Length of the whole hidden prefix — the caret at visual column 0 sits here. */\n prefixLen: number\n /** `[start, end)` within the line to remove for \"one level out\". */\n drop: [number, number]\n}\n\nfunction prefixEditAt(text: string): PrefixEdit | null {\n const heading = /^#{1,6} /.exec(text)\n if (heading) return { prefixLen: heading[0].length, drop: [0, heading[0].length] }\n\n const quote = /^(?:> ?)+/.exec(text)\n if (quote) {\n const one = /^> ?/.exec(text)![0].length\n return { prefixLen: quote[0].length, drop: [0, one] }\n }\n\n const task = /^(\\s*)[-*+] \\[[ xX]\\] /.exec(text)\n if (task) return { prefixLen: task[0].length, drop: [0, task[0].length] }\n\n const list = /^(\\s*)([-*+] |\\d+[.)] )/.exec(text)\n if (list) {\n const indent = list[1]!\n if (indent) {\n const step = indent.startsWith(\"\\t\") ? 1 : Math.min(2, indent.length)\n return { prefixLen: list[0].length, drop: [0, step] }\n }\n return { prefixLen: list[2]!.length, drop: [0, list[2]!.length] }\n }\n return null\n}\n\n/** Backspace at visual column 0 of a hidden-prefix line — one level out. */\nexport const unwrapLinePrefix: Command = (view: EditorView): boolean => {\n if (activeTableCell(view)) return false\n const { state } = view\n const sel = state.selection.main\n if (!sel.empty) return false\n\n const line = state.doc.lineAt(sel.head)\n if (!markersHidden(state, line.number)) return false\n\n const edit = prefixEditAt(line.text)\n if (!edit) return false\n\n // Visual column 0: the caret is within the hidden prefix run — atomic ranges\n // collapse every position from `line.from` to the prefix end to one pixel.\n if (sel.head < line.from || sel.head > line.from + edit.prefixLen) return false\n\n const [ds, de] = edit.drop\n view.dispatch({\n changes: { from: line.from + ds, to: line.from + de, insert: \"\" },\n selection: { anchor: line.from + ds },\n userEvent: \"delete.backward\",\n scrollIntoView: true,\n })\n return true\n}\n\nexport const inPlaceLinePrefixEdit: Extension = Prec.high(\n keymap.of([{ key: \"Backspace\", run: unwrapLinePrefix }]),\n)\n","/**\n * Click a collapsed `[text](url)` in the seamless canvas and its URL editor\n * opens at the pointer — the same field the right-click menu and the selection\n * bar use. Under `reveal: \"never\"` the `(url)` is never on screen as text, so a\n * plain click otherwise has nowhere to go for an edit. The read side is\n * `link-hover.ts`; this is the write side (ADR-007 Stage 5, the click half).\n *\n * Scope:\n * - Only under `reveal: \"never\"`. In `\"caret\"` mode a click already reveals the\n * source on that line, so inline editing is the path there.\n * - External links only. A wikilink click is navigation (`onWikiLinkClick`);\n * its target stays editable through hover + the right-click menu.\n */\n\nimport { ViewPlugin, type EditorView, type PluginValue } from \"@codemirror/view\"\nimport { inPlaceConfigFacet, revealModeFacet } from \"./config\"\nimport { createContextMenu, type ContextMenu } from \"./context-menu\"\nimport { linkRow } from \"./context-menu-actions\"\n\nclass LinkClickEditor implements PluginValue {\n private menu: ContextMenu\n private contentDOM: HTMLElement\n private onClick: (e: MouseEvent) => void\n\n constructor(view: EditorView) {\n this.menu = createContextMenu(view.dom.ownerDocument)\n view.dom.appendChild(this.menu.el)\n this.contentDOM = view.contentDOM\n\n this.onClick = (e: MouseEvent) => {\n if (view.state.facet(revealModeFacet) !== \"never\") return\n if (!view.state.facet(inPlaceConfigFacet).links) return\n const target = e.target as HTMLElement | null\n const el = target?.closest(\".cm-inplace-link\")\n if (!el || el.classList.contains(\"cm-inplace-wikilink\")) return\n\n let pos = view.posAtDOM(el as HTMLElement)\n if (pos < 0) {\n const at = view.posAtCoords({ x: e.clientX, y: e.clientY })\n if (at == null) return\n pos = at\n }\n view.dispatch({ selection: { anchor: pos } })\n this.menu.showField(linkRow(view), e.clientX, e.clientY)\n }\n this.contentDOM.addEventListener(\"click\", this.onClick)\n }\n\n destroy() {\n this.contentDOM.removeEventListener(\"click\", this.onClick)\n this.menu.destroy()\n }\n}\n\nexport const linkClickEditor = ViewPlugin.fromClass(LinkClickEditor)\n","/**\n * Hover a link or wikilink in the in-place canvas and a small bubble shows where\n * it points — the raw `(url)` of a `[text](url)`, or the `[[target]]`. Under\n * `reveal: \"never\"` the destination is otherwise never on screen, so this is the\n * read affordance for it (ADR-007 Stage 5, the hover half).\n */\n\nimport { syntaxTree } from \"@codemirror/language\"\nimport { type EditorView, hoverTooltip, type Tooltip } from \"@codemirror/view\"\nimport type { SyntaxNode } from \"@lezer/common\"\nimport { WIKILINK_PATTERN } from \"../wikilink\"\nimport { inPlaceConfigFacet } from \"./config\"\n\nconst stripAngles = (s: string): string => s.replace(/^<([^]*)>$/, \"$1\").trim()\n\nconst bubble = (from: number, to: number, text: string): Tooltip | null => {\n if (!text) return null\n return {\n pos: from,\n end: to,\n above: true,\n create() {\n const dom = document.createElement(\"div\")\n dom.className = \"cm-inplace-href-tip\"\n dom.textContent = text\n return { dom }\n },\n }\n}\n\n/** The `[text](url)` destination at `pos`, or `null`. */\nfunction linkDestAt(view: EditorView, pos: number): Tooltip | null {\n for (\n let node: SyntaxNode | null = syntaxTree(view.state).resolveInner(pos, -1);\n node;\n node = node.parent\n ) {\n if (node.name !== \"Link\") continue\n if (view.state.doc.sliceString(Math.max(0, node.from - 1), node.from) === \"[\") break // [[wiki]]\n const url = node.getChild(\"URL\")\n const dest = url\n ? view.state.sliceDoc(url.from, url.to)\n : view.state.sliceDoc(node.from, node.to)\n return bubble(node.from, node.to, stripAngles(dest))\n }\n return null\n}\n\n/** The `[[target]]` at `pos` on its line, or `null`. */\nfunction wikiTargetAt(view: EditorView, pos: number): Tooltip | null {\n const line = view.state.doc.lineAt(pos)\n for (const m of line.text.matchAll(WIKILINK_PATTERN)) {\n const from = line.from + (m.index ?? 0)\n const to = from + m[0].length\n if (pos < from || pos > to) continue\n return bubble(from, to, (m[1] ?? \"\").trim())\n }\n return null\n}\n\nexport const linkHoverTooltip = hoverTooltip((view, pos): Tooltip | null => {\n const toggles = view.state.facet(inPlaceConfigFacet)\n return (\n (toggles.links ? linkDestAt(view, pos) : null) ??\n (toggles.wikilinks ? wikiTargetAt(view, pos) : null)\n )\n})\n","/**\n * Owns the in-place right-click menu: one `ContextMenu` per editor, a\n * `contextmenu` listener on the content DOM, and the rule for when Stylo takes\n * over from the browser's own menu (see the 2026-09-03 journal note). On touch\n * there is no `contextmenu` event, so a long-press opens the same menu.\n */\n\nimport { ViewPlugin, type EditorView, type PluginValue } from \"@codemirror/view\"\nimport { contextMenuEnabled } from \"./config\"\nimport { createContextMenu, type ContextMenu } from \"./context-menu\"\nimport { menuRows } from \"./context-menu-actions\"\nimport { wrapAt } from \"./edit-boundaries\"\nimport { attachLongPress, type LongPressHandle } from \"./long-press\"\n\nclass ContextMenuController implements PluginValue {\n private view: EditorView\n private menu: ContextMenu\n private onContextMenu: (e: MouseEvent) => void\n private onPointerDown: () => void\n private longPress: LongPressHandle\n private contentDOM: HTMLElement\n /** Selection captured at pointer-down — a right-click can collapse it before\n * `contextmenu` fires, which would drop the selection-aware menu rows. */\n private stashed: { anchor: number; head: number } | null = null\n /** When a long-press last opened the menu. Android also synthesises a\n * `contextmenu` from the same gesture; one that lands within the window is\n * swallowed so the menu does not re-open on top of itself. */\n private longPressAt = 0\n\n constructor(view: EditorView) {\n this.view = view\n this.menu = createContextMenu(view.dom.ownerDocument)\n // Inside `.cm-editor` so the `inPlaceTheme` rules (an `EditorView.theme`,\n // scoped to that element) reach it and the `--stylo-*` tokens inherit. The\n // panels are `position: fixed`, so placement is still viewport-relative.\n view.dom.appendChild(this.menu.el)\n\n this.contentDOM = view.contentDOM\n this.onPointerDown = () => {\n const s = view.state.selection.main\n this.stashed = s.empty ? null : { anchor: s.anchor, head: s.head }\n }\n this.contentDOM.addEventListener(\"pointerdown\", this.onPointerDown, true)\n\n this.onContextMenu = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null\n if (!view.state.facet(contextMenuEnabled)) return\n\n // Editable tables run their own context menu (structural rows, plus the\n // format group when a cell has a selection) and stop propagation before\n // this fires. Anything from that subtree that still reaches here is not a\n // cell — leave it to the browser.\n if (target?.closest(\".cm-inplace-table-edit\")) return\n\n // Every in-canvas target is handled: even a plain paragraph with no\n // selection has Insert + clipboard to offer, and adding a block is a\n // right-click action. Targets outside `.cm-content` never reach here, so\n // the browser's own menu still shows there.\n e.preventDefault()\n // Cancel any press still counting down, and drop a `contextmenu` that the\n // browser fired off a long-press that already opened the menu.\n this.longPress.cancel()\n if (Date.now() - this.longPressAt < 700) return\n this.openMenuAt(e.clientX, e.clientY, target)\n }\n this.contentDOM.addEventListener(\"contextmenu\", this.onContextMenu)\n\n this.longPress = attachLongPress(this.contentDOM, {\n onLongPress: (x, y, t) => {\n this.longPressAt = Date.now()\n this.openMenuAt(x, y, t as HTMLElement | null)\n },\n })\n }\n\n /** Open the canvas menu at a screen point, from a right-click or a long-press.\n * Reconciles the selection first so the menu offers the right rows. */\n private openMenuAt(clientX: number, clientY: number, target: HTMLElement | null) {\n const view = this.view\n if (!view.state.facet(contextMenuEnabled)) return\n if (target?.closest(\".cm-inplace-table-edit\")) return\n\n // A press that landed inside a selection may have collapsed it in the DOM\n // before this fired — put it back so the menu still offers the selection\n // rows (Link field, inline marks).\n if (this.stashed && view.state.selection.main.empty) {\n view.dispatch({ selection: this.stashed })\n } else if (view.state.selection.main.empty) {\n // No prior selection: select what the pointer is on so the menu offers\n // formatting for it. Inside an inline mark run (`**two words**`,\n // `*a phrase*`, `~~struck~~`, `` `code` ``) take the run's text, so a\n // toggle hits all of it. Inside a link or wikilink take the *whole*\n // construct — `[a b](url)`, `[[Page|a b]]` — because its label is not a\n // Markdown context: Bold there must wrap the link (`**[a b](url)**`),\n // never land `**` inside it. Otherwise the single word; failing that\n // (blank line, whitespace, punctuation) just drop the caret.\n const pos = view.posAtCoords({ x: clientX, y: clientY })\n if (pos != null) {\n const wrap = wrapAt(view.state, pos, false, true)\n let span = view.state.wordAt(pos) ?? { anchor: pos }\n if (wrap?.kind === \"link\") span = { anchor: wrap.from, head: wrap.to }\n else if (wrap && wrap.contentTo > wrap.contentFrom)\n span = { anchor: wrap.contentFrom, head: wrap.contentTo }\n view.dispatch({ selection: span })\n }\n }\n\n this.menu.show(menuRows(view), clientX, clientY)\n }\n\n destroy() {\n this.contentDOM.removeEventListener(\"pointerdown\", this.onPointerDown, true)\n this.contentDOM.removeEventListener(\"contextmenu\", this.onContextMenu)\n this.longPress.dispose()\n this.menu.destroy()\n }\n}\n\nexport const contextMenuLayer = ViewPlugin.fromClass(ContextMenuController)\n","/**\n * A floating inline-formatting bar that follows a non-empty selection in the\n * in-place canvas, Notion style. Inline marks only — bold, italic,\n * strikethrough, inline code, link, wikilink, inline math; block and insert\n * actions live on the right-click menu.\n *\n * It follows an editor selection (`state.selection`) and also a text selection\n * inside an editable table cell (a DOM selection — the widget is atomic, so it\n * never reaches `state.selection`). In a cell the mark buttons route through\n * `runInlineInCell`; the link / wikilink field editors do not apply there, so\n * those buttons fall back to the plain toggle.\n */\n\nimport { ViewPlugin, type EditorView, type PluginValue, type ViewUpdate } from \"@codemirror/view\"\nimport type { ToolbarCommandId } from \"../types\"\nimport { activeTableCell } from \"../toolbar/cell-inline\"\nimport { BUILTIN_BY_ID } from \"../toolbar/commands\"\nimport { ICON_PATHS, iconSvg } from \"../toolbar/icon-paths\"\nimport { selectionBarItemsFacet, selectionUIFacet } from \"./config\"\nimport { createContextMenu, type ContextMenu } from \"./context-menu\"\nimport { cellHasSelection, linkRow, wikiLinkRow } from \"./context-menu-actions\"\n\ninterface Box {\n left: number\n right: number\n top: number\n bottom: number\n}\n\nclass SelectionBar implements PluginValue {\n private bar: HTMLElement\n private ids: ToolbarCommandId[]\n private buttons = new Map<ToolbarCommandId, HTMLButtonElement>()\n private linkMenu: ContextMenu\n // Scrolling detaches the bar from its selection — just dismiss it. It returns,\n // repositioned, on the next selection change.\n private onScroll = () => {\n this.bar.hidden = true\n }\n // A cell's text selection lives in the DOM, so no `ViewUpdate` fires for it.\n private onSelectionChange = () => {\n if (activeTableCell(this.view)) this.schedule()\n }\n\n constructor(private view: EditorView) {\n const doc = view.dom.ownerDocument\n this.ids = view.state.facet(selectionBarItemsFacet)\n this.linkMenu = createContextMenu(doc)\n view.dom.appendChild(this.linkMenu.el)\n this.bar = doc.createElement(\"div\")\n this.bar.className = \"cm-inplace-selbar\"\n this.bar.setAttribute(\"contenteditable\", \"false\")\n this.bar.hidden = true\n for (const id of this.ids) {\n const cmd = BUILTIN_BY_ID[id]!\n const b = doc.createElement(\"button\")\n b.type = \"button\"\n b.className = \"cm-inplace-selbar-btn\"\n b.title = cmd.title\n b.setAttribute(\"aria-label\", cmd.title)\n b.appendChild(iconSvg(doc, ICON_PATHS[id] ?? \"\"))\n b.addEventListener(\"mousedown\", (e) => e.preventDefault())\n b.addEventListener(\"click\", (e) => {\n e.preventDefault()\n const inCell = Boolean(activeTableCell(view))\n // The link / wikilink buttons open a URL/target editor rather than\n // dropping a placeholder — but that editor works on `state.selection`,\n // so in a cell they fall back to the plain toggle.\n const field =\n !inCell && id === \"link\"\n ? linkRow(view)\n : !inCell && id === \"wikilink\"\n ? wikiLinkRow(view)\n : null\n if (field) {\n const r = b.getBoundingClientRect()\n this.linkMenu.showField(field, r.left, r.bottom + 6)\n return\n }\n cmd.run(view)\n if (!inCell) view.focus() // a cell keeps its own DOM focus\n this.schedule()\n })\n this.buttons.set(id, b)\n this.bar.appendChild(b)\n }\n // Inside `.cm-editor` so the `inPlaceTheme` rules and `--stylo-*` tokens\n // reach it; the bar is `position: fixed`, positioned against the viewport.\n view.dom.appendChild(this.bar)\n // Capture phase catches a scroll on any ancestor — the editor's own\n // scroller, or the page, when the editor grows with its content.\n doc.addEventListener(\"scroll\", this.onScroll, true)\n doc.addEventListener(\"selectionchange\", this.onSelectionChange)\n }\n\n update(u: ViewUpdate) {\n // Not `geometryChanged` — scrolling dismisses the bar (see `onScroll`)\n // rather than re-chasing the selection.\n if (u.selectionSet || u.docChanged || u.focusChanged) this.schedule()\n }\n\n /**\n * Layout reads (`coordsAtPos`, `getBoundingClientRect`) are illegal inside an\n * `update`, so the placement is computed in a measure phase and applied in the\n * write phase. `key: this` collapses repeats within one cycle.\n */\n private schedule() {\n this.view.requestMeasure({\n key: this,\n read: () => this.measure(),\n write: (m) => this.apply(m),\n })\n }\n\n /** The screen box of the current text selection — editor or table cell. */\n private selectionBox(): { box: Box; inCell: boolean } | null {\n const { view } = this\n const sel = view.state.selection.main\n if (!sel.empty) {\n const from = view.coordsAtPos(sel.from)\n const to = view.coordsAtPos(sel.to)\n if (!from || !to) return null\n return {\n inCell: false,\n box: {\n left: Math.min(from.left, to.left),\n right: Math.max(from.right, to.right),\n top: Math.min(from.top, to.top),\n bottom: Math.max(from.bottom, to.bottom),\n },\n }\n }\n if (!cellHasSelection(view)) return null\n const dom = view.dom.ownerDocument.getSelection()\n if (!dom || dom.rangeCount === 0) return null\n const r = dom.getRangeAt(0).getBoundingClientRect()\n return { inCell: true, box: { left: r.left, right: r.right, top: r.top, bottom: r.bottom } }\n }\n\n private measure(): Placement {\n const { view } = this\n if (view.state.facet(selectionUIFacet) !== \"bar\") return null\n const found = this.selectionBox()\n if (!found) return null\n const { box, inCell } = found\n // The editor-selection path needs editor focus; the cell path is already\n // gated on the cell being `document.activeElement` (via `cellHasSelection`).\n if (!inCell && !view.hasFocus) return null\n\n const barRect = this.bar.getBoundingClientRect() // `[hidden]` hides visibility only\n const vw = view.dom.ownerDocument.defaultView?.innerWidth ?? 0\n const midX = (box.left + box.right) / 2\n const editorTop = view.dom.getBoundingClientRect().top\n const aboveTop = box.top - barRect.height - 6\n const belowTop = box.bottom + 6\n\n const disabled: Record<string, boolean> = {}\n const active: Record<string, boolean> = {}\n for (const id of this.ids) {\n const cmd = BUILTIN_BY_ID[id]!\n // Every mark applies to a non-empty cell selection; `isActive` / `disabled`\n // read `state.selection`, which is collapsed there, so skip them.\n const off = inCell ? false : Boolean(cmd.disabled?.(view.state))\n disabled[id] = off\n active[id] = !off && !inCell && Boolean(cmd.isActive?.(view.state))\n }\n // Nothing the bar offers applies here (a fenced code / `$$` / frontmatter\n // selection) — show no bar rather than a row of dead buttons.\n if (this.ids.every((id) => disabled[id])) return null\n return {\n left: Math.max(4, Math.min(midX - barRect.width / 2, vw - barRect.width - 4)),\n top: aboveTop < editorTop + 2 ? belowTop : aboveTop,\n disabled,\n active,\n }\n }\n\n private apply(m: Placement) {\n if (!m) {\n this.bar.hidden = true\n return\n }\n this.bar.hidden = false\n this.bar.style.left = `${m.left}px`\n this.bar.style.top = `${m.top}px`\n for (const [id, b] of this.buttons) {\n b.disabled = m.disabled[id]!\n b.toggleAttribute(\"data-active\", m.active[id]!)\n }\n }\n\n destroy() {\n const doc = this.view.dom.ownerDocument\n doc.removeEventListener(\"scroll\", this.onScroll, true)\n doc.removeEventListener(\"selectionchange\", this.onSelectionChange)\n this.linkMenu.destroy()\n this.bar.remove()\n }\n}\n\ntype Placement = null | {\n left: number\n top: number\n disabled: Record<string, boolean>\n active: Record<string, boolean>\n}\n\nexport const selectionBar = ViewPlugin.fromClass(SelectionBar)\n","import { syntaxTree } from \"@codemirror/language\"\nimport { type EditorState, type Range, StateField, type Text } from \"@codemirror/state\"\nimport { Decoration, type DecorationSet, EditorView, WidgetType } from \"@codemirror/view\"\nimport type { SyntaxNode } from \"@lezer/common\"\nimport { type Align, parseGrid } from \"../toolbar/table-grid\"\nimport { inPlaceConfigFacet, tableEditingFacet } from \"./config\"\nimport { frontmatterRange } from \"./frontmatter\"\nimport { renderInline } from \"./inline-md\"\nimport { revealedLines } from \"./reveal\"\nimport { EditableTableWidget, fromTableWidget, type ParsedTable } from \"./table-widget\"\n\n/**\n * A GFM pipe table rendered as a real `<table>`. Cell text is run through\n * `renderInline` so `**bold**`, `` `code` ``, `[links]`, `[[wikilinks]]`, and\n * `$math$` display formatted; the caret entering any table line still reveals\n * the full source.\n */\nclass TableWidget extends WidgetType {\n constructor(readonly table: ParsedTable) {\n super()\n }\n\n override eq(other: TableWidget) {\n return JSON.stringify(this.table) === JSON.stringify(other.table)\n }\n\n toDOM() {\n const { head, body, aligns } = this.table\n const el = document.createElement(\"table\")\n el.className = \"cm-inplace-table\"\n\n // `\\|` is a literal pipe inside a GFM cell — unescape before inline parsing.\n const cell = (raw: string) => renderInline(raw.replace(/\\\\\\|/g, \"|\"))\n\n const hr = el.createTHead().insertRow()\n head.forEach((text, i) => {\n const th = document.createElement(\"th\")\n th.appendChild(cell(text))\n th.dataset.styloRow = \"0\"\n th.dataset.styloCol = String(i)\n align(th, aligns[i])\n hr.appendChild(th)\n })\n\n const tbody = el.createTBody()\n body.forEach((row, r) => {\n const tr = tbody.insertRow()\n for (let i = 0; i < head.length; i++) {\n const td = tr.insertCell()\n td.appendChild(cell(row[i] ?? \"\"))\n td.dataset.styloRow = String(r + 1)\n td.dataset.styloCol = String(i)\n align(td, aligns[i])\n }\n })\n return el\n }\n\n override ignoreEvent() {\n return false\n }\n}\n\nfunction align(cell: HTMLTableCellElement, value: Align | undefined) {\n if (value) cell.style.textAlign = value\n}\n\n/**\n * Parse a `Table` syntax node into `{ head, body, aligns }` by pipe-splitting\n * its raw lines. The Lezer parser omits a `TableCell` node for a whitespace-only\n * cell, so a tree-based read collapses `| | x |` to a single column — pull the\n * cells from the text instead, reusing the toolbar's grid parser.\n */\nfunction parseTable(node: SyntaxNode, doc: Text): ParsedTable | null {\n const first = doc.lineAt(node.from).number\n const last = doc.lineAt(node.to).number\n const lines: string[] = []\n for (let n = first; n <= last; n++) lines.push(doc.line(n).text)\n\n const grid = parseGrid(lines)\n if (!grid || grid.rows.length === 0) return null\n return { head: grid.rows[0]!, body: grid.rows.slice(1), aligns: grid.aligns }\n}\n\nfunction build(state: EditorState): DecorationSet {\n if (!state.facet(inPlaceConfigFacet).tables) return Decoration.none\n const editable = state.facet(tableEditingFacet) === \"cells\"\n const tree = syntaxTree(state)\n const fm = frontmatterRange(state.doc)\n const revealed = editable ? null : revealedLines(state)\n const out: Range<Decoration>[] = []\n\n tree.iterate({\n enter: (node) => {\n if (node.name !== \"Table\") return undefined\n if (fm && node.from < fm.to) return false\n\n // In \"cells\" mode the editable widget stays mounted; the caret lives in\n // its contentEditable cells, so there is no source to reveal.\n if (revealed) {\n const first = state.doc.lineAt(node.from).number\n const last = state.doc.lineAt(node.to).number\n for (let n = first; n <= last; n++) {\n if (revealed.has(n)) return false\n }\n }\n\n const parsed = parseTable(node.node, state.doc)\n if (parsed) {\n const widget = editable ? new EditableTableWidget(parsed) : new TableWidget(parsed)\n out.push(Decoration.replace({ widget, block: true }).range(node.from, node.to))\n }\n return false\n },\n })\n\n return Decoration.set(out, true)\n}\n\n/**\n * Renders GFM tables in place. A state field, not the view plugin, because the\n * replacement spans line breaks. The whole document is scanned — tables are few.\n */\nexport const tableField = StateField.define<DecorationSet>({\n create: build,\n update: (value, tr) => {\n // An edit from the editable widget's own DOM: keep the widget instance\n // (and its focused cell) by mapping the existing decoration through the\n // change instead of rebuilding. The block-replace range maps cleanly —\n // its `from` side is negative (→ change start), its `to` side positive\n // (→ change end) — so the mapped span is exactly the new table.\n if (tr.annotation(fromTableWidget)) return value.map(tr.changes)\n // In \"cells\" mode the editable widget is always mounted and owns live DOM\n // (contentEditable cells, an open context menu). A selection-only\n // transaction must not rebuild it — that swaps the widget instance behind\n // the mounted DOM and orphans an in-flight structural edit. Only a real\n // external document change reloads it.\n if (tr.state.facet(tableEditingFacet) === \"cells\") {\n return tr.docChanged ? build(tr.state) : value.map(tr.changes)\n }\n return tr.docChanged || tr.selection ? build(tr.state) : value\n },\n provide: (field) => [\n EditorView.decorations.from(field),\n EditorView.atomicRanges.of((view) => view.state.field(field)),\n ],\n})\n","/**\n * Keyboard entry into a table.\n *\n * A GFM table renders as one block widget spanning every table line, registered\n * as a single atomic range — so stock vertical cursor motion skips the whole\n * construct and ArrowDown from the line above lands *below* the table, never in\n * it.\n *\n * Here ArrowDown on the line directly above a table (ArrowUp directly below)\n * steps in instead. In `table: \"cells\"` it focuses the near edge cell; in\n * `source` it drops the caret on the adjacent table source line, which reveals\n * the raw pipe syntax the same way a blockquote or fenced block reveals on\n * caret entry.\n */\n\nimport { Prec, type Extension } from \"@codemirror/state\"\nimport { type Command, type EditorView, keymap, type WidgetType } from \"@codemirror/view\"\nimport { activeTableCell } from \"../toolbar/cell-inline\"\nimport { tableEditingFacet } from \"./config\"\nimport { EditableTableWidget } from \"./table-widget\"\nimport { tableField } from \"./tables\"\n\nconst arrowIntoTable =\n (forward: boolean): Command =>\n (view: EditorView): boolean => {\n if (activeTableCell(view)) return false\n const sel = view.state.selection.main\n if (!sel.empty) return false\n const { doc } = view.state\n const line = doc.lineAt(sel.head)\n const edgeLineNo = forward ? line.number + 1 : line.number - 1\n if (edgeLineNo < 1 || edgeLineNo > doc.lines) return false\n const edge = doc.line(edgeLineNo)\n\n let from = -1\n let to = -1\n let widget: WidgetType | undefined\n view.state.field(tableField).between(edge.from, edge.to, (a, b, deco) => {\n // Entering from above, the table must start on the adjacent line; from\n // below, it must end on it. A middle line is never an entry point.\n if (forward ? a === edge.from : b === edge.to) {\n from = a\n to = b\n widget = deco.spec.widget\n return false\n }\n })\n if (from < 0) return false\n\n if (view.state.facet(tableEditingFacet) === \"cells\") {\n return widget instanceof EditableTableWidget && widget.focusEdge(forward ? \"first\" : \"last\")\n }\n\n // Source mode: land on the table's near source line and let the reveal\n // follow from the selection change.\n const anchor = forward ? doc.lineAt(from).from : doc.lineAt(to).to\n view.dispatch({ selection: { anchor }, userEvent: \"select\", scrollIntoView: true })\n return true\n }\n\n/** ArrowDown that steps into a table on the line below. */\nexport const enterTableFromAbove: Command = arrowIntoTable(true)\n/** ArrowUp that steps into a table on the line above. */\nexport const enterTableFromBelow: Command = arrowIntoTable(false)\n\nexport const inPlaceTableEnter: Extension = Prec.high(\n keymap.of([\n { key: \"ArrowDown\", run: enterTableFromAbove },\n { key: \"ArrowUp\", run: enterTableFromBelow },\n ]),\n)\n","import { EditorView } from \"@codemirror/view\"\n\nconst MONO = \"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace\"\n\n/**\n * Display styling for the in-place canvas. Scoped to editors that include this\n * extension (via `EditorView.theme`), so `source` mode is untouched. Sizes are\n * relative to the editor font so they track the host's type scale; colour stays\n * inherited from the `--stylo-*` tokens.\n *\n * Vertical rhythm mirrors the `preview` surface, which follows Tailwind's\n * `prose` scale (reference only, no plugin). The match is approximate here: a\n * `.cm-line` cannot take a `margin` without drifting click-to-position (see the\n * 2026-09-02 click-mapping note), and a blank source line already supplies most\n * of the inter-block gap, so heading `padding-top` is trimmed accordingly.\n */\nexport const inPlaceTheme = EditorView.theme({\n // The canvas reads as prose, not source. Code spans opt back into monospace.\n //\n // The horizontal gutter lives here, not on `.cm-line`. A `.cm-line` padding\n // insets its text but not a line background/border (CSS paints those across\n // the padding too) nor a block widget (a `block: true` replacement renders\n // outside `.cm-line`). So a boxed block — fenced code, the blockquote bar, a\n // rendered table, a `$$` math block — would otherwise bleed to the editor\n // frame. Padding on `.cm-content` holds every one of them off the edge.\n \"& .cm-content\": {\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif',\n lineHeight: \"1.75\",\n padding: \"0.75rem\",\n // Suppress iOS Safari's own long-press callout so it stops racing (and\n // usually beating) the canvas's long-press → context-menu gesture. Text\n // selection and the selection handles are unaffected.\n WebkitTouchCallout: \"none\",\n },\n \"& .cm-line\": { paddingLeft: \"0\", paddingRight: \"0\" },\n\n \".cm-inplace-heading\": { fontWeight: \"600\" },\n \".cm-inplace-h1\": { fontSize: \"2.25em\", lineHeight: \"1.1111111\", paddingTop: \"0.35em\" },\n \".cm-inplace-h2\": { fontSize: \"1.5em\", lineHeight: \"1.3333333\", paddingTop: \"0.7em\" },\n \".cm-inplace-h3\": { fontSize: \"1.25em\", lineHeight: \"1.6\", paddingTop: \"0.6em\" },\n \".cm-inplace-h4\": { fontSize: \"1em\", lineHeight: \"1.5\", paddingTop: \"0.5em\" },\n \".cm-inplace-h5\": { fontSize: \"0.9em\" },\n \".cm-inplace-h6\": { fontSize: \"0.9em\", color: \"var(--stylo-text-muted)\" },\n\n \".cm-inplace-strong\": { fontWeight: \"700\" },\n \".cm-inplace-em\": { fontStyle: \"italic\" },\n \".cm-inplace-strike\": { textDecoration: \"line-through\" },\n \".cm-inplace-code\": {\n fontFamily: MONO,\n fontSize: \"0.9em\",\n padding: \"0.1em 0.35em\",\n borderRadius: \"3px\",\n background: \"color-mix(in srgb, var(--stylo-border) 45%, transparent)\",\n },\n\n // Fenced / indented code block rows. The background runs the full line width\n // and the text is inset by `0.9rem`, mirroring the preview surface's `pre`\n // (`stylo.module.css`) so a block lines up with the prose column on both\n // edges. No horizontal margin — that inset the background and read as a\n // floating, too-narrow block against every other flush block.\n \".cm-inplace-mono\": {\n fontFamily: MONO,\n fontSize: \"0.9em\",\n background: \"color-mix(in srgb, var(--stylo-border) 35%, transparent)\",\n padding: \"0 0.9rem\",\n },\n // Vertical spacing is padding, never margin, on anything CodeMirror measures\n // for its height map (`.cm-line` decorations, block/inline widgets): margin\n // sits outside the border box CM measures, so it drifts click-to-position for\n // every line below. Applies to the block, the rule, the table, and the math\n // block too.\n \".cm-inplace-code-top\": {\n paddingTop: \"0.7rem\",\n borderTopLeftRadius: \"var(--stylo-radius)\",\n borderTopRightRadius: \"var(--stylo-radius)\",\n },\n \".cm-inplace-code-bottom\": {\n paddingBottom: \"0.7rem\",\n borderBottomLeftRadius: \"var(--stylo-radius)\",\n borderBottomRightRadius: \"var(--stylo-radius)\",\n },\n \".cm-inplace-fence\": { color: \"var(--stylo-text-muted)\" },\n // Off-caret fence row: no text, no height — the container is padding + code.\n \".cm-inplace-code-pad\": { fontSize: \"0\", lineHeight: \"0\" },\n\n // Links read by colour, not underline (a standard link blue via the token).\n \".cm-inplace-link\": {\n color: \"var(--stylo-link)\",\n textDecoration: \"none\",\n cursor: \"pointer\",\n },\n \".cm-inplace-wikilink\": { color: \"var(--stylo-link)\" },\n\n \".cm-inplace-math-block\": {\n display: \"block\",\n padding: \"0.9em 0\",\n textAlign: \"center\",\n },\n \".cm-inplace-math-block .katex-display\": { margin: \"0\" },\n\n // The `---` line's own text row is zeroed (same recipe as the fenced-code\n // fence rows) so it does not stack under the widget's height — that stacking\n // was the extra space above and below the rule.\n \".cm-inplace-hr-line\": { fontSize: \"0\", lineHeight: \"0\" },\n // A Setext heading's `===` / `---` underline row, collapsed to nothing off\n // the caret so the heading reads as one line (the `---` text is also hidden).\n \".cm-inplace-setext-rule\": { fontSize: \"0\", lineHeight: \"0\" },\n \".cm-inplace-hr\": {\n display: \"block\",\n // ~one text row, so the rule renders in the `---`'s own footprint with no\n // extra space and no shift when the caret enters (Obsidian's behaviour).\n // `rem` not `em` because the line's font-size is zeroed above. No margin,\n // so CodeMirror's height map measures it right (2026-09-02 click-mapping).\n height: \"1.6rem\",\n margin: \"0\",\n border: \"none\",\n // A 1px hairline painted at the row's centre line.\n background:\n \"linear-gradient(var(--stylo-border), var(--stylo-border)) left center / 100% 1px no-repeat\",\n },\n \".cm-inplace-quote\": {\n borderLeft: \"0.25rem solid var(--stylo-border)\",\n // Same content inset as a callout, so a quote and a callout line up.\n paddingLeft: \"1rem\",\n color: \"var(--stylo-text-muted)\",\n },\n\n // Callout blockquotes (`> [!note]`). A tinted box keyed by colour bucket; the\n // head line carries a `data-callout` label in place of the hidden `[!type]`.\n // `--stylo-callout-accent` is set per bucket and can be overridden per type.\n \".cm-inplace-callout\": {\n borderLeft: \"0.25rem solid var(--stylo-callout-accent, var(--stylo-border))\",\n padding: \"0 1rem\",\n background:\n \"color-mix(in srgb, var(--stylo-callout-accent, var(--stylo-border)) 10%, transparent)\",\n color: \"var(--stylo-text)\",\n },\n // First / last line of the box carry the vertical breathing room and the\n // rounded outer corners (left stays a straight accent rule). Padding only —\n // `margin` on a `.cm-line` escapes CodeMirror's height map and clicks land on\n // the wrong line (2026-09-02 click-mapping).\n \".cm-inplace-callout-head\": {\n paddingTop: \"0.7em\",\n borderTopRightRadius: \"var(--stylo-radius)\",\n },\n \".cm-inplace-callout-foot\": {\n paddingBottom: \"0.7em\",\n borderBottomRightRadius: \"var(--stylo-radius)\",\n },\n \".cm-inplace-callout-note\": { \"--stylo-callout-accent\": \"var(--stylo-callout-note, #3b82f6)\" },\n \".cm-inplace-callout-tip\": { \"--stylo-callout-accent\": \"var(--stylo-callout-tip, #22c55e)\" },\n \".cm-inplace-callout-warn\": { \"--stylo-callout-accent\": \"var(--stylo-callout-warn, #f59e0b)\" },\n \".cm-inplace-callout-danger\": {\n \"--stylo-callout-accent\": \"var(--stylo-callout-danger, #ef4444)\",\n },\n \".cm-inplace-callout-example\": {\n \"--stylo-callout-accent\": \"var(--stylo-callout-example, #a855f7)\",\n },\n \".cm-inplace-callout-head::before\": {\n content: \"attr(data-callout)\",\n display: \"block\",\n marginBottom: \"0.2em\",\n fontSize: \"0.8em\",\n fontWeight: \"700\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\",\n color: \"var(--stylo-callout-accent, var(--stylo-text-muted))\",\n },\n // Caret in the block: the raw `> [!type]` shows, so drop the duplicate label.\n \".cm-inplace-callout-head[data-revealed]::before\": { content: '\"\"', display: \"none\" },\n\n \".cm-inplace-bullet\": { color: \"var(--stylo-text-muted)\" },\n // Nested-list indent guides: `--sl-li-depth` 1px rules, one per level above\n // this line, spaced by an indent step and clipped to that width. Approximate\n // alignment — decorative depth cue, not a pixel-exact rail.\n \".cm-inplace-li\": {\n backgroundImage:\n \"repeating-linear-gradient(to right, var(--stylo-guide) 0 1px, transparent 1px 1.5em)\",\n backgroundRepeat: \"no-repeat\",\n backgroundPosition: \"0.35em 0\",\n backgroundSize: \"calc(var(--sl-li-depth, 0) * 1.5em) 100%\",\n },\n \".cm-inplace-checkbox\": {\n margin: \"0 0.4em 0 0\",\n verticalAlign: \"middle\",\n cursor: \"pointer\",\n },\n \".cm-inplace-fm\": {\n fontFamily: MONO,\n fontSize: \"0.85em\",\n color: \"var(--stylo-text-muted)\",\n },\n \".cm-inplace-fm-first::before\": {\n content: '\"Frontmatter\"',\n marginRight: \"0.6em\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif',\n fontSize: \"0.8rem\",\n fontWeight: \"600\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\",\n color: \"var(--stylo-text-muted)\",\n },\n\n \".cm-inplace-table\": {\n borderCollapse: \"collapse\",\n padding: \"1em 0 1.4em\",\n fontSize: \"0.95em\",\n },\n \".cm-inplace-table th\": {\n padding: \"0.35em 0.6em\",\n border: \"1px solid var(--stylo-table-border)\",\n background: \"var(--stylo-table-header-bg)\",\n fontWeight: \"600\",\n },\n \".cm-inplace-table td\": {\n padding: \"0.35em 0.6em\",\n border: \"1px solid var(--stylo-table-border)\",\n },\n // Zebra striping — a no-op until the host sets `--stylo-table-stripe-bg`.\n \".cm-inplace-table tbody tr:nth-child(even) td\": {\n background: \"var(--stylo-table-stripe-bg)\",\n },\n\n \".cm-inplace-table-edit .cm-inplace-tcell\": {\n minWidth: \"3em\",\n cursor: \"text\",\n outline: \"none\",\n },\n \".cm-inplace-table-edit .cm-inplace-tcell:focus\": {\n boxShadow: \"inset 0 0 0 2px var(--stylo-ring)\",\n },\n\n // --- editable-table affordances: edge `+` (hover) and a right-click menu ---\n \".cm-inplace-table-wrap\": {\n position: \"relative\",\n display: \"inline-block\",\n maxWidth: \"100%\",\n // Reserve the right / bottom gutters the edge strips occupy. `border-collapse`\n // makes the browser ignore padding on the `<table>` itself, so without this\n // the wrapper is sized to the bare grid and the strips overflow it — the row\n // strip spilling into the block below. Padding (not margin) so CodeMirror's\n // height map still measures the widget correctly.\n padding: \"0 calc(1.15em + 4px) calc(1.15em + 4px) 0\",\n },\n \".cm-inplace-table-gizmos\": {\n position: \"absolute\",\n inset: \"0\",\n pointerEvents: \"none\",\n },\n // right edge → add column; bottom edge → add row. Click anywhere along the\n // strip; it only shows itself (and its centred `+`) while the pointer is on it.\n // The clearance from the grid edge is set in `table-gizmos.ts` `layout()` so it\n // is identical on both strips; the tint matches the header-row fill.\n \".cm-inplace-tg-edge\": {\n position: \"absolute\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n pointerEvents: \"auto\",\n padding: \"0\",\n font: \"inherit\",\n border: \"none\",\n background: \"transparent\",\n cursor: \"pointer\",\n opacity: \"0\",\n transition: \"opacity 0.1s ease\",\n },\n \".cm-inplace-tg-edge:hover\": {\n opacity: \"1\",\n background: \"color-mix(in srgb, var(--stylo-border) 30%, transparent)\",\n },\n \".cm-inplace-tg-addcol\": { width: \"1.15em\" },\n \".cm-inplace-tg-addrow\": { height: \"1.15em\" },\n // A CSS-drawn cross, not a font glyph: a `+` character rides up toward the\n // font's math axis, so flex centring leaves it visibly high no matter how the\n // font size is tuned. Two `currentColor` bars positioned dead centre are exact\n // and still follow the hover colour change below.\n \".cm-inplace-tg-plus\": {\n width: \"0.7em\",\n height: \"0.7em\",\n color: \"var(--stylo-text-muted)\",\n background:\n \"linear-gradient(currentColor, currentColor) center / 100% 2px no-repeat,\" +\n \"linear-gradient(currentColor, currentColor) center / 2px 100% no-repeat\",\n pointerEvents: \"none\",\n },\n \".cm-inplace-tg-edge:hover .cm-inplace-tg-plus\": { color: \"var(--stylo-text)\" },\n // No hover on a touch device — keep the strips faintly visible so \"add row\" /\n // \"add column\" stays discoverable. A tap still runs them at full opacity.\n \"@media (hover: none)\": {\n \".cm-inplace-tg-edge\": { opacity: \"0.5\" },\n },\n\n // --- Right-click menu (menu-plugin.ts / context-menu.ts) ---\n // Also the editable table's structural menu (table-gizmos.ts) — same shell.\n // `.cm-inplace-menu` is a non-interactive full-viewport layer; each panel\n // inside it is a fixed-positioned popup.\n \".cm-inplace-menu\": {\n position: \"fixed\",\n inset: \"0\",\n zIndex: \"20\",\n pointerEvents: \"none\",\n },\n \".cm-inplace-menu-panel\": {\n position: \"fixed\",\n minWidth: \"12em\",\n padding: \"0.25em\",\n display: \"flex\",\n flexDirection: \"column\",\n pointerEvents: \"auto\",\n background: \"var(--stylo-surface-floating, #fff)\",\n border: \"1px solid var(--stylo-border)\",\n borderRadius: \"6px\",\n boxShadow: \"0 4px 16px rgba(0, 0, 0, 0.12)\",\n font: \"inherit\",\n },\n \".cm-inplace-menu-sep\": {\n height: \"1px\",\n margin: \"0.25em 0.3em\",\n background: \"var(--stylo-border)\",\n },\n \".cm-inplace-menu-item\": {\n all: \"unset\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"0.55em\",\n padding: \"0.35em 0.6em\",\n borderRadius: \"4px\",\n fontSize: \"0.9em\",\n cursor: \"pointer\",\n whiteSpace: \"nowrap\",\n },\n \".cm-inplace-menu-item svg\": {\n width: \"1em\",\n height: \"1em\",\n flex: \"0 0 auto\",\n color: \"var(--stylo-text-muted)\",\n },\n \".cm-inplace-menu-item:hover:not(:disabled)\": {\n background: \"color-mix(in srgb, var(--stylo-border) 40%, transparent)\",\n },\n \".cm-inplace-menu-item:disabled\": { opacity: \"0.4\", cursor: \"default\" },\n // Active row uses `--stylo-accent` (\"active / pressed states\"), not\n // `--stylo-ring` — the focus-ring token stays a focus ring only, so a host can\n // restyle one without disturbing the other.\n \".cm-inplace-menu-item[data-active]\": { color: \"var(--stylo-accent)\", fontWeight: \"600\" },\n \".cm-inplace-menu-item[data-active] svg\": { color: \"var(--stylo-accent)\" },\n \".cm-inplace-menu-parent::after\": {\n content: '\"\\\\203A\"',\n marginLeft: \"auto\",\n paddingLeft: \"1.5em\",\n },\n \".cm-inplace-menu-input\": {\n display: \"block\",\n boxSizing: \"border-box\",\n width: \"18em\",\n maxWidth: \"70vw\",\n margin: \"0.15em\",\n padding: \"0.45em 0.6em\",\n border: \"1px solid var(--stylo-text-muted)\",\n borderRadius: \"4px\",\n fontSize: \"0.9em\",\n fontFamily: \"inherit\",\n lineHeight: \"1.4\",\n color: \"var(--stylo-text)\",\n background: \"var(--stylo-surface-floating, #fff)\",\n outline: \"none\",\n },\n \".cm-inplace-menu-input:focus\": { borderColor: \"var(--stylo-ring)\" },\n\n // --- Selection bar (selection-bar.ts) ---\n // `[hidden]` toggles visibility, not `display` — the bar stays laid out so\n // `getBoundingClientRect` can size it during the measure phase. It is\n // `position: fixed`, so an always-present hidden bar costs no document flow.\n \".cm-inplace-selbar\": {\n position: \"fixed\",\n zIndex: \"20\",\n display: \"flex\",\n gap: \"0.1em\",\n padding: \"0.2em\",\n background: \"var(--stylo-surface-floating, #fff)\",\n border: \"1px solid var(--stylo-border)\",\n borderRadius: \"6px\",\n boxShadow: \"0 4px 16px rgba(0, 0, 0, 0.12)\",\n },\n \".cm-inplace-selbar[hidden]\": { visibility: \"hidden\", pointerEvents: \"none\" },\n \".cm-inplace-selbar-btn\": {\n all: \"unset\",\n display: \"flex\",\n padding: \"0.3em\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n color: \"var(--stylo-text-muted)\",\n },\n \".cm-inplace-selbar-btn svg\": { width: \"1.05em\", height: \"1.05em\", display: \"block\" },\n \".cm-inplace-selbar-btn:hover\": {\n background: \"color-mix(in srgb, var(--stylo-border) 40%, transparent)\",\n color: \"var(--stylo-text)\",\n },\n \".cm-inplace-selbar-btn[data-active]\": {\n color: \"var(--stylo-text)\",\n background: \"color-mix(in srgb, var(--stylo-border) 55%, transparent)\",\n },\n\n // --- Touch sizing for the popup UI ---\n // When the primary pointer is a finger, the right-click menu, its URL input,\n // and the selection bar grow to a comfortable tap size. Automatic — this is\n // popup-internal sizing, not a layout change, so unlike `toolbar.sticky` it\n // needs no opt-in. Consumers still override via the `.cm-inplace-*` classes.\n // Menu rows use 9px of vertical padding (an ~18px gutter between labels) and\n // no `min-height` — a full 44px row spread the list out more than it earned.\n \"@media (pointer: coarse)\": {\n \".cm-inplace-menu-panel\": { minWidth: \"14em\", padding: \"0.25em\" },\n \".cm-inplace-menu-item\": { padding: \"9px 0.75em\", fontSize: \"1em\" },\n \".cm-inplace-menu-item svg\": { width: \"1.15em\", height: \"1.15em\" },\n \".cm-inplace-menu-sep\": { margin: \"0.2em 0.3em\" },\n \".cm-inplace-menu-input\": { padding: \"9px 0.75em\", fontSize: \"1em\" },\n \".cm-inplace-selbar\": { gap: \"0.15em\", padding: \"0.25em\" },\n \".cm-inplace-selbar-btn\": { padding: \"0.55em\", minWidth: \"44px\", justifyContent: \"center\" },\n \".cm-inplace-selbar-btn svg\": { width: \"1.25em\", height: \"1.25em\" },\n },\n\n // --- Link / wikilink hover bubble (link-hover.ts) ---\n \".cm-tooltip.cm-tooltip-hover:has(.cm-inplace-href-tip)\": {\n border: \"none\",\n background: \"transparent\",\n },\n \".cm-inplace-href-tip\": {\n maxWidth: \"min(28em, 70vw)\",\n padding: \"0.3em 0.55em\",\n borderRadius: \"5px\",\n background: \"var(--stylo-surface-floating, #fff)\",\n border: \"1px solid var(--stylo-border)\",\n boxShadow: \"0 4px 16px rgba(0, 0, 0, 0.12)\",\n color: \"var(--stylo-text-muted)\",\n fontSize: \"0.82em\",\n lineHeight: \"1.4\",\n wordBreak: \"break-all\",\n },\n})\n","import { Prec, type Extension } from \"@codemirror/state\"\nimport { EditorView } from \"@codemirror/view\"\nimport { cellSourcePos } from \"../toolbar/table\"\nimport type { InPlaceConfig } from \"../types\"\nimport {\n contextMenuEnabled,\n inPlaceConfigFacet,\n linkOpenFacet,\n menuGroupsFacet,\n resolveContextMenu,\n resolveSelectionBarItems,\n resolveToggles,\n revealModeFacet,\n selectionBarItemsFacet,\n selectionUIFacet,\n tableEditingFacet,\n} from \"./config\"\nimport { inPlaceEditBoundaries } from \"./edit-boundaries\"\nimport { inPlaceAutoformat } from \"./autoformat\"\nimport { inPlaceInsertAssociation } from \"./edit-insert-assoc\"\nimport { inPlaceLinePrefixEdit } from \"./edit-line-prefix\"\nimport { frontmatterField } from \"./frontmatter\"\nimport { linkClickEditor } from \"./link-click\"\nimport { linkHoverTooltip } from \"./link-hover\"\nimport { blockMathField } from \"./math\"\nimport { contextMenuLayer } from \"./menu-plugin\"\nimport { inPlaceDecorations } from \"./plugin\"\nimport { selectionBar } from \"./selection-bar\"\nimport { inPlaceTableEnter } from \"./table-enter\"\nimport { tableField } from \"./tables\"\nimport { inPlaceTheme } from \"./theme\"\n\nexport interface InPlaceOptions {\n /** Fired when a collapsed `[[wikilink]]` is clicked in the canvas. */\n onWikiLinkClick?: (target: string) => void\n /** Fired by the link editor's \"Open link\" action with the link's href. */\n onLinkClick?: (href: string) => void\n /** Which decoration types render; see ADR-005. Applied once, at construction. */\n inPlace?: InPlaceConfig\n}\n\n/**\n * Rendered widgets with no interior text position. A click on one (its body,\n * KaTeX internals, the empty parts of an `<hr>`) can leave the caret unplaced,\n * so nothing reveals — this hands it to the widget's edge instead. Everything\n * else, text and line padding alike, stays with CodeMirror.\n */\nconst REVEAL_WIDGET = \".cm-inplace-math, .cm-inplace-hr, .cm-inplace-table\"\n\n/**\n * Character offset of a screen point within a rendered table cell's text,\n * clamped to that text. Lets a click land mid-word instead of at the cell's\n * start when the source is revealed. Returns 0 where the browser can't resolve\n * a caret (jsdom, or a click on the cell's padding beyond the text).\n */\nfunction caretOffsetInCell(cell: HTMLElement, x: number, y: number): number {\n const text = cell.firstChild\n const len = cell.textContent?.length ?? 0\n if (!text || text.nodeType !== Node.TEXT_NODE || len === 0) return 0\n\n const doc = cell.ownerDocument as Document & {\n caretPositionFromPoint?: (x: number, y: number) => { offsetNode: Node; offset: number } | null\n }\n let node: Node | null = null\n let offset = 0\n if (doc.caretPositionFromPoint) {\n const p = doc.caretPositionFromPoint(x, y)\n if (p) [node, offset] = [p.offsetNode, p.offset]\n } else if (doc.caretRangeFromPoint) {\n const r = doc.caretRangeFromPoint(x, y)\n if (r) [node, offset] = [r.startContainer, r.startOffset]\n }\n\n if (node === text) return Math.min(offset, len)\n if (node === cell) return offset > 0 ? len : 0 // clicked the cell padding\n return 0\n}\n\n/**\n * The complete in-place canvas layer: decoration plugin, display theme, a\n * reveal-on-click fallback for rendered widgets, and a delegated click handler\n * for wikilinks.\n *\n * The theme is raised with `Prec.high` so its `.cm-content` font rule overrides\n * the base editor theme (which sets the source surface to monospace) for\n * in-place editors only.\n */\nexport function inPlaceExtension(opts: InPlaceOptions = {}): Extension {\n const menu = resolveContextMenu(opts.inPlace?.contextMenu)\n return [\n inPlaceConfigFacet.of(resolveToggles(opts.inPlace)),\n tableEditingFacet.of(opts.inPlace?.table ?? \"source\"),\n revealModeFacet.of(opts.inPlace?.reveal ?? \"caret\"),\n linkOpenFacet.of(opts.onLinkClick ?? null),\n contextMenuEnabled.of(menu.enabled),\n menuGroupsFacet.of(menu.groups),\n selectionUIFacet.of(opts.inPlace?.selectionUI ?? \"menu\"),\n selectionBarItemsFacet.of(resolveSelectionBarItems(opts.inPlace?.selectionBarItems)),\n inPlaceDecorations(),\n // Backspace: the line-prefix unwrap gets first refusal, then the\n // step-over-markers handler, then CodeMirror's default.\n inPlaceLinePrefixEdit,\n inPlaceEditBoundaries,\n inPlaceTableEnter,\n inPlaceInsertAssociation,\n inPlaceAutoformat,\n blockMathField,\n frontmatterField,\n tableField,\n contextMenuLayer,\n selectionBar,\n linkClickEditor,\n linkHoverTooltip,\n Prec.high(inPlaceTheme),\n EditorView.domEventHandlers({\n mousedown(event, view) {\n const target = event.target as HTMLElement | null\n // An editable table (`inPlace.table: \"cells\"`) owns its own clicks —\n // the mousedown places the caret in a contentEditable cell.\n if (target?.closest(\".cm-inplace-table-edit\")) return false\n const widget = target?.closest<HTMLElement>(REVEAL_WIDGET)\n if (!widget) return false // text or padding — CodeMirror places the caret\n let pos = view.posAtDOM(widget)\n if (pos < 0) return false\n // A rendered table: reveal the source at the cell that was clicked, not\n // at the table's first cell (`posAtDOM` gives the widget's start).\n const cell = target?.closest<HTMLElement>(\"[data-stylo-row]\")\n if (cell && widget.contains(cell)) {\n const at = cellSourcePos(\n view.state.doc,\n pos,\n Number(cell.dataset.styloRow),\n Number(cell.dataset.styloCol),\n )\n if (at != null) pos = at + caretOffsetInCell(cell, event.clientX, event.clientY)\n }\n view.focus()\n view.dispatch({ selection: { anchor: pos } })\n return true\n },\n click(event) {\n if (!opts.onWikiLinkClick) return false\n const el = (event.target as HTMLElement | null)?.closest(\"[data-stylo-wikilink]\")\n if (!el) return false\n opts.onWikiLinkClick(el.getAttribute(\"data-stylo-wikilink\") ?? \"\")\n return false\n },\n }),\n ]\n}\n","import { useRef, useState } from \"react\"\nimport type { EditorView } from \"@codemirror/view\"\nimport { useCodeMirror } from \"../editor/useCodeMirror\"\nimport styles from \"../styles/stylo.module.css\"\nimport type { CodeLanguages, InPlaceConfig } from \"../types\"\nimport { inPlaceExtension } from \"./extension\"\n\nexport interface InPlaceViewProps {\n value: string\n onChange: (next: string) => void\n readOnly?: boolean\n placeholder?: string\n onWikiLinkClick?: (target: string) => void\n /** Fired by the link editor's \"Open link\" action. */\n onLinkClick?: (href: string) => void\n /** Read once, when the canvas mounts — see ADR-005. */\n inPlace?: InPlaceConfig\n /** Fenced-code grammars, forwarded to the Markdown language. Read once. */\n codeLanguages?: CodeLanguages\n /** Called with the doc string on `Mod-s`. */\n onSave?: (value: string) => void\n /** Called with the `EditorView` once created, and with `null` on teardown. */\n onViewChange?: (view: EditorView | null) => void\n}\n\n/**\n * The in-place canvas: a CodeMirror surface that renders Markdown structure live\n * via view decorations, revealing the raw source under the cursor. Loaded lazily\n * so `mode=\"source\"` consumers never pull it in.\n *\n * The extension array (and the `inPlace` config baked into it) is built once;\n * `onWikiLinkClick` is reached through a ref so a changed handler does not force\n * the editor to be rebuilt.\n */\nexport function InPlaceView({\n value,\n onChange,\n readOnly,\n placeholder,\n onWikiLinkClick,\n onLinkClick,\n inPlace,\n codeLanguages,\n onSave,\n onViewChange,\n}: InPlaceViewProps) {\n const clickRef = useRef(onWikiLinkClick)\n clickRef.current = onWikiLinkClick\n const linkRef = useRef(onLinkClick)\n linkRef.current = onLinkClick\n\n // Built once; a changed handler is picked up through the ref, not a rebuild.\n const [extensions] = useState(() => [\n inPlaceExtension({\n onWikiLinkClick: (target) => clickRef.current?.(target),\n onLinkClick: (href) => linkRef.current?.(href),\n inPlace,\n }),\n ])\n\n const ref = useCodeMirror({\n value,\n onChange,\n readOnly,\n placeholder,\n extensions,\n codeLanguages,\n onSave,\n onViewChange,\n })\n return <div className={styles.inplace} ref={ref} />\n}\n"],"mappings":";;;;;;;;;;;AAcA,IAAM,KAAmC;CACvC,UAAU;CACV,UAAU;CACV,OAAO;CACP,WAAW;CACX,MAAM;CACN,OAAO;CACP,OAAO;CACP,YAAY;CACZ,gBAAgB;CAChB,MAAM;CACN,aAAa;CACb,QAAQ;AACV;AAEA,SAAgB,GAAe,GAAyC;CACtE,OAAO;EAAE,GAAG;EAAiB,GAAG,GAAQ;CAAY;AACtD;AAOA,IAAa,IAAqB,EAAM,OAAyC,EAC/E,UAAU,MAAW,EAAO,MAAM,GACpC,CAAC,GAGY,IAAoB,EAAM,OAAmC,EACxE,UAAU,MAAW,EAAO,MAAM,SACpC,CAAC,GAMY,IAAkB,EAAM,OAA+B,EAClE,UAAU,MAAW,EAAO,MAAM,QACpC,CAAC,GAMY,KAAgB,EAAM,OAGjC,EACA,UAAU,MAAW,EAAO,MAAM,KACpC,CAAC,GAMY,IAAqB,EAAM,OAAyB,EAC/D,UAAU,MAAW,EAAO,MAAM,GACpC,CAAC,GAGY,IAAqC;CAChD;CACA;CACA;CACA;CACA;AACF,GAGa,IAAkD;CAC7D;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAGA,SAAgB,GAAmB,GAGjC;CAGA,OAFI,MAAM,KAAc;EAAE,SAAS;EAAO,QAAQ,CAAC;CAAE,IACjD,KAAK,QAAQ,MAAM,KAAa;EAAE,SAAS;EAAM,QAAQ;CAAoB,IAC1E;EAAE,SAAS;EAAM,QAAQ,EAAE,QAAQ,SAAS,EAAE,SAAS;CAAoB;AACpF;AAMA,IAAa,IAAkB,EAAM,OAAqC,EACxE,UAAU,MAAW,EAAO,MAAM,EACpC,CAAC;AAGD,SAAgB,GAAyB,GAA8C;CACrF,IAAI,CAAC,GAAK,QAAQ,OAAO;CACzB,IAAM,IAAO,EAAI,QAAQ,MAAO,EAA4B,SAAS,CAAE,CAAC;CACxE,OAAO,EAAK,SAAS,IAAO;AAC9B;AAMA,IAAa,KAAyB,EAAM,OAA+C,EACzF,UAAU,MAAW,EAAO,MAAM,EACpC,CAAC,GAQY,IAAmB,EAAM,OAAiC,EACrE,UAAU,MAAW,EAAO,MAAM,OACpC,CAAC;;;AChID,SAAS,GAAM,GAAmC;CAChD,IAAI,CAAC,EAAM,MAAM,CAAkB,CAAC,CAAC,aAAa,OAAO,EAAW;CACpE,IAAM,IAAQ,EAAiB,EAAM,GAAG;CACxC,IAAI,CAAC,GAAO,OAAO,EAAW;CAE9B,IAAM,IAAQ,EAAM,IAAI,OAAO,EAAM,IAAI,CAAC,CAAC,QACrC,IAAO,EAAM,IAAI,OAAO,EAAM,EAAE,CAAC,CAAC,QAClC,IAAW,EAAM,UAAU,OAAO,MAAM,MAAM;EAClD,IAAM,IAAI,EAAM,IAAI,OAAO,EAAE,IAAI,CAAC,CAAC;EACnC,OAAO,KAAK,KAAS,KAAK;CAC5B,CAAC,GAEK,IAAM,CAAC;CACb,KAAK,IAAI,IAAI,GAAO,KAAK,GAAM,KAAK;EAClC,IAAM,IAAO,EAAM,IAAI,KAAK,CAAC,GACvB,IAAM,MAAM,IAAQ,sCAAsC;EAGhE,AAFA,EAAI,KAAK,EAAW,KAAK,EAAE,OAAO,EAAI,CAAC,CAAC,CAAC,MAAM,EAAK,IAAI,CAAC,IAEpD,MAAM,KAAS,MAAM,MAAS,CAAC,KAAY,EAAK,KAAK,EAAK,QAC7D,EAAI,KAAK,EAAW,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,EAAK,MAAM,EAAK,EAAE,CAAC;CAE7D;CACA,OAAO,EAAW,IAAI,GAAK,EAAI;AACjC;AASA,IAAa,KAAmB,EAAW,OAAsB;CAC/D,QAAQ;CACR,SAAS,GAAO,MAAQ,EAAG,cAAc,EAAG,YAAY,GAAM,EAAG,KAAK,IAAI;CAC1E,UAAU,MAAU,EAAW,YAAY,KAAK,CAAK;AACvD,CAAC;;;ACzBD,SAAS,GAAQ,GAA6B;CAC5C,IAAI,IAAQ;CACZ,KAAK,IAAI,IAAI,EAAK,KAAK,QAAQ,GAAG,IAAI,EAAE,QACtC,AAAI,EAAE,SAAS,cAAY;CAE7B,OAAO;AACT;AAEA,SAAgB,GACd,GACA,GACA,GACA,GACA,GACA,GACM;CACN,IAAI,CAAC,EAAQ,OAAO;CACpB,IAAM,oBAAO,IAAI,IAAY;CAE7B,EAAK,QAAQ;EACX;EACA;EACA,QAAQ,MAAS;GACf,IAAI,EAAK,SAAS,YAAY;GAC9B,IAAM,IAAS,GAAQ,CAAI,IAAI;GAC/B,IAAI,IAAS,GAAG;GAEhB,IAAM,IAAY,EAAI,OAAO,EAAK,IAAI,CAAC,CAAC,QAClC,IAAS,EAAK,KAAK,SAAS,YAAY,KAAK,EAAK,KAAK,SAAS,aAAa,GAC7E,IAAW,EAAI,OAAO,IAAS,EAAO,OAAO,IAAI,KAAK,IAAI,EAAK,IAAI,EAAI,MAAM,CAAC,CAAC,CAAC;GAEtF,KAAK,IAAI,IAAI,GAAW,KAAK,GAAU,KACjC,EAAK,IAAI,CAAC,MACd,EAAK,IAAI,CAAC,GACV,EAAI,KACF,EAAW,KAAK;IACd,OAAO;IACP,YAAY,EAAE,OAAO,iBAAiB,IAAS;GACjD,CAAC,CAAC,CAAC,MAAM,EAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAC3B;EAEJ;CACF,CAAC;AACH;;;ACtDA,SAAgB,EAAc,GAAiC;CAC7D,IAAM,oBAAQ,IAAI,IAAY;CAC9B,KAAK,IAAM,KAAS,EAAM,UAAU,QAAQ;EAC1C,IAAM,IAAQ,EAAM,IAAI,OAAO,EAAM,IAAI,CAAC,CAAC,QACrC,IAAO,EAAM,IAAI,OAAO,EAAM,EAAE,CAAC,CAAC;EACxC,KAAK,IAAI,IAAI,GAAO,KAAK,GAAM,KAAK,EAAM,IAAI,CAAC;CACjD;CACA,OAAO;AACT;;;ACVA,IAAM,qBAAa,IAAI,IAAI;CAAC;CAAc;CAAc;CAAa;AAAU,CAAC;AAMhF,SAAgB,EAAc,GAAY,GAAsB;CAC9D,IAAI,IAAO,EAAK,aAAa,GAAK,CAAC;CACnC,SAAS;EACP,IAAI,GAAW,IAAI,EAAK,IAAI,GAAG,OAAO;EACtC,IAAM,IAAS,EAAK;EACpB,IAAI,CAAC,GAAQ,OAAO;EACpB,IAAO;CACT;AACF;AAGA,SAAgB,EAAc,GAAuB,GAAW,GAAc,GAAqB;CACjG,IAAM,IAAQ,EAAI,OAAO,CAAI,CAAC,CAAC,QACzB,IAAO,EAAI,OAAO,CAAE,CAAC,CAAC;CAC5B,KAAK,IAAI,IAAI,GAAO,KAAK,GAAM,KAAK,IAAI,EAAS,IAAI,CAAC,GAAG,OAAO;CAChE,OAAO;AACT;;;AClBA,IAAM,KAAc,mDACd,KAAiB,0CACjB,KAAY,8BAEZ,IAAN,cAAyB,EAAW;CAEvB;CACA;CAFX,YACE,GACA,GACA;EADS,AAET,MAAM,GAHG,KAAA,MAAA,GACA,KAAA,QAAA;CAGX;CAEA,GAAY,GAAmB;EAC7B,OAAO,EAAM,QAAQ,KAAK,OAAO,EAAM,UAAU,KAAK;CACxD;CAEA,QAAQ;EACN,IAAM,IAAK,SAAS,cAAc,KAAK,QAAQ,QAAQ,MAAM;EAC7D,EAAG,YAAY,KAAK,QAAQ,0CAA0C;EACtE,IAAI;GACF,GAAM,OAAO,KAAK,KAAK,GAAI;IAAE,aAAa,KAAK;IAAO,cAAc;GAAM,CAAC;EAC7E,QAAQ;GACN,EAAG,cAAc,KAAK,QAAQ,KAAK,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI;EACjE;EACA,OAAO;CACT;CAEA,cAAuB;EACrB,OAAO;CACT;AACF;AAOA,SAAgB,GACd,GACA,GACA,GACA,GACA,GACA,GACM;CACN,IAAM,IAAO,EAAK,MAAM,IAAI,YAAY,GAAM,CAAE;CAChD,IAAI,CAAC,EAAK,SAAS,GAAG,GAAG;CACzB,IAAM,EAAE,WAAQ,EAAK,OACf,IAAmC,CAAC;CAE1C,KAAK,IAAM,KAAK,EAAK,SAAS,EAAc,GAAG;EAC7C,IAAM,KAAO,EAAE,MAAM,GAAA,CAAI,KAAK,GACxB,IAAQ,KAAQ,EAAE,SAAS,IAC3B,IAAM,KAAS,EAAE,MAAM,GAAA,CAAI;EAC7B,CAAC,KAAO,EAAc,GAAM,IAAQ,CAAC,MACzC,EAAQ,KAAK,CAAC,GAAO,CAAG,CAAC,GACrB,GAAc,GAAU,GAAK,GAAO,CAAG,KAC3C,EAAI,KAAK,EAAW,QAAQ,EAAE,QAAQ,IAAI,EAAW,GAAK,EAAI,EAAE,CAAC,CAAC,CAAC,MAAM,GAAO,CAAG,CAAC;CACtF;CAEA,KAAK,IAAM,KAAK,EAAK,SAAS,EAAW,GAAG;EAC1C,IAAM,KAAO,EAAE,MAAM,GAAA,CAAI,KAAK,GACxB,IAAQ,KAAQ,EAAE,SAAS,IAC3B,IAAM,KAAS,EAAE,MAAM,GAAA,CAAI;EAC7B,CAAC,KAAO,EAAc,GAAM,IAAQ,CAAC,KACrC,EAAQ,MAAM,CAAC,GAAG,OAAO,KAAS,KAAK,KAAO,CAAC,KAC/C,EAAc,GAAU,GAAK,GAAO,CAAG,KAC3C,EAAI,KAAK,EAAW,QAAQ,EAAE,QAAQ,IAAI,EAAW,GAAK,EAAK,EAAE,CAAC,CAAC,CAAC,MAAM,GAAO,CAAG,CAAC;CACvF;AACF;AAOA,IAAa,KAAiB,EAAW,OAAsB;CAC7D,QAAQ;CACR,OAAO,GAAO,GAAI;EAChB,OAAO,EAAG,cAAc,EAAG,YAAY,GAAe,EAAG,KAAK,IAAI;CACpE;CACA,UAAU,MAAU,CAClB,EAAW,YAAY,KAAK,CAAK,GACjC,EAAW,aAAa,IAAI,MAAS,EAAK,MAAM,MAAM,CAAK,CAAC,CAC9D;AACF,CAAC;AAED,SAAS,GAAe,GAAmC;CACzD,IAAI,CAAC,EAAM,MAAM,CAAkB,CAAC,CAAC,MAAM,OAAO,EAAW;CAC7D,IAAM,IAAO,EAAM,IAAI,SAAS;CAChC,IAAI,CAAC,EAAK,SAAS,IAAI,GAAG,OAAO,EAAW;CAE5C,IAAM,IAA2B,CAAC,GAC5B,IAAW,EAAc,CAAK,GAC9B,IAAO,EAAW,CAAK;CAE7B,KAAK,IAAM,KAAK,EAAK,SAAS,EAAS,GAAG;EACxC,IAAM,IAAM,EAAE,MAAM,IACd,KAAO,EAAE,MAAM,GAAA,CAAI,KAAK;EAC9B,IAAI,CAAC,KAAO,CAAC,EAAI,SAAS,IAAI,GAAG;EAEjC,IAAM,IAAQ,EAAE,SAAS,GACnB,IAAM,IAAQ,EAAI,QAClB,IAAY,EAAM,IAAI,OAAO,CAAK,GAClC,IAAU,EAAM,IAAI,OAAO,CAAG,GAC9B,IAAS,EAAM,IAAI,YAAY,EAAU,MAAM,CAAK,CAAC,CAAC,KAAK,GAC3D,IAAQ,EAAM,IAAI,YAAY,GAAK,EAAQ,EAAE,CAAC,CAAC,KAAK;EACtD,MAAW,MAAM,MAAU,OAC3B,EAAc,GAAM,IAAQ,CAAC,KAC7B,EAAc,GAAU,EAAM,KAAK,GAAO,CAAG,KAEjD,EAAI,KACF,EAAW,QAAQ;GAAE,QAAQ,IAAI,EAAW,GAAK,EAAI;GAAG,OAAO;EAAK,CAAC,CAAC,CAAC,MAAM,GAAO,CAAG,CACzF;CACF;CAEA,OAAO,EAAW,IAAI,GAAK,EAAI;AACjC;;;AC3HA,IAAa,KAAb,cAA8B,EAAW;CACvC,KAAc;EACZ,OAAO;CACT;CAEA,QAAQ;EACN,IAAM,IAAK,SAAS,cAAc,IAAI;EAEtC,OADA,EAAG,YAAY,iBACR;CACT;CAEA,cAAuB;EACrB,OAAO;CACT;AACF,GAGa,KAAb,cAAkC,EAAW;CAC3C,KAAc;EACZ,OAAO;CACT;CAEA,QAAQ;EACN,IAAM,IAAK,SAAS,cAAc,MAAM;EAGxC,OAFA,EAAG,YAAY,qBACf,EAAG,cAAc,KACV;CACT;CAEA,cAAuB;EACrB,OAAO;CACT;AACF,GAMa,KAAb,cAAoC,EAAW;CACxB;CAArB,YAAY,GAA2B;EAAlB,AACnB,MAAM,GADa,KAAA,UAAA;CAErB;CAEA,GAAY,GAAuB;EACjC,OAAO,EAAM,YAAY,KAAK;CAChC;CAEA,MAAM,GAAkB;EACtB,IAAM,IAAQ,SAAS,cAAc,OAAO;EAS5C,OARA,EAAM,OAAO,YACb,EAAM,UAAU,KAAK,SACrB,EAAM,YAAY,uBAClB,EAAM,iBAAiB,cAAc,MAAU,EAAM,gBAAgB,CAAC,GACtE,EAAM,iBAAiB,gBAAgB;GACrC,IAAM,IAAK,EAAK,SAAS,CAAK,IAAI;GAClC,EAAK,SAAS,EAAE,SAAS;IAAE,MAAM;IAAI,IAAI,IAAK;IAAG,QAAQ,KAAK,UAAU,MAAM;GAAI,EAAE,CAAC;EACvF,CAAC,GACM;CACT;CAEA,cAAuB;EACrB,OAAO;CACT;AACF,GC3DM,KAAU,uBACV,KAAS,yBACT,KAAS,WAGT,KAA2F;CAC/F,gBAAgB;EAAE,MAAM;EAAgB,WAAW;EAAqB,QAAQ;CAAW;CAC3F,UAAU;EAAE,MAAM;EAAgB,WAAW;EAAiB,QAAQ;CAAW;CACjF,eAAe;EAAE,MAAM;EAAqB,WAAW;EAAqB,QAAQ;CAAW;CAE/F,YAAY;EAAE,MAAM;EAAY,WAAW;EAAmB,QAAQ;CAAO;AAC/E;AAqBA,SAAgB,GAAa,GAAqB,GAAmC;CACnF,IAAM,EAAE,QAAK,aAAU,kBAAe,QAAK,YAAS,UAAO,qBAAkB;CAC7E,IAAI,EAAK,MAAM,GAAO,OAAO;CAE7B,IAAM,IAAU,GAAQ,KAAK,EAAK,IAAI;CACtC,IAAI,GAAS;EACX,IAAI,EAAQ,UAAU;GACpB,IAAM,IAAO,EAAI,OAAO,EAAK,IAAI;GAYjC,IAXA,EAAI,KACF,EAAW,KAAK;IACd,OAAO,kCAAkC,EAAQ;IAMjD,YAAY;KAAE,MAAM;KAAW,cAAc,EAAQ;IAAI;GAC3D,CAAC,CAAC,CAAC,MAAM,EAAK,IAAI,CACpB,GACI,CAAC,EAAS,IAAI,EAAK,MAAM,GAAG;IAC9B,IAAM,IAAK,EAAK,KAAK;IACrB,AAAI,GAAI,SAAS,gBACf,EAAI,KAAK,EAAW,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,EAAG,MAAM,KAAK,IAAI,EAAG,KAAK,GAAG,EAAK,EAAE,CAAC,CAAC;GAEhF;EACF;EACA;CACF;CAQA,IAAM,IAAS,GAAO,KAAK,EAAK,IAAI;CACpC,IAAI,GAAQ;EACV,IAAI,EAAQ,UAAU;GACpB,IAAM,IAAW,EAAI,OAAO,EAAK,IAAI;GACrC,EAAI,KACF,EAAW,KAAK;IACd,OAAO,kCAAkC,EAAO;IAChD,YAAY;KAAE,MAAM;KAAW,cAAc,EAAO;IAAI;GAC1D,CAAC,CAAC,CAAC,MAAM,EAAS,IAAI,CACxB;GACA,IAAM,IAAK,EAAK,KAAK,SAAS,YAAY;GAC1C,IAAI,GAAI;IACN,IAAM,IAAY,EAAI,OAAO,EAAG,IAAI;IACpC,AAAI,CAAC,EAAc,IAAI,EAAS,MAAM,KAAK,CAAC,EAAc,IAAI,EAAU,MAAM,MAC5E,EAAI,KAAK,EAAW,KAAK,EAAE,OAAO,yBAAyB,CAAC,CAAC,CAAC,MAAM,EAAU,IAAI,CAAC,GACnF,EAAI,KAAK,EAAW,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,EAAG,MAAM,EAAG,EAAE,CAAC;GAEzD;EACF;EACA;CACF;CAEA,IAAM,IAAO,GAAO,EAAK;CACzB,IAAI,GAAM;EACR,IAAI,CAAC,EAAQ,EAAK,SAAS;EAC3B,IAAM,IAAQ,EAAK,KAAK,YAAY,EAAK,IAAI,GACvC,IAAO,EAAM,IACb,IAAQ,EAAM,EAAM,SAAS,IAC7B,IAAS,KAAQ,KAAS,MAAS,GACnC,IAAO,IAAS,EAAK,KAAK,EAAK,MAC/B,IAAK,IAAS,EAAM,OAAO,EAAK;EAItC,AAHI,IAAK,KACP,EAAI,KAAK,EAAW,KAAK,EAAE,OAAO,EAAK,UAAU,CAAC,CAAC,CAAC,MAAM,GAAM,CAAE,CAAC,GAEjE,KAAU,CAAC,EAAS,IAAI,EAAI,OAAO,EAAK,IAAI,CAAC,CAAC,MAAM,MACtD,EAAI,KAAK,EAAW,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,EAAK,MAAM,EAAK,EAAE,CAAC,GACzD,EAAI,KAAK,EAAW,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,EAAM,MAAM,EAAM,EAAE,CAAC;EAE7D;CACF;CAEA,IAAI,EAAK,SAAS,QAAQ;EACxB,IAAM,IAAS,EAAI,YAAY,KAAK,IAAI,GAAG,EAAK,OAAO,CAAC,GAAG,EAAK,IAAI,GAC9D,IAAQ,EAAI,YAAY,EAAK,IAAI,EAAK,KAAK,CAAC;EAElD,IADI,MAAW,OAAO,MAAU,OAC5B,CAAC,EAAQ,OAAO,OAAO;EAI3B,IAAM,IAAW,EAAI,OAAO,EAAK,IAAI,GAC/B,IAAc,EAAkB,KAAK,EAAS,IAAI;EACxD,IACE,KACA,EAAK,OAAO,EAAS,OAAO,EAAY,EAAE,CAAE,SAAS,EAAY,EAAE,CAAE,QAErE,OAAO;EAGT,IAAM,IAAQ,EAAK,KAAK,YAAY,UAAU;EAC9C,IAAI,EAAM,UAAU,GAAG;GACrB,IAAM,IAAO,EAAM,IACb,IAAO,EAAM;GAInB,AAHI,EAAK,OAAO,EAAK,MACnB,EAAI,KAAK,EAAW,KAAK,EAAE,OAAO,kBAAkB,CAAC,CAAC,CAAC,MAAM,EAAK,IAAI,EAAK,IAAI,CAAC,GAE7E,EAAS,IAAI,EAAI,OAAO,EAAK,IAAI,CAAC,CAAC,MAAM,MAC5C,EAAI,KAAK,EAAW,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,EAAK,MAAM,EAAK,EAAE,CAAC,GACzD,EAAI,KAAK,EAAW,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,EAAK,MAAM,EAAK,EAAE,CAAC;EAE7D;EACA;CACF;CAEA,IAAI,EAAK,SAAS,kBAAkB;EAClC,IAAI,CAAC,EAAQ,gBAAgB,OAAO;EACpC,IAAM,IAAO,EAAI,OAAO,EAAK,IAAI;EAUjC,OALK,EAAc,IAAI,EAAK,MAAM,MAEhC,EAAI,KAAK,EAAW,KAAK,EAAE,OAAO,qBAAqB,CAAC,CAAC,CAAC,MAAM,EAAK,IAAI,CAAC,GAC1E,EAAI,KAAK,EAAW,QAAQ,EAAE,QAAQ,IAAI,GAAS,EAAE,CAAC,CAAC,CAAC,MAAM,EAAK,MAAM,EAAK,EAAE,CAAC,IAE5E;CACT;CAEA,IAAI,EAAK,SAAS,cAAc;EAC9B,IAAI,EAAQ,YAAY;GACtB,IAAM,IAAQ,EAAI,OAAO,EAAK,IAAI,CAAC,CAAC,QAC9B,IAAO,EAAI,OAAO,KAAK,IAAI,EAAK,IAAI,EAAI,MAAM,CAAC,CAAC,CAAC,QACjD,IAAW,EAAI,KAAK,CAAK,GAIzB,IAAO,EAAkB,KAAK,EAAS,IAAI,GAC3C,IAAO,IAAO,GAAc,EAAK,EAAG,IAAI,MAK1C,IAAgB;GACpB,KAAK,IAAI,IAAI,GAAO,KAAK,GAAM,KAAK,AAAI,EAAc,IAAI,CAAC,MAAG,IAAgB;GAC9E,IAAI,GAAe,KAAK,IAAI,IAAI,GAAO,KAAK,GAAM,KAAK,EAAc,IAAI,CAAC;GAE1E,KAAK,IAAI,IAAI,GAAO,KAAK,GAAM,KAAK;IAClC,IAAI,IAAM,IAAO,yCAAyC,MAAS;IAEnE,AADI,KAAQ,MAAM,MAAO,KAAO,6BAC5B,KAAQ,MAAM,MAAM,KAAO;IAC/B,IAAM,IAAqC,CAAC;IAG5C,AAFI,MAAM,EAAW,kBAAkB,EAAM,EAAE,CAAE,YAAY,IACzD,KAAQ,MAAe,EAAW,mBAAmB,KACzD,EAAI,KAAK,EAAW,KAAK;KAAE,OAAO;KAAK;IAAW,CAAC,CAAC,CAAC,MAAM,EAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;GAC9E;GACA,IAAI,KAAQ,CAAC,KAAiB,CAAC,EAAS,IAAI,CAAK,GAAG;IAClD,IAAM,IAAY,EAAS,OAAO,EAAM,EAAE,CAAE;IAC5C,EAAI,KAAK,EAAW,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,GAAW,IAAY,EAAM,EAAE,CAAE,MAAM,CAAC;GAChF;EACF;EACA;CACF;CAEA,IAAI,EAAK,SAAS,aAAa;EAC7B,IAAI,CAAC,EAAQ,YAAY,OAAO;EAChC,IAAM,IAAO,EAAI,OAAO,EAAK,IAAI;EACjC,IAAI,CAAC,EAAS,IAAI,EAAK,MAAM,KAAK,CAAC,EAAc,IAAI,EAAK,MAAM,GAAG;GAKjE,IAAM,IAAY,KAAK,IAAI,EAAK,KAAK,GAAG,EAAK,EAAE,GACzC,IAAO,EAAkB,KAAK,EAAK,IAAI,GACvC,IAAO,IACT,EAAK,KAAK,MAAM,EAAK,EAAE,CAAE,SAAS,EAAK,EAAE,CAAE,MAAM,IACjD,EAAK,KAAK,MAAM,IAAY,EAAK,IAAI;GACzC,EAAI,KAAK,EAAW,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,EAAK,MAAM,EAAK,KAAK,MAAM,KAAK,EAAK,KAAK,CAAS,CAAC;EAC5F;EACA,OAAO;CACT;CAEA,IAAI,EAAK,SAAS,YAAY;EAC5B,IAAM,IAAO,EAAI,YAAY,EAAK,MAAM,EAAK,EAAE,GACzC,IAAO,EAAI,OAAO,EAAK,IAAI,GAC3B,IAAO,EAAK,KAAK,QACjB,IAAS,GAAQ,GAAM,SAAS,MAAM,KAAK,GAAM,SAAS,YAAY;EAU5E,OATI,EAAS,IAAI,EAAK,MAAM,MACxB,IAEE,EAAQ,SACV,EAAI,KAAK,EAAW,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,EAAK,MAAM,KAAK,IAAI,EAAK,KAAK,GAAG,EAAK,EAAE,CAAC,CAAC,IAEzE,EAAQ,SAAS,GAAO,KAAK,CAAI,KAC1C,EAAI,KAAK,EAAW,QAAQ,EAAE,QAAQ,IAAI,GAAa,EAAE,CAAC,CAAC,CAAC,MAAM,EAAK,MAAM,EAAK,EAAE,CAAC,IAPjD;CAUxC;CAEA,IAAI,EAAK,SAAS,cAAc;EAC9B,IAAI,CAAC,EAAQ,OAAO,OAAO;EAC3B,IAAI,CAAC,EAAS,IAAI,EAAI,OAAO,EAAK,IAAI,CAAC,CAAC,MAAM,GAAG;GAC/C,IAAM,IAAU,EAAI,YAAY,EAAK,OAAO,GAAG,EAAK,KAAK,CAAC,CAAC,CAAC,YAAY,MAAM;GAC9E,EAAI,KACF,EAAW,QAAQ,EAAE,QAAQ,IAAI,GAAe,CAAO,EAAE,CAAC,CAAC,CAAC,MAAM,EAAK,MAAM,EAAK,EAAE,CACtF;EACF;EACA,OAAO;CACT;CAEA,IAAI,EAAK,SAAS,gBAAgB,EAAK,SAAS,aAAa;EAC3D,IAAI,CAAC,EAAQ,MAAM,OAAO;EAC1B,IAAM,IAAS,EAAK,SAAS,cACvB,IAAQ,EAAI,OAAO,EAAK,IAAI,CAAC,CAAC,QAC9B,IAAO,EAAI,OAAO,EAAK,KAAK,EAAK,OAAO,EAAK,KAAK,IAAI,EAAK,EAAE,CAAC,CAAC,QAMjE,IAAgB;EACpB,KAAK,IAAI,IAAI,GAAO,KAAK,KAAQ,CAAC,GAAe,KAC/C,AAAI,EAAc,IAAI,CAAC,MAAG,IAAgB;EAM5C,IAAM,IAAc,KAAU,IAAO,KAAS,CAAC;EAE/C,KAAK,IAAI,IAAI,GAAO,KAAK,GAAM,KAAK;GAClC,IAAM,IAAU,MAAW,MAAM,KAAS,MAAM,IAC5C,IAAM;GAGV,AAFI,MAAM,MAAO,KAAO,yBACpB,MAAM,MAAM,KAAO,4BACnB,MAAS,KAAO,IAAc,yBAAyB;GAC3D,IAAM,IAAO,EAAI,KAAK,CAAC;GAEvB,AADA,EAAI,KAAK,EAAW,KAAK,EAAE,OAAO,EAAI,CAAC,CAAC,CAAC,MAAM,EAAK,IAAI,CAAC,GACrD,KAAW,KAAe,EAAK,KAAK,EAAK,QAC3C,EAAI,KAAK,EAAW,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,EAAK,MAAM,EAAK,EAAE,CAAC;EAE7D;EACA,OAAO;CACT;AAGF;;;AC7QA,SAAgB,GACd,GACA,GACA,GACA,GACA,GACA,GACM;CACN,IAAM,IAAO,EAAK,MAAM,IAAI,YAAY,GAAM,CAAE;CAC3C,MAAK,SAAS,IAAI,GAEvB,KAAK,IAAM,KAAS,EAAK,SAAS,CAAgB,GAAG;EACnD,IAAM,CAAC,IAAM,IAAI,IAAY,IAAI,KAAY,GACvC,IAAS,EAAU,KAAK,GACxB,IAAQ,KAAQ,EAAM,SAAS;EACrC,IAAI,CAAC,KAAU,EAAc,GAAM,IAAQ,CAAC,GAAG;EAE/C,IAAM,IAAM,IAAQ,EAAI,QAClB,IAAa,KAAY,OAA0C,IAAQ,IAA3C,IAAQ,IAAI,EAAU,SAAS,GAC/D,IAAW,IAAM;EAQvB,AANA,EAAI,KACF,EAAW,KAAK;GACd,OAAO;GACP,YAAY,EAAE,uBAAuB,EAAO;EAC9C,CAAC,CAAC,CAAC,MAAM,GAAY,CAAQ,CAC/B,GACK,EAAS,IAAI,EAAK,MAAM,IAAI,OAAO,CAAK,CAAC,CAAC,MAAM,MACnD,EAAI,KAAK,EAAW,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,GAAO,CAAU,CAAC,GACxD,EAAI,KAAK,EAAW,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,GAAU,CAAG,CAAC;CAExD;AACF;;;AC9BA,IAAM,qBAAwB,IAAI,IAAI,GAGhC,KAAS,EAAW,QAAQ,CAAC,CAAC;AAiBpC,SAAgB,GAAiB,GAAsC;CACrE,IAAM,IAA2B,CAAC,GAO5B,IAAgB,EAAc,EAAK,KAAK,GACxC,IAAW,EAAK,MAAM,MAAM,CAAe,MAAM,UAAU,KAAW,GACtE,IAAO,EAAW,EAAK,KAAK,GAC5B,EAAE,WAAQ,EAAK,OACf,IAAU,EAAK,MAAM,MAAM,CAAkB,GAC7C,IAAM;EACV;EACA;EACA;EACA;EACA;EACA,OAAO,EAAiB,CAAG,CAAC,EAAE,MAAM;EACpC,+BAAe,IAAI,IAAY;CACjC;CAEA,KAAK,IAAM,KAAS,EAAK,eAQvB,AAPA,EAAK,QAAQ;EACX,MAAM,EAAM;EACZ,IAAI,EAAM;EACV,QAAQ,MAAS,GAAa,GAAM,CAAG;CACzC,CAAC,GACG,EAAQ,aAAW,GAAc,GAAM,EAAM,MAAM,EAAM,IAAI,GAAU,GAAM,CAAG,GAChF,EAAQ,QAAM,GAAe,GAAM,EAAM,MAAM,EAAM,IAAI,GAAe,GAAM,CAAG,GACrF,GAAe,EAAM,MAAM,EAAM,IAAI,GAAM,GAAK,GAAS,CAAG;CAS9D,IAAM,IAAW,EACd,QAAQ,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,KAAK,CAAC,CACnD,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,GAC1C,IAA8B,CAAC;CACrC,KAAK,IAAM,KAAK,GAAU;EAKxB,IAAI,CAAC,EAAE,MAAM,KAAK,QAAQ;GACxB,IAAM,IAAO,EAAI,OAAO,EAAE,IAAI;GAC9B,IAAI,EAAE,SAAS,EAAK,QAAQ,EAAE,OAAO,EAAK,IAAI;EAChD;EACA,IAAM,IAAO,EAAO,EAAO,SAAS;EACpC,AAAI,KAAQ,EAAE,QAAQ,EAAK,KACrB,EAAE,KAAK,EAAK,OAAI,EAAO,EAAO,SAAS,KAAK,GAAO,MAAM,EAAK,MAAM,EAAE,EAAE,KAE5E,EAAO,KAAK,GAAO,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;CAE1C;CAEA,OAAO;EACL,aAAa,EAAW,IAAI,GAAK,EAAI;EACrC,QAAQ,EAAW,IAAI,GAAQ,EAAI;CACrC;AACF;;;AC3EA,IAAa,IAAgB,EAAW,UACtC,MAAM;CACJ;CACA;CAEA,YAAY,GAAkB;EAC5B,IAAM,IAAQ,GAAiB,CAAI;EAEnC,AADA,KAAK,cAAc,EAAM,aACzB,KAAK,SAAS,EAAM;CACtB;CAEA,OAAO,GAAoB;EACzB,IAAI,EAAO,cAAc,EAAO,mBAAmB,EAAO,cAAc;GACtE,IAAM,IAAQ,GAAiB,EAAO,IAAI;GAE1C,AADA,KAAK,cAAc,EAAM,aACzB,KAAK,SAAS,EAAM;EACtB;CACF;AACF,GACA;CACE,cAAc,MAAW,EAAO;CAChC,UAAU,MACR,EAAW,aAAa,IAAI,MAAS,EAAK,OAAO,CAAM,CAAC,EAAE,UAAU,EAAW,IAAI;AACvF,CACF;AAEA,SAAgB,KAAgC;CAC9C,OAAO;AACT;;;ACnBA,IAAM,KAA0E;CAC9E,gBAAgB;EAAE,UAAU;EAAgB,QAAQ;CAAW;CAC/D,UAAU;EAAE,UAAU;EAAgB,QAAQ;CAAW;CACzD,eAAe;EAAE,UAAU;EAAqB,QAAQ;CAAW;CACnE,YAAY;EAAE,UAAU;EAAY,QAAQ;CAAO;AACrD;AAcA,SAAgB,EAAc,GAAoB,GAA6B;CAC7E,OAAO,EAAM,MAAM,CAAe,MAAM,WAAW,CAAC,EAAc,CAAK,CAAC,CAAC,IAAI,CAAU;AACzF;AAOA,SAAS,GAAkB,GAAkB,GAAa,GAAqB;CAC7E,IAAM,IAAM,EAAK,OAAO,CAAa,CAAC,EAAE;CACxC,IAAI,CAAC,GAAK,OAAO;CACjB,IAAM,IAAM,IAAM,IAAI,IAAI,EAAK,MAAM,IAAI,QACrC,IAAI;CACR,KAAK,IAAI,IAAQ,IAAM,IAErB,AADA,IAAQ,IACR,EAAI,QAAQ,KAAK,IAAI,GAAG,CAAG,GAAG,KAAK,IAAI,GAAG,CAAG,IAAI,GAAM,GAAI,MAAS;EAC9D,KAAQ,KAAM,EAAK,KAAK,UAAU,EAAK,KAAK,UAC5C,IAAM,IAAI,MAAO,IAAI,MAAS,OAChC,IAAI,IAAM,IAAI,IAAO,GACrB,IAAQ;CAEZ,CAAC;CAEH,OAAO;AACT;AAaA,SAAgB,EACd,GACA,GACA,IAAe,IACf,IAAe,IACF;CACb,IAAM,IAAO,EAAM,IAAI,OAAO,CAAG;CACjC,IAAI,CAAC,KAAgB,CAAC,EAAc,GAAO,EAAK,MAAM,GAAG,OAAO;CAChE,IAAM,IAAU,EAAM,MAAM,CAAkB,GACxC,IAAO,EAAW,CAAK;CAE7B,KAAK,IAAM,KAAQ,CAAC,IAAI,CAAC,GACvB,KAAK,IAAI,IAA0B,EAAK,aAAa,GAAK,CAAI,GAAG,GAAM,IAAO,EAAK,QAAQ;EACzF,IAAM,IAAO,GAAK,EAAK;EACvB,IAAI,GAAM;GACR,IAAI,CAAC,EAAQ,EAAK,SAAS;GAC3B,IAAM,IAAQ,EAAK,YAAY,EAAK,QAAQ,GACtC,IAAO,EAAM,IACb,IAAQ,EAAM,EAAM,SAAS;GACnC,IAAI,CAAC,KAAQ,CAAC,KAAS,MAAS,GAAO;GACvC,OAAO;IACL,MAAM,EAAK;IACX,IAAI,EAAK;IACT,aAAa,EAAK;IAClB,WAAW,EAAM;IACjB,MAAM;GACR;EACF;EACA,IAAI,EAAK,SAAS,QAAQ;GAGxB,IAFI,KACA,EAAM,IAAI,YAAY,KAAK,IAAI,GAAG,EAAK,OAAO,CAAC,GAAG,EAAK,IAAI,MAAM,OACjE,CAAC,EAAQ,OAAO;GACpB,IAAM,IAAQ,EAAK,YAAY,UAAU;GACzC,IAAI,EAAM,SAAS,GAAG;GACtB,OAAO;IACL,MAAM,EAAK;IACX,IAAI,EAAK;IACT,aAAa,EAAM,EAAE,CAAE;IACvB,WAAW,EAAM,EAAE,CAAE;IACrB,MAAM;GACR;EACF;CACF;CAIF,IAAI,EAAQ,aAAa,CAAC,GACxB,KAAK,IAAM,KAAK,EAAK,KAAK,SAAS,CAAgB,GAAG;EACpD,IAAM,IAAO,EAAK,QAAQ,EAAE,SAAS,IAC/B,IAAK,IAAO,EAAE,EAAE,CAAC;EACvB,IAAI,IAAM,KAAQ,IAAM,GAAI;EAC5B,IAAM,IAAS,EAAE,MAAM,IACjB,IAAW,EAAE,MAAM;EACzB,OAAO;GACL;GACA;GACA,aAAa,IAAO,KAAK,IAAW,EAAO,SAAS,IAAI;GACxD,WAAW,IAAK;GAChB,MAAM;EACR;CACF;CAEF,OAAO;AACT;AAGA,IAAM,MACH,OACA,MAA8B;CAC7B,IAAI,EAAgB,CAAI,GAAG,OAAO;CAClC,IAAM,IAAM,EAAK,MAAM,UAAU;CACjC,IAAI,CAAC,EAAI,OAAO,OAAO;CACvB,IAAM,EAAE,aAAU;CAClB,IAAI,CAAC,EAAc,GAAO,EAAM,IAAI,OAAO,EAAI,IAAI,CAAC,CAAC,MAAM,GAAG,OAAO;CAErE,IAAM,IAAQ,GAAkB,GAAM,EAAI,MAAM,CAAG;CACnD,IAAI,MAAU,EAAI,MAAM,OAAO;CAE/B,IAAM,IAAM,EAAM;CAClB,IAAI,IAAM,IAAI,KAAS,IAAI,KAAS,EAAI,QAAQ,OAAO;CAEvD,IAAI,IAAO,IAAM,IAAI,IAAQ,IAAI,GAC7B,IAAK,IAAM,IAAI,IAAQ,IAAQ;CAOnC,KACE,IAAI,IAAI,EAAO,GAAO,CAAI,GAC1B,KAAK,KAAQ,EAAE,eAAe,KAAM,EAAE,aAAa,EAAE,YAAY,EAAE,eAG/D,IAAE,QAAQ,KAAQ,EAAE,MAAM,IAF9B,IAAI,EAAO,GAAO,CAAI,GAItB,AADA,IAAO,KAAK,IAAI,GAAM,EAAE,IAAI,GAC5B,IAAK,KAAK,IAAI,GAAI,EAAE,EAAE;CASxB,OANA,EAAK,SAAS;EACZ,SAAS;GAAE;GAAM;GAAI,QAAQ;EAAG;EAChC,WAAW,EAAE,QAAQ,EAAK;EAC1B,WAAW,IAAM,IAAI,oBAAoB;EACzC,gBAAgB;CAClB,CAAC,GACM;AACT,GAGW,KAAsC,GAAoB,EAAE,GAE5D,KAAqC,GAAoB,CAAC;AAIvE,SAAS,GAAkB,GAAkB,GAAc,GAAqB;CAC9E,IAAI,KAAM,GAAM,OAAO;CACvB,IAAM,IAAM,EAAK,OAAO,CAAa,CAAC,EAAE;CACxC,IAAI,CAAC,GAAK,OAAO;CACjB,IAAI,IAAU;CAKd,OAJA,EAAI,QAAQ,GAAM,IAAK,GAAG,GAAG,MAAS;EAChC,EAAK,KAAK,UAAU,EAAK,KAAK,SAAS,KAAK,KAC5C,KAAK,MAAS,IAAU,KAAK,IAAI,GAAS,CAAC;CACjD,CAAC,GACM,KAAW;AACpB;AAeA,IAAM,KACH,GAAkB,OAClB,MAA8B;CAC7B,IAAI,EAAgB,CAAI,GAAG,OAAO;CAClC,IAAM,IAAM,EAAK,MAAM,UAAU;CAEjC,IADI,CAAC,KAAU,CAAC,EAAI,SAChB,CAAC,EAAc,EAAK,OAAO,EAAK,MAAM,IAAI,OAAO,EAAI,IAAI,CAAC,CAAC,MAAM,GAAG,OAAO;CAE/E,IAAI,IAAQ,EAAK,WAAW,GAAK,CAAO;CAIxC,IADI,GAAkB,GAFX,KAAK,IAAI,EAAI,MAAM,EAAM,IAER,GADjB,KAAK,IAAI,EAAI,MAAM,EAAM,IACJ,CAAE,MAAG,IAAQ,EAAK,WAAW,GAAO,CAAO,IACvE,EAAM,SAAS,EAAI,MAAM,OAAO;CACpC,IAAM,IAAQ,IACV,GAAgB,MAAM,EAAI,QAAQ,EAAM,IAAI,IAC5C,GAAgB,OAAO,EAAM,IAAI;CAErC,OADA,EAAK,SAAS;EAAE,WAAW;EAAO,WAAW;CAAS,CAAC,GAChD;AACT,GAGW,KAAiC,EAAmB,IAAO,EAAK,GAEhE,KAAkC,EAAmB,IAAM,EAAK,GAEhE,KAAkC,EAAmB,IAAO,EAAI,GAEhE,KAAmC,EAAmB,IAAM,EAAI,GAEhE,KAAmC,EAAK,KACnD,GAAO,GAAG;CACR;EAAE,KAAK;EAAa,KAAK;CAA2B;CACpD;EAAE,KAAK;EAAU,KAAK;CAA0B;CAChD;EAAE,KAAK;EAAa,KAAK;CAAsB;CAC/C;EAAE,KAAK;EAAc,KAAK;CAAuB;CACjD;EAAE,KAAK;EAAmB,KAAK;CAAuB;CACtD;EAAE,KAAK;EAAoB,KAAK;CAAwB;AAC1D,CAAC,CACH,GCrPM,MAAW,MACf,MAAO,QAAQ,MAAO,QAAQ,MAAO,OAAO,EAAW,UAAU,EAAW,IAGxE,KAAsC;CAAC;CAAQ;CAAU;AAAQ,GACjE,KAAsC,CAAC,QAAQ,MAAM,GACrD,KAAoC;CAAC;CAAc;CAAe;AAAM,GACxE,KAAuC;CAAC;CAAM;CAAM;AAAI,GACxD,KAAwC,CAAC,SAAS,IAAI,GACtD,KAAuC;CAAC;CAAa;CAAa;AAAa;AAQrF,SAAgB,EAAiB,GAA2B;CAC1D,IAAM,IAAO,EAAgB,CAAI;CACjC,IAAI,CAAC,GAAM,OAAO;CAClB,IAAM,EAAE,SAAM,UAAO,EAAiB,CAAI;CAC1C,OAAO,IAAK;AACd;AAQA,IAAM,MAAY,GAAkB,GAAsB,IAAS,OAA6B;CAC9F,IAAM,IAAM,EAAc;CAE1B,OADK,IACE;EACL,OAAO,EAAI;EACX,MAAM,GAAQ,CAAE;EAChB,QAAQ,MAAiB,EAAQ,EAAI,WAAW,EAAK,KAAK;EAC1D,UAAU,MAAiB,EAAQ,EAAI,WAAW,EAAK,KAAK;EAC5D,gBAAgB;GAEd,AADA,EAAI,IAAI,CAAI,GACZ,EAAK,MAAM;EACb;CACF,IAViB;AAWnB,GAEM,KACJ,GACA,GACA,IAAe,IACf,IAAS,OACQ;CACjB,IAAM,IAAoB,CAAC;CAC3B,KAAK,IAAM,KAAM,GAAK;EACpB,IAAM,IAAI,GAAS,GAAM,GAAI,CAAM;EACnC,AAAI,KAAK,EAAE,KAAgB,EAAE,aAAW,EAAI,KAAK,CAAC;CACpD;CACA,OAAO;AACT,GAEM,KAAiB,MAAgC;CACrD,IAAM,IAAM,EAAK,WAAW,eACtB,KAAQ,YAA8B;EAC1C,EAAK,MAAM;EACX,IAAI;GACF,EAAI,YAAY,CAAG;EACrB,QAAQ,CAER;CACF,GAIM,IAAY,EAAK,IAAI,cAAc,aAAa,WAAW,WAC3D,IAAW,OAAO,GAAW,YAAa;CAehD,OAAO;EACL;GAAE,OAAO;GAAO,MAAM,EAAW;GAAK,UAAU,EAAK,KAAK;EAAE;EAC5D;GAAE,OAAO;GAAQ,MAAM,EAAW;GAAM,UAAU,EAAK,MAAM;EAAE;EAC/D,IACI;GAAE,OAAO;GAAS,MAAM,EAAW;GAAO,gBAlB5B;IAClB,IAAM,IAAO,EAAgB,CAAI;IAEjC,AADK,KAAM,EAAK,MAAM,GACtB,GACI,SAAS,CAAC,CACX,MAAM,MAAS;KACT,MACD,IAAM,EAAI,YAAY,cAAc,IAAO,CAAI,IAC9C,EAAK,SAAS,EAAK,MAAM,iBAAiB,CAAI,CAAC;IACtD,CAAC,CAAC,CACD,YAAY,CAEb,CAAC;GACL;EAKgE,IAC1D;GACE,OAAO;GACP,MAAM,EAAW;GACjB,UAAU;GACV,OAAO;GACP,gBAAgB,CAAC;EACnB;CACN;AACF,GAIM,MAAY,MAAwB;CACxC,IAAM,IAAO,EAAI,KAAK,CAAC,CAAC,QAAQ,cAAc,IAAI;CAClD,OAAO,SAAS,KAAK,CAAI,IAAI,IAAI,EAAK,QAAQ,SAAS,EAAE,EAAE,KAAK;AAClE,GAEM,MAAW,MAAwB,EAAI,QAAQ,cAAc,IAAI;AAQvE,SAAS,GACP,GACA,GACmD;CACnD,IAAM,IAAO,EAAM,IAAI,OAAO,EAAI,IAAI;CACtC,IAAI,EAAM,IAAI,OAAO,EAAI,EAAE,CAAC,CAAC,WAAW,EAAK,QAAQ,OAAO;CAC5D,IAAM,IAAI,EAAI,OAAO,EAAK,MACpB,IAAI,EAAI,KAAK,EAAK,MAClB,IAAO,GAAY,EAAK,MAAM,CAAC,KAAK,GAAY,EAAK,MAAM,CAAC;CAClE,IAAI,GAAM,OAAO;EAAE,MAAM,EAAK,OAAO,EAAK;EAAM,IAAI,EAAK,OAAO,EAAK;EAAI,MAAM,EAAK;CAAM;CAC1F,IAAM,IAAO,GAAa,EAAK,MAAM,CAAC,KAAK,GAAa,EAAK,MAAM,CAAC;CAEpE,OADI,IAAa;EAAE,MAAM,EAAK,OAAO,EAAK;EAAM,IAAI,EAAK,OAAO,EAAK;EAAI,MAAM,EAAK;CAAM,IACnF;AACT;AAQA,SAAgB,EAAQ,GAA6B;CACnD,IAAM,EAAE,aAAU,GACZ,IAAM,EAAM,UAAU,MACtB,IAAO,EAAM,IAAI,OAAO,EAAI,IAAI,GAChC,IAAQ,GAAY,EAAK,MAAM,EAAI,OAAO,EAAK,IAAI;CAEzD,IAAI,GAAO;EACT,IAAM,IAAO,EAAK,OAAO,EAAM,MACzB,IAAK,EAAK,OAAO,EAAM,IACvB,IAAU,EAAK,OAAO,EAAM,SAC5B,IAAQ,EAAK,OAAO,EAAM,OAC1B,IAAW,EAAM,MAAM,EAAa,GACpC,IAA2B,CAAC;EAkBlC,OAjBI,KAAY,EAAM,OACpB,EAAW,KAAK;GACd,OAAO;GACP,MAAM,EAAW;GACjB,gBAAgB,EAAS,EAAM,GAAG;EACpC,CAAC,GAEH,EAAW,KAAK;GACd,OAAO;GACP,gBAAgB;IAKd,AAJA,EAAK,SAAS;KACZ,SAAS;MAAE;MAAM;MAAI,QAAQ,EAAM;KAAM;KACzC,WAAW;MAAE,QAAQ;MAAM,MAAM,IAAO,EAAM,MAAM;KAAO;IAC7D,CAAC,GACD,EAAK,MAAM;GACb;EACF,CAAC,GACM;GACL,OAAO;GACP,OAAO;GACP,MAAM,EAAW;GACjB,OAAO,GAAQ,EAAM,GAAG;GACxB,aAAa;GACb,WAAW,MAAQ;IAEjB,AADA,EAAK,SAAS,EAAE,SAAS;KAAE,MAAM;KAAS,IAAI;KAAO,QAAQ,GAAS,CAAG;IAAE,EAAE,CAAC,GAC9E,EAAK,MAAM;GACb;GACA,SAAS;EACX;CACF;CAIA,IAAM,IAAO,GAAe,GAAO,CAAG,GAChC,IAAO,IAAO,EAAK,OAAO,EAAI,MAC9B,IAAK,IAAO,EAAK,KAAK,EAAI,IAC1B,KAAS,IAAO,EAAK,OAAO,EAAM,SAAS,EAAI,MAAM,EAAI,EAAE,MAAM;CACvE,OAAO;EACL,OAAO;EACP,OAAO;EACP,MAAM,EAAW;EACjB,OAAO;EACP,aAAa;EACb,WAAW,MAAQ;GAKjB,AAJA,EAAK,SAAS;IACZ,SAAS;KAAE;KAAM;KAAI,QAAQ,IAAI,EAAM,IAAI,GAAS,CAAG,EAAE;IAAG;IAC5D,WAAW;KAAE,QAAQ,IAAO;KAAG,MAAM,IAAO,IAAI,EAAM;IAAO;GAC/D,CAAC,GACD,EAAK,MAAM;EACb;CACF;AACF;AAQA,SAAgB,GAAY,GAA6B;CACvD,IAAM,EAAE,aAAU,GACZ,IAAM,EAAM,UAAU,MACtB,IAAO,EAAM,IAAI,OAAO,EAAI,IAAI,GAChC,IAAQ,EAAgB,EAAK,MAAM,EAAI,OAAO,EAAK,IAAI;CAE7D,IAAI,GAAO;EACT,IAAM,IAAO,EAAK,OAAO,EAAM,MACzB,IAAK,EAAK,OAAO,EAAM,IACvB,IAAa,EAAK,OAAO,EAAM,YAC/B,IAAW,EAAK,OAAO,EAAM,UAC7B,IAAU,EAAM,SAAS,EAAM;EACrC,OAAO;GACL,OAAO;GACP,OAAO;GACP,MAAM,EAAW;GACjB,OAAO,EAAM;GACb,aAAa;GACb,WAAW,MAAW;IAIpB,AAHI,KACF,EAAK,SAAS,EAAE,SAAS;KAAE,MAAM;KAAY,IAAI;KAAU,QAAQ;IAAO,EAAE,CAAC,GAE/E,EAAK,MAAM;GACb;GACA,SAAS,CACP;IACE,OAAO;IACP,gBAAgB;KAKd,AAJA,EAAK,SAAS;MACZ,SAAS;OAAE;OAAM;OAAI,QAAQ;MAAQ;MACrC,WAAW;OAAE,QAAQ;OAAM,MAAM,IAAO,EAAQ;MAAO;KACzD,CAAC,GACD,EAAK,MAAM;IACb;GACF,CACF;EACF;CACF;CAIA,IAAM,IAAO,GAAe,GAAO,CAAG,GAChC,IAAO,IAAO,EAAK,OAAO,EAAI,MAC9B,IAAK,IAAO,EAAK,KAAK,EAAI,IAC1B,IAAQ,IAAO,EAAK,OAAO,EAAM,SAAS,EAAI,MAAM,EAAI,EAAE;CAChE,OAAO;EACL,OAAO;EACP,OAAO;EACP,MAAM,EAAW;EACjB,OAAO;EACP,aAAa;EACb,WAAW,MAAW;GACpB,IAAM,IAAI,KAAU,KAAS,UACvB,IAAS,CAAC,KAAU,MAAW,IAAQ,KAAK,EAAE,MAAM,KAAK,EAAO,GAAG,EAAM;GAK/E,AAJA,EAAK,SAAS;IACZ,SAAS;KAAE;KAAM;KAAI;IAAO;IAC5B,WAAW;KAAE,QAAQ,IAAO;KAAG,MAAM,IAAO,KAAK,KAAU,EAAA,CAAG;IAAO;GACvE,CAAC,GACD,EAAK,MAAM;EACb;CACF;AACF;AAEA,IAAM,KACJ,GACA,GACA,GACA,IAAW,QACM;CAAE;CAAO;CAAM;CAAM;AAAS;AAQjD,SAAgB,GAAa,GAA6B;CACxD,IAAM,IAAO,GAAY,EAAK,KAAK;CACnC,OAAO;EACL,OAAO;EACP,OAAO;EACP,MAAM,EAAW;EACjB,OAAO,GAAM,QAAQ;EACrB,aAAa;EACb,WAAW,MAAS;GAElB,AADI,KAAM,EAAK,SAAS,EAAE,SAAS;IAAE,MAAM,EAAK;IAAM,IAAI,EAAK;IAAI,QAAQ,EAAK,KAAK;GAAE,EAAE,CAAC,GAC1F,EAAK,MAAM;EACb;EACA,SAAS,CACP;GACE,OAAO;GACP,gBAAgB;IAEd,AADA,EAAc,WAAW,IAAI,CAAI,GACjC,EAAK,MAAM;GACb;EACF,CACF;CACF;AACF;AAGA,IAAM,MAAe,GAAkB,IAAS,OAAqB;CACnE,GAAG,EAAQ,GAAM,IAAiB,IAAO,CAAM;CAC/C;CACA,GAAG,EAAQ,GAAM,IAAiB,IAAO,CAAM;AACjD;AAQA,SAAgB,GAAkB,GAA6B;CAC7D,IAAM,IAAS,EAAK,MAAM,MAAM,CAAe,GACzC,IAAkB,CAAC;CAKzB,OAJI,EAAO,SAAS,QAAQ,KAC1B,EAAU,GAAM,CAAC,EAAQ,UAAU,EAAW,QAAQ,GAAY,GAAM,EAAI,CAAC,CAAC,CAAC,GAE7E,EAAO,SAAS,WAAW,KAAG,EAAU,GAAM,EAAc,CAAI,CAAC,GAC9D;AACT;AAGA,IAAM,MAAkB,MAAgC;CACtD,GAAG,EAAQ,GAAM,EAAa;CAC9B;CACA,GAAG,EAAQ,GAAM,CAAC,GAAG,IAAkB,MAAM,CAAC;CAC9C;CACA,GAAG,EAAQ,GAAM,CAAC,OAAO,CAAC;AAC5B,GAGM,MAAe,MAAgC;CACnD,GAAG,EAAQ,GAAM,EAAiB;CAClC;CACA,GAAG,EAAQ,GAAM,EAAgB;AACnC;AAGA,SAAS,EAAU,GAAiB,GAAsB;CACnD,EAAI,WACL,EAAK,UAAQ,EAAK,KAAK,WAAW,GACtC,EAAK,KAAK,GAAG,CAAG;AAClB;AASA,SAAgB,GAAS,GAA6B;CACpD,IAAM,EAAE,aAAU,GACZ,IAAS,EAAM,MAAM,CAAe,GACpC,KAAO,MAAmB,EAAO,SAAS,CAAC;CAKjD,IAAI,EAAiB,CAAI,GAAG,OAAO,GAAkB,CAAI;CAIzD,IAAI,GAAiB,CAAK,GAAG;EAC3B,IAAM,IAAkB,CAAC,GAAa,CAAI,CAAC;EAE3C,OADI,EAAI,WAAW,KAAG,EAAU,GAAM,EAAc,CAAI,CAAC,GAClD;CACT;CAEA,IAAM,IAAM,EAAM,UAAU,MAItB,IAHO,EAAM,IAAI,OAAO,EAAI,IAGjB,CAAA,CAAK,KAAK,KAAK,MAAM,IAIhC,IAAW,CAAC,EAAI,SAAS,EAAQ,EAAM,OAAO,EAAI,IAAI,GAEtD,IAAY,EAAM,MAAM,CAAgB,MAAM,QAE9C,IAAkB,CAAC;CACzB,KAAK,IAAM,KAAK,GACd,AAAI,MAAM,UAAU,IAAW,EAAU,GAAM,CAAC,GAAY,CAAI,GAAG,EAAQ,CAAI,CAAC,CAAC,IACxE,MAAM,YAAY,IACzB,EAAU,GAAM,CAAC,EAAQ,UAAU,EAAW,QAAQ,GAAY,CAAI,GAAG,CAAC,CAAQ,CAAC,CAAC,IAC7E,MAAM,cACb,EAAU,GAAM,CAAC,EAAQ,aAAa,EAAW,WAAW,GAAe,CAAI,CAAC,CAAC,CAAC,IAC3E,MAAM,WACb,EAAU,GAAM,CAAC,EAAQ,UAAU,EAAW,QAAQ,GAAY,CAAI,GAAG,CAAC,CAAQ,CAAC,CAAC,IAC7E,MAAM,eAAa,EAAU,GAAM,EAAc,CAAI,CAAC;CAEjE,OAAO;AACT;;;AC7ZA,SAAgB,GAAa,GAAgC;CAC3D,IAAM,IAAO,SAAS,uBAAuB;CAE7C,OADA,GAAK,GAAM,CAAI,GACR;AACT;AAOA,IAAM,KAAgB;CACpB;EACE,IAAI;EACJ,QAAQ,MAAM,EAAG,QAAQ,mBAAmB,SAAS,eAAe,EAAE,EAAG,CAAC;CAC5E;CACA;EAEE,IAAI;EACJ,QAAQ,MAAM;GACZ,IAAM,IAAO,EAAG,QAAQ,iBAAiB;GAEzC,OADA,GAAM,OAAO,EAAE,IAAK,GAAqB,EAAE,cAAc,GAAM,CAAC,GACzD;EACT;CACF;CACA;EAEE,IAAI,IAAI,OAAO,EAAiB,MAAM;EACtC,QAAQ,MAAM;GACZ,IAAM,IAAO,EAAG,QAAQ,uBAAuB,SAAS,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;GAE1F,OADC,EAAsB,QAAQ,gBAAgB,EAAE,MAAM,IAChD;EACT;CACF;CACA;EACE,IAAI;EACJ,QAAQ,MAAM;GACZ,IAAM,IAAI,EAAG,KAAK,iBAAiB;GAGnC,OAFA,EAAE,OAAO,EAAE,MAAM,IACjB,EAAE,OAAO,EAAW,EAAE,MAAM,EAAE,CAAC,GACxB;EACT;CACF;CACA;EACE,IAAI;EACJ,QAAQ,MAAM,EAAG,UAAU,qBAAqB,EAAG,MAAM,iBAAiB,EAAW,EAAE,EAAG,CAAC,CAAC;CAC9F;CACA;EACE,IAAI;EACJ,QAAQ,MAAM,EAAG,UAAU,qBAAqB,EAAW,EAAE,EAAG,CAAC;CACnE;CACA;EACE,IAAI;EACJ,QAAQ,MAAM,EAAG,QAAQ,qBAAqB,EAAW,EAAE,EAAG,CAAC;CACjE;CACA;EACE,IAAI;EACJ,QAAQ,MAAM,EAAG,MAAM,iBAAiB,EAAW,EAAE,EAAG,CAAC;CAC3D;AACF;AAEA,SAAS,EAAG,GAAa,GAAmB,GAAG,GAA2B;CACxE,IAAM,IAAO,SAAS,cAAc,CAAG;CAGvC,OAFA,EAAK,YAAY,GACjB,EAAK,OAAO,GAAG,CAAQ,GAChB;AACT;AAEA,SAAS,EAAW,GAAgC;CAClD,IAAM,IAAO,SAAS,uBAAuB;CAE7C,OADA,GAAK,GAAM,CAAI,GACR;AACT;AAGA,SAAS,GAAK,GAAc,GAAoB;CAC9C,OAAO,IAAM;EACX,IAAI,IAAK,IACL,IAAkD;EACtD,KAAK,IAAM,KAAQ,IAAO;GACxB,IAAM,IAAI,EAAK,GAAG,KAAK,CAAI;GAC3B,AAAI,MAAM,IAAK,KAAK,EAAE,QAAS,OAC7B,IAAK,EAAE,OACP,IAAM;IAAE;IAAM;GAAE;EAEpB;EACA,IAAI,CAAC,GAAK;GACR,EAAO,YAAY,SAAS,eAAe,CAAI,CAAC;GAChD;EACF;EAGA,AAFI,IAAK,KAAG,EAAO,YAAY,SAAS,eAAe,EAAK,MAAM,GAAG,CAAE,CAAC,CAAC,GACzE,EAAO,YAAY,EAAI,KAAK,MAAM,EAAI,CAAC,CAAC,GACxC,IAAO,EAAK,MAAM,IAAK,EAAI,EAAE,EAAE,CAAC,MAAM;CACxC;AACF;;;ACpEA,SAAgB,GAAgB,GAAiB,GAAyC;CACxF,IAAM,IAAQ,EAAK,SAAS,KACtB,IAAO,EAAK,QAAQ,IACtB,IAA8C,MAC9C,IAAS,GACT,IAAS,GAEP,UAAe;EACnB,AAAI,KAAS,SACX,aAAa,CAAK,GAClB,IAAQ;CAEZ,GAEM,KAAU,MAAoB;EAClC,IAAI,EAAE,gBAAgB,SAAS;EAG/B,AAFA,EAAO,GACP,IAAS,EAAE,SACX,IAAS,EAAE;EACX,IAAM,IAAS,EAAE;EACjB,IAAQ,iBAAiB;GAEvB,AADA,IAAQ,MACR,EAAK,YAAY,GAAQ,GAAQ,CAAM;EACzC,GAAG,CAAK;CACV,GAEM,KAAU,MAAoB;EAC9B,KAAS,SACT,KAAK,IAAI,EAAE,UAAU,CAAM,IAAI,KAAQ,KAAK,IAAI,EAAE,UAAU,CAAM,IAAI,MAAM,EAAO;CACzF;CAOA,OALA,EAAG,iBAAiB,eAAe,CAAM,GACzC,EAAG,iBAAiB,eAAe,CAAM,GACzC,EAAG,iBAAiB,aAAa,CAAM,GACvC,EAAG,iBAAiB,iBAAiB,CAAM,GAEpC;EACL;EACA,eAAe;GAKb,AAJA,EAAO,GACP,EAAG,oBAAoB,eAAe,CAAM,GAC5C,EAAG,oBAAoB,eAAe,CAAM,GAC5C,EAAG,oBAAoB,aAAa,CAAM,GAC1C,EAAG,oBAAoB,iBAAiB,CAAM;EAChD;CACF;AACF;;;AC9BA,IAAM,MAAa,MAAiC,OAAO,KAAM,YAAY,UAAU,GACjF,MAAW,MAA+B,OAAO,KAAM,YAAY,WAAW;AAEpF,SAAgB,EAAkB,GAAe,IAAY,mBAAgC;CAC3F,IAAM,IAAM,EAAI,aAEV,IAAO,EAAI,cAAc,KAAK;CAGpC,AAFA,EAAK,YAAY,GACjB,EAAK,aAAa,mBAAmB,OAAO,GAC5C,EAAK,SAAS;CAEd,IAAI,IAA6B,MAC7B,IAA8B,MAK5B,UAAoB;EAExB,AADA,GAAQ,OAAO,GACf,IAAS;CACX,GAEM,UAAa;EACb,EAAK,WACT,EAAY,GACZ,EAAK,SAAS,IACd,EAAK,gBAAgB,GACrB,IAAS,GACT,IAAS;CACX,GAGM,KAAa,MACjB,EAAG,iBAAiB,cAAc,MAAM;EAEtC,AADA,EAAE,eAAe,GACjB,EAAE,gBAAgB;CACpB,CAAC,GAEG,KAAS,GAAiB,GAAc,MAAkB;EAC9D,AAAI,KAAM,EAAG,YAAY,GAAQ,GAAK,CAAI,CAAC;EAC3C,IAAM,IAAO,EAAI,cAAc,MAAM;EAErC,AADA,EAAK,cAAc,GACnB,EAAG,YAAY,CAAI;CACrB,GAEM,KAAgB,MAA+B;EACnD,IAAM,IAAI,EAAI,cAAc,QAAQ;EAqBpC,OApBA,EAAE,OAAO,UACT,EAAE,YAAY,GAAG,EAAU,QAC3B,EAAM,GAAG,EAAE,OAAO,EAAE,IAAI,GACpB,EAAE,UAAO,EAAE,QAAQ,EAAE,QACrB,EAAE,WAAQ,EAAE,QAAQ,SAAS,KAC7B,EAAE,WACJ,EAAE,WAAW,MAEb,EAAU,CAAC,GAGX,EAAE,iBAAiB,sBAAsB;GACvC,AAAK,EAAE,QAAQ,IAAI,EAAU,iBAAiB,KAAG,EAAY;EAC/D,CAAC,GACD,EAAE,iBAAiB,UAAU,MAAM;GAGjC,AAFA,EAAE,gBAAgB,GAClB,EAAK,GACL,EAAE,SAAS;EACb,CAAC,IAEI;CACT,GAIM,KACJ,GACA,GACA,GACA,IAAW,OACR;EACH,IAAM,IAAI,EAAI,cAAc,QAAQ;EAIpC,IAHA,EAAE,OAAO,UACT,EAAE,YAAY,GAAG,EAAU,QAAQ,EAAU,UAC7C,EAAM,GAAG,GAAM,CAAI,GACf,GAEF,OADA,EAAE,WAAW,IACN;EAET,EAAU,CAAC;EACX,IAAM,UAAa;GACjB,IAAI,GAAQ,QAAQ,QAAQ,GAAM;GAClC,EAAY;GACZ,IAAM,IAAQ,EAAM;GAOnB,AAND,EAAM,QAAQ,MAAM,GACpB,EAAK,YAAY,CAAK,GACtB,GAAY,GAAO,EAAE,sBAAsB,CAAC,GAC5C,IAAS,GAGR,EAAO,cAAc,OAAO,CAAC,EAA8B,MAAM,EAAE,eAAe,GAAK,CAAC;EAC3F;EAMA,OALA,EAAE,iBAAiB,gBAAgB,CAAI,GACvC,EAAE,iBAAiB,UAAU,MAAM;GAEjC,AADA,EAAE,gBAAgB,GAClB,EAAK;EACP,CAAC,GACM;CACT,GAEM,KAAc,MAA8B;EAChD,IAAM,IAAQ,EAAI,cAAc,KAAK;EACrC,EAAM,YAAY,GAAG,EAAU;EAC/B,IAAM,IAAQ,EAAI,cAAc,OAAO;EAYvC,AAXA,EAAM,OAAO,QACb,EAAM,YAAY,GAAG,EAAU,SAC/B,EAAM,QAAQ,EAAE,OACZ,EAAE,gBAAa,EAAM,cAAc,EAAE,cACzC,EAAM,iBAAiB,YAAY,MAAM;GACvC,IAAI,EAAE,QAAQ,SAAS;GACvB,EAAE,eAAe;GACjB,IAAM,IAAI,EAAM,MAAM,KAAK;GAE3B,AADA,EAAK,GACL,EAAE,SAAS,CAAC;EACd,CAAC,GACD,EAAM,YAAY,CAAK;EACvB,KAAK,IAAM,KAAK,EAAE,WAAW,CAAC,GAAG,EAAM,YAAY,EAAa,CAAC,CAAC;EAClE,OAAO;CACT,GAEM,KAAc,MAAiC;EACnD,IAAM,IAAQ,EAAI,cAAc,KAAK;EACrC,EAAM,YAAY,GAAG,EAAU;EAC/B,KAAK,IAAM,KAAK,GACd,IAAI,MAAM,aAAa;GACrB,IAAM,IAAM,EAAI,cAAc,KAAK;GAEnC,AADA,EAAI,YAAY,GAAG,EAAU,OAC7B,EAAM,YAAY,CAAG;EACvB,OAAO,AAAI,GAAU,CAAC,IACpB,EAAM,YAAY,EAAU,EAAE,OAAO,EAAE,YAAY,EAAW,EAAE,IAAI,GAAG,EAAE,QAAQ,CAAC,IACzE,GAAQ,CAAC,IAClB,EAAM,YAAY,EAAU,EAAE,OAAO,EAAE,YAAY,EAAW,CAAC,CAAC,CAAC,IAEjE,EAAM,YAAY,EAAa,CAAC,CAAC;EAGrC,OAAO;CACT,GAGM,KAAS,GAAoB,GAAW,MAAc;EAC1D,IAAM,IAAK,GAAK,cAAc,GACxB,IAAK,GAAK,eAAe;EAE/B,AADA,EAAM,MAAM,OAAO,KACnB,EAAM,MAAM,MAAM;EAClB,IAAM,EAAE,UAAO,cAAW,EAAM,sBAAsB;EAEtD,AADA,EAAM,MAAM,OAAO,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAK,IAAQ,CAAC,CAAC,EAAE,KAC/D,EAAM,MAAM,MAAM,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAK,IAAS,CAAC,CAAC,EAAE;CACjE,GAKM,MAAe,GAAoB,MAAkB;EACzD,IAAM,IAAK,GAAK,cAAc,GACxB,IAAK,GAAK,eAAe;EAE/B,AADA,EAAM,MAAM,OAAO,KACnB,EAAM,MAAM,MAAM;EAClB,IAAM,EAAE,UAAO,cAAW,EAAM,sBAAsB,GAChD,IAAQ,EAAK,QAAQ,GACrB,IAAO,IAAQ,IAAQ,IAAK,IAAI,EAAK,OAAO,IAAQ,IAAI;EAE9D,AADA,EAAM,MAAM,OAAO,GAAG,KAAK,IAAI,GAAG,CAAI,EAAE,KACxC,EAAM,MAAM,MAAM,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,EAAK,MAAM,GAAG,IAAK,IAAS,CAAC,CAAC,EAAE;CAC5E,GAEM,UAAmB;EACvB,IAAM,IAAU,KAAK,IAAI,GACnB,KAAW,MAAa,CAAC,EAAK,SAAS,EAAE,MAAc,GACvD,KAAU,MAAa;GAC3B,AAAI,EAAQ,CAAC,KAAG,EAAK;EACvB,GACM,KAAS,MAAqB;GAClC,AAAI,EAAE,QAAQ,YAAU,EAAK;EAC/B,GAQM,KAAY,MAAa;GACzB,KAAK,IAAI,IAAI,IAAU,OACvB,EAAQ,CAAC,KAAG,EAAK;EACvB;EAOA,AAJA,EAAI,iBAAiB,eAAe,GAAQ,EAAI,GAChD,EAAI,iBAAiB,aAAa,GAAQ,EAAI,GAC9C,EAAI,iBAAiB,WAAW,GAAO,EAAI,GAC3C,EAAI,iBAAiB,UAAU,GAAU,EAAI,GAC7C,UAAe;GAIb,AAHA,EAAI,oBAAoB,eAAe,GAAQ,EAAI,GACnD,EAAI,oBAAoB,aAAa,GAAQ,EAAI,GACjD,EAAI,oBAAoB,WAAW,GAAO,EAAI,GAC9C,EAAI,oBAAoB,UAAU,GAAU,EAAI;EAClD;CACF;CAuBA,OAAO;EACL,IAAI;EACJ,IAAI,SAAS;GACX,OAAO,CAAC,EAAK;EACf;EACA,OA1BY,GAAiB,GAAW,MAAc;GACtD,EAAK;GACL,IAAM,IAAO,EAAW,CAAI;GAI5B,AAHA,EAAK,YAAY,CAAI,GACrB,EAAK,SAAS,IACd,EAAM,GAAM,GAAG,CAAC,GAChB,EAAW;EACb;EAoBE,YAhBiB,GAAc,GAAW,MAAc;GACxD,EAAK;GACL,IAAM,IAAQ,EAAW,CAAC;GAK1B,AAJA,EAAK,YAAY,CAAK,GACtB,EAAK,SAAS,IACd,EAAM,GAAO,GAAG,CAAC,GAChB,EAAO,cAAc,OAAO,CAAC,EAA8B,MAAM,EAAE,eAAe,GAAK,CAAC,GACzF,EAAW;EACb;EASE;EACA,eAAe;GAEb,AADA,EAAK,GACL,EAAK,OAAO;EACd;CACF;AACF;;;AClQA,SAAgB,GAAkB,GAAe,GAA8B;CAC7E,IAAM,IAAK,EAAI,cAAc,KAAK;CAElC,AADA,EAAG,YAAY,2BACf,EAAG,aAAa,mBAAmB,OAAO;CAE1C,IAAM,IAAoB,EAAkB,CAAG,GAEzC,KAAU,GAAmB,GAAe,MAAwB;EACxE,IAAM,IAAI,EAAI,cAAc,QAAQ;EAYpC,OAXA,EAAE,OAAO,UACT,EAAE,YAAY,GACd,EAAE,aAAa,cAAc,CAAK,GAClC,EAAE,iBAAiB,cAAc,MAAM;GAErC,AADA,EAAE,eAAe,GACjB,EAAE,gBAAgB;EACpB,CAAC,GACD,EAAE,iBAAiB,UAAU,MAAM;GAEjC,AADA,EAAE,gBAAgB,GAClB,EAAQ;EACV,CAAC,GACM;CACT,GAQM,KAAQ,GAAqB,GAAe,MAAwB;EACxE,IAAM,IAAQ,EAAO,uCAAuC,KAAQ,GAAO,CAAO,GAC5E,IAAO,EAAI,cAAc,MAAM;EAGrC,OAFA,EAAK,YAAY,sBACjB,EAAM,YAAY,CAAI,GACf;CACT,GAEM,IAAS,EAAK,OAAO,oBACzB,EAAK,IAAI;EAAE,MAAM;EAAgB,IAAI,EAAK,KAAK,CAAC,CAAC;EAAM,OAAO,CAAC,GAAG,EAAK,KAAK,CAAC,CAAC,IAAI;CAAE,CAAC,CACvF,GACM,IAAS,EAAK,OAAO,iBACzB,EAAK,IAAI;EAAE,MAAM;EAAa,IAAI,EAAK,KAAK,CAAC,CAAC;EAAM,OAAO,CAAC,EAAK,KAAK,CAAC,CAAC,MAAM,CAAC;CAAE,CAAC,CACpF;CACA,EAAG,OAAO,GAAQ,GAAQ,EAAK,EAAE;CAEjC,IAAM,KAAQ,GAAW,GAAW,IAAmB,CAAC,MAAiB;EACvE,IAAM,EAAE,SAAM,MAAM,GAAU,eAAY,EAAK,KAAK,GAC9C,KAAQ,GAAe,GAAc,IAAS,QAAoB;GACtE;GACA;GACA,gBAAgB,EAAK,IAAI,CAAE;EAC7B,IACM,IAAkB;GACtB,EAAK,oBAAoB;IAAE,MAAM;IAAa,IAAI;IAAG,OAAO,CAAC,GAAG,CAAC;GAAE,CAAC;GACpE,EAAK,oBAAoB;IAAE,MAAM;IAAa,IAAI,IAAI;IAAG,OAAO,CAAC,IAAI,GAAG,CAAC;GAAE,CAAC;GAC5E,EAAK,sBAAsB;IAAE,MAAM;IAAgB,IAAI;IAAG,OAAO,CAAC,GAAG,CAAC;GAAE,CAAC;GACzE,EAAK,uBAAuB;IAAE,MAAM;IAAgB,IAAI,IAAI;IAAG,OAAO,CAAC,GAAG,IAAI,CAAC;GAAE,CAAC;EACpF;EAOA,AANI,IAAI,KAAK,IAAW,KACtB,EAAK,KAAK,EAAK,cAAc;GAAE,MAAM;GAAa,IAAI;GAAG,OAAO,CAAC,GAAG,CAAC;EAAE,CAAC,CAAC,GAEvE,IAAO,KACT,EAAK,KAAK,EAAK,iBAAiB;GAAE,MAAM;GAAgB,IAAI;GAAG,OAAO,CAAC,GAAG,IAAI,CAAC;EAAE,CAAC,CAAC,GAErF,EAAK,KAAK,WAAW;EACrB,KAAK,IAAM,KAAS;GAAC;GAAQ;GAAU;EAAO,GAC5C,EAAK,KAAK,EAAK,SAAS,KAAS;GAAE,MAAM;GAAS,IAAI;GAAG;EAAM,GAAG,EAAQ,CAAC,MAAM,CAAK,CAAC;EAGzF,OADI,EAAM,UAAQ,EAAK,KAAK,aAAa,GAAG,CAAK,GAC1C;CACT;CA4BA,OAAO;EAAE;EAAI,SAtBG,MAA4B;GAC1C,IAAM,IAAM,CAAC,GAAG,EAAM,IAAI;GAC1B,IAAI,CAAC,EAAI,QAAQ;GACjB,IAAM,IAAO,EAAG,sBAAsB,GAChC,IAAM,EAAI,EAAE,CAAE,sBAAsB,CAAC,CAAC,MAAM,EAAK,KACjD,IAAS,EAAI,EAAI,SAAS,EAAE,CAAE,sBAAsB,CAAC,CAAC,SAAS,EAAK,KACpE,IAAO,EAAM,sBAAsB,GACnC,IAAO,EAAK,OAAO,EAAK,MACxB,IAAQ,EAAK,QAAQ,EAAK;GAWhC,AANA,EAAO,MAAM,OAAO,GAAG,IAAQ,EAAI,KACnC,EAAO,MAAM,MAAM,GAAG,EAAI,KAC1B,EAAO,MAAM,SAAS,GAAG,IAAS,EAAI,KAEtC,EAAO,MAAM,OAAO,GAAG,EAAK,KAC5B,EAAO,MAAM,MAAM,GAAG,IAAS,EAAI,KACnC,EAAO,MAAM,QAAQ,GAAG,IAAQ,EAAK;EACvC;EAEqB,UA1BJ,GAAmB,GAAW,GAAW,MAAsB;GAC9E,EAAK,KAAK,EAAK,OAAO,EAAK,QAAQ,CAAC,GAAG,OAAO,EAAK,QAAQ,CAAC,GAAG,CAAK,GAAG,GAAG,CAAC;EAC7E;EAwB8B,eAAe,EAAK,QAAQ;CAAE;AAC9D;;;AC3HA,IAAM,KAAQ,MAAyB,EAAE,OAAO;AAGhD,SAAgB,GAAa,GAAc,GAAkB;CAC3D,IAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAI,EAAK,CAAC,CAAC,CAAC;CAC3C,KAAK,IAAM,KAAO,EAAE,MAAM,EAAI,OAAO,GAAG,GAAG,EAAE;CAC7C,EAAE,OAAO,OAAO,GAAG,GAAG,EAAE;AAC1B;AAGA,SAAgB,GAAa,GAAc,GAAkB;CACvD,QAAK,CAAC,KAAK,KAAK,IAAK,KAAK,KAAM,EAAK,CAAC,IAC1C;OAAK,IAAM,KAAO,EAAE,MAAM,EAAI,OAAO,GAAI,CAAC;EAC1C,EAAE,OAAO,OAAO,GAAI,CAAC;CADqB;AAE5C;AAGA,SAAgB,GAAU,GAAc,GAAkB;CACxD,IAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAI,EAAE,KAAK,MAAM,CAAC;CACjD,EAAE,KAAK,OAAO,GAAG,GAAO,MAAM,EAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;AACjD;AAGA,SAAgB,GAAU,GAAc,GAAkB;CACpD,KAAM,KAAK,KAAM,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,KACvD,EAAE,KAAK,OAAO,GAAI,CAAC;AACrB;AAGA,SAAgB,GAAS,GAAc,GAAW,GAAoB;CACpE,AAAI,KAAK,KAAK,IAAI,EAAK,CAAC,MAAG,EAAE,OAAO,KAAK;AAC3C;;;AClBA,IAAa,IAAkB,GAAW,OAAgB,GAqB7C,KAAb,cAAyC,EAAW;CAe7B;CAdrB,QAAyC;CACzC;CACA,UAA+C;CAC/C,UAAkB;CAElB,gBAAuC;CACvC;CACA,SAAqC;CACrC,YAA4C;CAI5C,cAAsB;CAEtB,YAAY,GAA4B;EAGtC,AAFA,MAAM,GADa,KAAA,OAAA,GAEnB,KAAK,OAAO,GAAO,CAAI,GACvB,KAAK,UAAU,EAAS,KAAK,IAAI;CACnC;CAEA,GAAY,GAA4B;EAOtC,OADA,CAAI,KAAK,SACF,KAAK,UAAU,KAAK,OAAO,MAAM,KAAK,UAAU,EAAM,OAAO;CACtE;CAEA,cAAuB;EACrB,OAAO;CACT;CAEA,OAAuB;EACrB,OAAO,KAAK,KAAK,OAAO;CAC1B;CAOA,OAAe,GAAgD;EAC7D,IAAM,IAAM,EAAK,MAAM,KACjB,KAAQ,MAAc;GAC1B,IAAM,IAAI,EAAI,KAAK,CAAC,CAAC,CAAC;GACtB,OAAO,EAAE,KAAK,MAAM,MAAM,EAAE,SAAS,GAAG;EAC1C,GACI,IAAQ,EAAI,OAAO,EAAK,SAAS,KAAK,KAAM,CAAC,CAAC,CAAC,QAC/C,IAAO;EACX,OAAO,IAAQ,KAAK,EAAK,IAAQ,CAAC,IAAG;EACrC,OAAO,IAAO,EAAI,SAAS,EAAK,IAAO,CAAC,IAAG;EAC3C,OAAO;GAAE,MAAM,EAAI,KAAK,CAAK,CAAC,CAAC;GAAM,IAAI,EAAI,KAAK,CAAI,CAAC,CAAC;EAAG;CAC7D;CAEA,OAAe,GAAW,GAAwC;EAGhE,OAFK,KAAK,SACE,MAAM,IAAI,KAAK,MAAM,MAAO,KAAK,KAAM,KAAK,MAAM,QAAQ,EAAE,CAAE,KAAK,IAAI,GAAA,EACtE,MAAM,MAA+B,OAF1B;CAG1B;CAEA,OAAe,GAAsD;EACnE,OAAO;GAAE,GAAG,OAAO,EAAK,QAAQ,CAAC;GAAG,GAAG,OAAO,EAAK,QAAQ,CAAC;EAAE;CAChE;CAGA,MAAc,GAA4B,GAAc;EACtD,IAAM,EAAE,MAAG,SAAM,KAAK,OAAO,CAAI,GAC3B,IAAO,KAAK,KAAK,EAAE,GAAG,MAAM;EAClC,EAAK,gBACH,IAAM,EAAK,cAAc,eAAe,CAAI,IAAI,GAAa,EAAa,CAAI,CAAC,CACjF;CACF;CAEA,OAAe,GAAW,GAAW,GAAuC;EAC1E,IAAM,IAAK,SAAS,cAAc,IAAS,OAAO,IAAI;EAOtD,AANA,EAAG,YAAY,oBAIf,EAAG,aAAa,mBAAmB,MAAM,GACzC,EAAG,QAAQ,IAAI,OAAO,CAAC,GACvB,EAAG,QAAQ,IAAI,OAAO,CAAC;EACvB,IAAM,IAAI,KAAK,KAAK,OAAO;EAG3B,OAFI,MAAG,EAAG,MAAM,YAAY,IAC5B,KAAK,MAAM,GAAI,EAAK,GACb;CACT;CAGA,cAAsB;EACpB,IAAM,IAAQ,KAAK;EACnB,EAAM,gBAAgB;EACtB,IAAM,IAAK,EAAM,YAAY,CAAC,CAAC,UAAU;EACzC,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK,GAAG,KAAK,EAAG,YAAY,KAAK,OAAO,GAAG,GAAG,EAAI,CAAC;EAC5E,IAAM,IAAQ,EAAM,YAAY;EAChC,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK,QAAQ,KAAK;GACzC,IAAM,IAAK,EAAM,UAAU;GAC3B,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK,GAAG,KAAK,EAAG,YAAY,KAAK,OAAO,GAAG,GAAG,EAAK,CAAC;EAC/E;CACF;CAEA,YAAoB;EAGlB,AAFA,GAAU,KAAK,MAAM,GAAG,KAAK,KAAK,MAAM,GACxC,KAAK,YAAY,GACjB,KAAK,QAAQ,OAAO,KAAK,KAAM;CACjC;CAEA,QAA2B;EACzB,OAAO;GAAE,MAAM,KAAK;GAAM,QAAQ,KAAK,KAAK;EAAO;CACrD;CAGA,MAAc,GAAkB,GAAc;EAC5C,IAAI,CAAC,KAAK,OAAO;EACjB,IAAM,IAAI,KAAK,MAAM;EAarB,IAZI,EAAG,SAAS,iBAAgB,GAAa,GAAG,EAAG,EAAE,IAC5C,EAAG,SAAS,iBAAgB,GAAa,GAAG,EAAG,EAAE,IACjD,EAAG,SAAS,cAAa,GAAU,GAAG,EAAG,EAAE,IAC3C,EAAG,SAAS,cAAa,GAAU,GAAG,EAAG,EAAE,IAC/C,GAAS,GAAG,EAAG,IAAI,EAAE,OAAO,EAAG,QAAQ,EAAG,QAAQ,KAAK,EAAG,KAAK,GAIpE,KAAK,UAAU,MACf,KAAK,KAAK,CAAI,GACd,KAAK,YAAY,GACjB,KAAK,QAAQ,OAAO,KAAK,KAAM,GAC3B,EAAG,SAAS,SAAS;GACvB,IAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,EAAG,MAAM,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,GAC3D,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,EAAG,MAAM,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC;GAC5D,KAAK,OAAO,GAAG,CAAC,CAAC,EAAE,MAAM;EAC3B;CACF;CAGA,OAAe,GAA4B,GAAkB;EAC3D,IAAM,EAAE,MAAG,SAAM,KAAK,OAAO,CAAI;EAEjC,AADI,KAAK,KAAK,OAAI,KAAK,KAAK,EAAE,CAAE,MAAM,EAAK,eAAe,GAAA,CAAI,QAAQ,UAAU,GAAG,IAC9E,KAAS,KAAK,MAAM,GAAM,EAAK;CACtC;CAEA,UAAkB,GAAmB;EACnC,IAAM,IAAQ,EAAM,OAAuB,QAA8B,QAAQ;EACjF,IAAI,CAAC,KAAQ,MAAS,KAAK,SAAS;EAGpC,IAAM,IAAS,KAAK,iBAAiB,EAAoB,CAAI;EAK7D,AAJA,KAAK,gBAAgB,MACjB,KAAK,WAAS,KAAK,OAAO,KAAK,SAAS,EAAK,GACjD,KAAK,UAAU,GACf,KAAK,MAAM,GAAM,EAAI,GACrB,EAAW,GAAM,CAAM;CACzB;CAEA,WAAmB,GAAmB;EACpC,IAAI,KAAK,WAAW,CAAC,KAAK,SAAS;EACnC,IAAM,IAAK,EAAM;EACb,KAAM,KAAK,OAAO,SAAS,CAAE,MACjC,KAAK,OAAO,KAAK,SAAS,EAAK,GAC/B,KAAK,UAAU;CACjB;CAGA,YAAmF;EACjF,IAAI,CAAC,KAAK,SAAS,OAAO;EAC1B,IAAM,EAAE,MAAG,SAAM,KAAK,OAAO,KAAK,OAAO,GACnC,IAAM,KAAK,QAAQ,cAAc,aAAa,GAC9C,IAAO,KAAK,QAAQ,YACpB,KAAO,KAAK,QAAQ,eAAe,GAAA,CAAI,QACvC,IAAS,GAAK,eAAe,IAAQ,GAAK,gBAAgB,IAAK;EAErE,OAAO;GAAE;GAAG;GAAG;GAAQ,MADV,GAAK,cAAc,IAAQ,GAAK,eAAe,IAAU;EAC1C;CAC9B;CAEA,WAAmB,GAA+D;EAChF,IAAM,IAAO,KAAK,OAAO,EAAM,GAAG,EAAM,CAAC;EACzC,AAAI,KAAM,EAAW,GAAM,EAAM,QAAQ,EAAM,IAAI;CACrD;CAGA,KAAa,GAAkB;EAC7B,IAAI,CAAC,KAAK,OAAO;EACjB,IAAM,IAAQ,KAAK,UAAU,GACvB,IAAO,EAAc;GAAE,MAAM,KAAK;GAAM,QAAQ,KAAK,KAAK;EAAO,CAAC;EACxE,KAAK,UAAU,EAAS,KAAK,IAAI;EACjC,IAAM,EAAE,SAAM,UAAO,KAAK,OAAO,CAAI;EACjC,EAAK,MAAM,SAAS,GAAM,CAAE,MAAM,MAKtC,KAAK,UAAU,IACf,EAAK,SAAS;GACZ,SAAS;IAAE;IAAM;IAAI,QAAQ;GAAK;GAClC,aAAa,EAAgB,GAAG,EAAI;GACpC,WAAW;EACb,CAAC,GACD,KAAK,UAAU,IACX,MACF,KAAK,WAAW,CAAK,GACrB,4BAA4B;GAC1B,AAAI,KAAK,SAAS,KAAO,KAAK,WAAW,CAAK;EAChD,CAAC;CAEL;CAEA,MAAc,GAAsB,GAAkB;EACpD,IAAM,IAAQ,EAAM,OAAuB,QAA8B,QAAQ;EACjF,IAAI,CAAC,KAAQ,CAAC,KAAK,OAAO;EAG1B,IAAI,EAAmB,GAAO,CAAI,GAAG;GACnC,EAAM,gBAAgB;GACtB;EACF;EACA,IAAM,EAAE,GAAG,SAAM,KAAK,OAAO,CAAI,GAC3B,IAAU,KAAK,KAAK,SAAS;EAEnC,IAAI,EAAM,QAAQ,OAAO;GAEvB,AADA,EAAM,eAAe,GACrB,EAAM,gBAAgB;GACtB,IAAM,IAAO,IAAI,KAAK,KAAK,IAAI,KAAK,EAAM,WAAW,KAAK;GAC1D,IAAI,IAAO,GAAG;GACd,IAAI,KAAQ,KAAK,KAAK,SAAS,KAAK,KAAK,GAAG;IAC1C,IAAI,EAAM,UAAU;IAGpB,AAFA,KAAK,UAAU,GACf,KAAK,OAAO,IAAU,GAAG,CAAC,CAAC,EAAE,MAAM,GACnC,KAAK,KAAK,CAAI;IACd;GACF;GACA,KAAK,OAAO,KAAK,MAAM,IAAO,KAAK,KAAK,CAAC,GAAG,IAAO,KAAK,KAAK,CAAC,CAAC,EAAE,MAAM;GACvE;EACF;EACA,IAAI,EAAM,QAAQ,SAAS;GAGzB,IAFA,EAAM,eAAe,GACrB,EAAM,gBAAgB,GAClB,IAAI,GAAS,OAAO,KAAK,OAAO,IAAI,GAAG,CAAC,CAAC,EAAE,MAAM;GAGrD,AAFA,KAAK,UAAU,GACf,KAAK,OAAO,IAAU,GAAG,CAAC,CAAC,EAAE,MAAM,GACnC,KAAK,KAAK,CAAI;GACd;EACF;EACA,IAAM,IAAO,KAAK,KAAK,GACjB,UAAkB;GACtB,IAAM,EAAE,UAAO,KAAK,OAAO,CAAI;GAE/B,AADA,EAAK,MAAM,GACX,EAAK,SAAS,EAAE,WAAW,EAAE,QAAQ,KAAK,IAAI,IAAK,GAAG,EAAK,MAAM,IAAI,MAAM,EAAE,EAAE,CAAC;EAClF,GACM,UAAkB;GACtB,IAAM,EAAE,YAAS,KAAK,OAAO,CAAI;GAEjC,AADA,EAAK,MAAM,GACX,EAAK,SAAS,EAAE,WAAW,EAAE,QAAQ,KAAK,IAAI,IAAO,GAAG,CAAC,EAAE,EAAE,CAAC;EAChE,GACM,KAAa,GAAc,MAAmB;GAClD,IAAM,IAAS,KAAK,OAAO,KAAK,MAAM,IAAO,CAAI,GAAG,IAAO,CAAI;GAC1D,MACL,KAAK,gBAAgB,GACrB,EAAO,MAAM;EACf;EAIA,IAAI,EAAM,QAAQ,aAAa;GAG7B,AAFA,EAAM,eAAe,GACrB,EAAM,gBAAgB,GAClB,MAAM,IAAS,EAAU,IACxB,GAAW,IAAI,KAAK,IAAO,GAAG,KAAK,UAAU,CAAC,EAAE,UAAU,CAAC;GAChE;EACF;EACA,IAAI,EAAM,QAAQ,WAAW;GAG3B,AAFA,EAAM,eAAe,GACrB,EAAM,gBAAgB,GAClB,MAAM,IAAG,EAAU,IAClB,GAAW,IAAI,KAAK,IAAO,GAAG,KAAK,UAAU,CAAC,EAAE,UAAU,CAAC;GAChE;EACF;EAGA,IAAI,EAAM,QAAQ,gBAAgB,EAAM,QAAQ,aAAa;GAC3D,IAAM,IAAO,EAAM,QAAQ,aACrB,IAAQ,KAAK,UAAU;GAE7B,IADI,CAAC,KAAS,EAAM,WAAW,EAAM,SACjC,IAAO,EAAM,SAAS,IAAI,EAAM,UAAU,EAAK,eAAe,GAAA,CAAI,SAAQ;GAE9E,AADA,EAAM,eAAe,GACrB,EAAM,gBAAgB;GACtB,IAAM,IAAO,IAAI,IAAO,KAAK,IAAO,KAAK;GACzC,IAAI,IAAO,GAAG,OAAO,EAAU;GAC/B,IAAI,KAAQ,KAAK,KAAK,SAAS,GAAM,OAAO,EAAU;GACtD,EAAU,GAAM,KAAQ,KAAK,KAAK,KAAK,MAAM,IAAO,CAAI,EAAE,GAAG,IAAO,MAAS,GAAA,CAAI,SAAS,CAAC;GAC3F;EACF;CACF;CAOA,UAAU,GAAiC;EACzC,IAAI,CAAC,KAAK,OAAO,OAAO;EACxB,IAAM,IAAI,MAAS,UAAU,IAAI,KAAK,KAAK,SAAS,GAC9C,IAAI,MAAS,UAAU,IAAI,KAAK,KAAK,IAAI,GACzC,IAAO,KAAK,OAAO,GAAG,CAAC;EAI7B,OAHK,KACL,KAAK,gBAAgB,MAAS,UAAU,KAAK,KAAK,KAAK,EAAE,GAAG,MAAM,GAAA,CAAI,QACtE,EAAK,MAAM,GACJ,MAHW;CAIpB;CAIA,eACE,GACA,GACA,GACA,GACA;EACA,IAAM,IAAO,GAAQ,QAA8B,QAAQ;EAC3D,IAAI,CAAC,GAAM;EACX,AAAI,KAAK,YAAY,KAAQ,CAAC,EAAiB,CAAI,KACjD,EAAkB,GAAM,GAAS,CAAO;EAE1C,IAAM,IAAQ,EAAiB,CAAI,IAAI,GAAkB,CAAI,IAAI,KAAA;EACjE,KAAK,QAAQ,QAAQ,GAAM,GAAS,GAAS,CAAK;CACpD;CAEA,MAAM,GAAkB;EACtB,IAAM,IAAO,SAAS,cAAc,KAAK;EACzC,EAAK,YAAY;EACjB,IAAM,IAAQ,SAAS,cAAc,OAAO;EAgB5C,AAfA,KAAK,QAAQ,GACb,KAAK,UAAU,MACf,EAAM,YAAY,0CAClB,KAAK,YAAY,GAKjB,EAAM,iBAAiB,cAAc,MAAM;GACzC,EAAE,gBAAgB;GAClB,IAAM,IAAQ,EAAE,OAAuB,QAA8B,QAAQ;GAC7E,KAAK,gBACH,KAAQ,MAAS,KAAK,UAAU,EAAgB,GAAM,EAAE,SAAS,EAAE,OAAO,IAAI;EAClF,CAAC,GACD,EAAM,iBAAiB,YAAY,MAAM,KAAK,UAAU,CAAC,CAAC,GAC1D,EAAM,iBAAiB,aAAa,MAAM,KAAK,WAAW,CAAC,CAAC;EAC5D,IAAM,KAAU,MAAsC;GAC/C,MAGL,KAAK,UAAU,GACf,KAAK,OAAO,GAAM,EAAI,GACtB,KAAK,KAAK,CAAI;EAChB;EA+CA,OA9CA,EAAM,iBAAiB,UAAU,MAAM;GAChC,EAAiB,eACtB,EAAQ,EAAE,OAAuB,QAA8B,QAAQ,CAAC;EAC1E,CAAC,GACD,EAAM,iBAAiB,mBAAmB,MACxC,EAAQ,EAAE,OAAuB,QAA8B,QAAQ,CAAC,CAC1E,GACA,EAAM,iBAAiB,YAAY,MAAM,KAAK,MAAM,GAAG,CAAI,CAAC,GAC5D,EAAM,iBAAiB,UAAU,MAAM;GACrC,EAAE,eAAe;GACjB,IAAM,KAAQ,EAAE,eAAe,QAAQ,YAAY,KAAK,GAAA,CAAI,QAAQ,UAAU,GAAG;GACjF,SAAS,YAAY,cAAc,IAAO,CAAI;EAChD,CAAC,GAOD,EAAM,iBAAiB,gBAAgB,MAAM;GAC7B,EAAE,OAAuB,QAA8B,QAChE,MACL,EAAE,eAAe,GACjB,EAAE,gBAAgB,GAClB,KAAK,WAAW,OAAO,GACnB,OAAK,IAAI,IAAI,KAAK,cAAc,QACpC,KAAK,eAAe,GAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAA4B;EAChF,CAAC,GACD,KAAK,YAAY,GAAgB,GAAO,EACtC,cAAc,GAAG,GAAG,MAAM;GAExB,AADA,KAAK,cAAc,KAAK,IAAI,GAC5B,KAAK,eAAe,GAAM,GAAG,GAAG,CAAuB;EACzD,EACF,CAAC,GAED,KAAK,SAAS,GAAkB,UAAU;GACxC,aAAa;IACX,MAAM,KAAK,KAAK;IAChB,MAAM,KAAK,KAAK;IAChB,UAAU,MAAM,KAAK,KAAK,OAAO,MAAM;GACzC;GACA,MAAM,MAAO,KAAK,MAAM,GAAM,CAAE;EAClC,CAAC,GACD,EAAK,OAAO,GAAO,KAAK,OAAO,EAAE,GACjC,EAAK,iBAAiB,oBAAoB,KAAK,QAAQ,OAAO,CAAK,CAAC,GACpE,4BAA4B,KAAK,QAAQ,OAAO,CAAK,CAAC,GAC/C;CACT;CAEA,UAAmB;EAMjB,AALA,KAAK,WAAW,QAAQ,GACxB,KAAK,YAAY,MACjB,KAAK,QAAQ,QAAQ,GACrB,KAAK,SAAS,MACd,KAAK,QAAQ,MACb,KAAK,UAAU;CACjB;AACF,GCtbM,qBAAY,IAAI,IAAI;CAAC;CAAK;CAAK;AAAG,CAAC,GAE5B,KAA+B,GAAY,kBAAkB,IAAI,MAAO;CAGnF,IAFI,CAAC,EAAG,cAAc,EAAG,YAAY,MAAM,KAAK,EAAG,YAAY,MAAM,KACjE,EAAG,WAAW,CAAe,KAC7B,CAAC,EAAG,WAAW,UAAU,KAAK,OAAO,OAAO;CAGhD,IAAM,IAAY,EAAG,WAAW,UAAU,KAAK,MAC3C,IAAW,IACX,IAAc;CAKlB,IAJA,EAAG,QAAQ,aAAa,GAAO,GAAK,GAAQ,GAAM,MAAQ;EAExD,AADA,KAAe,GACX,MAAU,KAAO,MAAU,MAAW,IAAW,EAAI,SAAS;CACpE,CAAC,GACG,MAAgB,KAAK,EAAS,WAAW,GAAG,OAAO;CAEvD,IAAM,IAAM,EAAG,QACT,IAAO,EAAG,aAAa,KAAK,MAC5B,IAAO,EAAI,OAAO,CAAI;CAC5B,IAAI,MAAS,EAAK,IAAI,OAAO;CAC7B,IAAM,IAAO,EAAK,MAEd,IAAuE;CAE3E,IAAI,MAAa,OAAO,YAAY,KAAK,CAAI,GAC3C,IAAO;EAAE,SAAS;GAAE,MAAM,EAAK;GAAM,IAAI,EAAK;GAAI,QAAQ;EAAS;EAAG,QAAQ,EAAK,OAAO;CAAE;MACvF,IAAI,MAAa,OAAO,MAAS,OACtC,IAAO;EAAE,SAAS;GAAE,MAAM;GAAM,QAAQ;EAAU;EAAG,QAAQ,IAAO;CAAE;MACjE,IAAI,MAAa,OAAO,MAAS,MACtC,IAAO;EAAE,SAAS;GAAE,MAAM;GAAM,QAAQ;EAAS;EAAG,QAAQ,IAAO;CAAE;MAChE,IAAI,GAAU,IAAI,CAAQ,KAAS,OAAO,MAAM,EAAS,MAAM,CAAC,CAAC,KAAK,CAAI,GAAG;EAClF,IAAM,IAAY,EAAK,WAAW,KAAK,EAAI,KAAK,EAAK,SAAS,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,IAG3E,IAAW,MAAa,OAAO,CAAC,GAChC,IAAS,EAAK,WAAW,EAAI;EACnC,IAAI,KAAY,GAAQ;GACtB,IAAM,IAA8C,CAAC;GAGrD,AAFI,KAAU,EAAQ,KAAK;IAAE,MAAM,EAAK;IAAM,QAAQ;GAAK,CAAC,GACxD,KAAQ,EAAQ,KAAK;IAAE,MAAM,EAAK;IAAI,QAAQ;GAAK,CAAC,GACxD,IAAO;IAAE;IAAS,QAAQ,EAAK,KAAM,OAAqB;GAAgB;EAC5E;CACF;CAGA,OADK,IACE,CACL,GACA;EACE,SAAS,EAAK;EACd,WAAW,EAAE,QAAQ,EAAK,OAAO;EACjC,YAAY;EACZ,gBAAgB;EAChB,WAAW;CACb,CACF,IAVkB;AAWpB,CAAC,GC1DK,qBAAa,IAAI,IAAI;CAAC;CAAgB;CAAY;AAAmB,CAAC;AAG5E,SAAS,GAAU,GAAY,GAAa,GAAqB;CAC/D,IAAI,IAAI;CACR,SAAS;EACP,IAAM,IAAO,EAAK,aAAa,GAAG,CAAG;EACrC,IAAI,CAAC,GAAW,IAAI,EAAK,IAAI,KAAK,EAAK,QAAQ,EAAK,IAAI,OAAO;EAC/D,IAAM,IAAO,IAAM,IAAI,EAAK,OAAO,EAAK;EACxC,IAAI,MAAS,GAAG,OAAO;EACvB,IAAI;CACN;AACF;AAQA,SAAS,GAAc,GAAoB,GAAqB;CAC9D,IAAM,IAAI,EAAO,GAAO,GAAK,EAAI;CACjC,IAAI,CAAC,GAAG,OAAO;CACf,IAAM,IAAO,EAAW,CAAK;CAG7B,OAFI,MAAQ,EAAE,YAAkB,GAAU,GAAM,GAAK,CAAC,IAClD,MAAQ,EAAE,cAAoB,GAAU,GAAM,GAAK,EAAE,IAClD;AACT;AAEA,IAAa,KAAsC,GAAY,kBAAkB,IAAI,MAAO;CAG1F,IAFI,CAAC,EAAG,cACJ,EAAG,YAAY,MAAM,KAAK,EAAG,YAAY,MAAM,KAC/C,EAAG,WAAW,CAAe,GAAG,OAAO;CAC3C,IAAM,IAAQ,EAAG,YACX,IAAM,EAAM,UAAU;CAE5B,IADI,CAAC,EAAI,SACL,CAAC,EAAc,GAAO,EAAM,IAAI,OAAO,EAAI,IAAI,CAAC,CAAC,MAAM,GAAG,OAAO;CAGrE,IAAM,IAAoB,CAAC,GACvB,IAAQ;CACZ,EAAG,QAAQ,aAAa,GAAO,GAAK,GAAQ,GAAM,MAAa;EAE7D,AADA,KACI,MAAU,KAAO,MAAU,EAAI,QAAQ,EAAS,SAAS,KAC3D,EAAQ,KAAK,EAAS,SAAS,CAAC;CAEpC,CAAC;CACD,IAAM,IAAS,EAAQ;CACvB,IAAI,MAAU,KAAK,MAAW,KAAA,GAAW,OAAO;CAEhD,IAAM,IAAS,GAAc,GAAO,EAAI,IAAI;CAG5C,OAFI,MAAW,EAAI,OAAa,IAEzB;EACL,SAAS;GAAE,MAAM;GAAQ;EAAO;EAChC,WAAW,EAAE,QAAQ,IAAS,EAAO,OAAO;EAC5C,gBAAgB;EAChB,WAAW;CACb;AACF,CAAC;;;ACnDD,SAAS,GAAa,GAAiC;CACrD,IAAM,IAAU,WAAW,KAAK,CAAI;CACpC,IAAI,GAAS,OAAO;EAAE,WAAW,EAAQ,EAAE,CAAC;EAAQ,MAAM,CAAC,GAAG,EAAQ,EAAE,CAAC,MAAM;CAAE;CAEjF,IAAM,IAAQ,YAAY,KAAK,CAAI;CACnC,IAAI,GAAO;EACT,IAAM,IAAM,OAAO,KAAK,CAAI,CAAC,CAAE,EAAE,CAAC;EAClC,OAAO;GAAE,WAAW,EAAM,EAAE,CAAC;GAAQ,MAAM,CAAC,GAAG,CAAG;EAAE;CACtD;CAEA,IAAM,IAAO,yBAAyB,KAAK,CAAI;CAC/C,IAAI,GAAM,OAAO;EAAE,WAAW,EAAK,EAAE,CAAC;EAAQ,MAAM,CAAC,GAAG,EAAK,EAAE,CAAC,MAAM;CAAE;CAExE,IAAM,IAAO,0BAA0B,KAAK,CAAI;CAChD,IAAI,GAAM;EACR,IAAM,IAAS,EAAK;EACpB,IAAI,GAAQ;GACV,IAAM,IAAO,EAAO,WAAW,GAAI,IAAI,IAAI,KAAK,IAAI,GAAG,EAAO,MAAM;GACpE,OAAO;IAAE,WAAW,EAAK,EAAE,CAAC;IAAQ,MAAM,CAAC,GAAG,CAAI;GAAE;EACtD;EACA,OAAO;GAAE,WAAW,EAAK,EAAE,CAAE;GAAQ,MAAM,CAAC,GAAG,EAAK,EAAE,CAAE,MAAM;EAAE;CAClE;CACA,OAAO;AACT;AA6BA,IAAa,KAAmC,EAAK,KACnD,GAAO,GAAG,CAAC;CAAE,KAAK;CAAa,MA3BS,MAA8B;EACtE,IAAI,EAAgB,CAAI,GAAG,OAAO;EAClC,IAAM,EAAE,aAAU,GACZ,IAAM,EAAM,UAAU;EAC5B,IAAI,CAAC,EAAI,OAAO,OAAO;EAEvB,IAAM,IAAO,EAAM,IAAI,OAAO,EAAI,IAAI;EACtC,IAAI,CAAC,EAAc,GAAO,EAAK,MAAM,GAAG,OAAO;EAE/C,IAAM,IAAO,GAAa,EAAK,IAAI;EAKnC,IAJI,CAAC,KAID,EAAI,OAAO,EAAK,QAAQ,EAAI,OAAO,EAAK,OAAO,EAAK,WAAW,OAAO;EAE1E,IAAM,CAAC,GAAI,KAAM,EAAK;EAOtB,OANA,EAAK,SAAS;GACZ,SAAS;IAAE,MAAM,EAAK,OAAO;IAAI,IAAI,EAAK,OAAO;IAAI,QAAQ;GAAG;GAChE,WAAW,EAAE,QAAQ,EAAK,OAAO,EAAG;GACpC,WAAW;GACX,gBAAgB;EAClB,CAAC,GACM;CACT;AAGuD,CAAC,CAAC,CACzD,GCjEM,KAAN,MAA6C;CAC3C;CACA;CACA;CAEA,YAAY,GAAkB;EAqB5B,AApBA,KAAK,OAAO,EAAkB,EAAK,IAAI,aAAa,GACpD,EAAK,IAAI,YAAY,KAAK,KAAK,EAAE,GACjC,KAAK,aAAa,EAAK,YAEvB,KAAK,WAAW,MAAkB;GAEhC,IADI,EAAK,MAAM,MAAM,CAAe,MAAM,WACtC,CAAC,EAAK,MAAM,MAAM,CAAkB,CAAC,CAAC,OAAO;GAEjD,IAAM,IADS,EAAE,QACE,QAAQ,kBAAkB;GAC7C,IAAI,CAAC,KAAM,EAAG,UAAU,SAAS,qBAAqB,GAAG;GAEzD,IAAI,IAAM,EAAK,SAAS,CAAiB;GACzC,IAAI,IAAM,GAAG;IACX,IAAM,IAAK,EAAK,YAAY;KAAE,GAAG,EAAE;KAAS,GAAG,EAAE;IAAQ,CAAC;IAC1D,IAAI,KAAM,MAAM;IAChB,IAAM;GACR;GAEA,AADA,EAAK,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAI,EAAE,CAAC,GAC5C,KAAK,KAAK,UAAU,EAAQ,CAAI,GAAG,EAAE,SAAS,EAAE,OAAO;EACzD,GACA,KAAK,WAAW,iBAAiB,SAAS,KAAK,OAAO;CACxD;CAEA,UAAU;EAER,AADA,KAAK,WAAW,oBAAoB,SAAS,KAAK,OAAO,GACzD,KAAK,KAAK,QAAQ;CACpB;AACF,GAEa,KAAkB,EAAW,UAAU,EAAe,GCzC7D,MAAe,MAAsB,EAAE,QAAQ,cAAc,IAAI,CAAC,CAAC,KAAK,GAExE,MAAU,GAAc,GAAY,MACnC,IACE;CACL,KAAK;CACL,KAAK;CACL,OAAO;CACP,SAAS;EACP,IAAM,IAAM,SAAS,cAAc,KAAK;EAGxC,OAFA,EAAI,YAAY,uBAChB,EAAI,cAAc,GACX,EAAE,OAAI;CACf;AACF,IAXkB;AAepB,SAAS,GAAW,GAAkB,GAA6B;CACjE,KACE,IAAI,IAA0B,EAAW,EAAK,KAAK,CAAC,CAAC,aAAa,GAAK,EAAE,GACzE,GACA,IAAO,EAAK,QACZ;EACA,IAAI,EAAK,SAAS,QAAQ;EAC1B,IAAI,EAAK,MAAM,IAAI,YAAY,KAAK,IAAI,GAAG,EAAK,OAAO,CAAC,GAAG,EAAK,IAAI,MAAM,KAAK;EAC/E,IAAM,IAAM,EAAK,SAAS,KAAK,GACzB,IAAO,IACT,EAAK,MAAM,SAAS,EAAI,MAAM,EAAI,EAAE,IACpC,EAAK,MAAM,SAAS,EAAK,MAAM,EAAK,EAAE;EAC1C,OAAO,GAAO,EAAK,MAAM,EAAK,IAAI,GAAY,CAAI,CAAC;CACrD;CACA,OAAO;AACT;AAGA,SAAS,GAAa,GAAkB,GAA6B;CACnE,IAAM,IAAO,EAAK,MAAM,IAAI,OAAO,CAAG;CACtC,KAAK,IAAM,KAAK,EAAK,KAAK,SAAS,CAAgB,GAAG;EACpD,IAAM,IAAO,EAAK,QAAQ,EAAE,SAAS,IAC/B,IAAK,IAAO,EAAE,EAAE,CAAC;EACnB,UAAM,KAAQ,IAAM,IACxB,OAAO,GAAO,GAAM,IAAK,EAAE,MAAM,GAAA,CAAI,KAAK,CAAC;CAC7C;CACA,OAAO;AACT;AAEA,IAAa,KAAmB,IAAc,GAAM,MAAwB;CAC1E,IAAM,IAAU,EAAK,MAAM,MAAM,CAAkB;CACnD,QACG,EAAQ,QAAQ,GAAW,GAAM,CAAG,IAAI,UACxC,EAAQ,YAAY,GAAa,GAAM,CAAG,IAAI;AAEnD,CAAC,GCpDK,KAAN,MAAmD;CACjD;CACA;CACA;CACA;CACA;CACA;CAGA,UAA2D;CAI3D,cAAsB;CAEtB,YAAY,GAAkB;EAsC5B,AArCA,KAAK,OAAO,GACZ,KAAK,OAAO,EAAkB,EAAK,IAAI,aAAa,GAIpD,EAAK,IAAI,YAAY,KAAK,KAAK,EAAE,GAEjC,KAAK,aAAa,EAAK,YACvB,KAAK,sBAAsB;GACzB,IAAM,IAAI,EAAK,MAAM,UAAU;GAC/B,KAAK,UAAU,EAAE,QAAQ,OAAO;IAAE,QAAQ,EAAE;IAAQ,MAAM,EAAE;GAAK;EACnE,GACA,KAAK,WAAW,iBAAiB,eAAe,KAAK,eAAe,EAAI,GAExE,KAAK,iBAAiB,MAAkB;GACtC,IAAM,IAAS,EAAE;GACZ,EAAK,MAAM,MAAM,CAAkB,MAMpC,GAAQ,QAAQ,wBAAwB,MAM5C,EAAE,eAAe,GAGjB,KAAK,UAAU,OAAO,GAClB,OAAK,IAAI,IAAI,KAAK,cAAc,QACpC,KAAK,WAAW,EAAE,SAAS,EAAE,SAAS,CAAM;EAC9C,GACA,KAAK,WAAW,iBAAiB,eAAe,KAAK,aAAa,GAElE,KAAK,YAAY,GAAgB,KAAK,YAAY,EAChD,cAAc,GAAG,GAAG,MAAM;GAExB,AADA,KAAK,cAAc,KAAK,IAAI,GAC5B,KAAK,WAAW,GAAG,GAAG,CAAuB;EAC/C,EACF,CAAC;CACH;CAIA,WAAmB,GAAiB,GAAiB,GAA4B;EAC/E,IAAM,IAAO,KAAK;EACb,MAAK,MAAM,MAAM,CAAkB,KACpC,IAAQ,QAAQ,wBAAwB,GAK5C;OAAI,KAAK,WAAW,EAAK,MAAM,UAAU,KAAK,OAC5C,EAAK,SAAS,EAAE,WAAW,KAAK,QAAQ,CAAC;QACpC,IAAI,EAAK,MAAM,UAAU,KAAK,OAAO;IAS1C,IAAM,IAAM,EAAK,YAAY;KAAE,GAAG;KAAS,GAAG;IAAQ,CAAC;IACvD,IAAI,KAAO,MAAM;KACf,IAAM,IAAO,EAAO,EAAK,OAAO,GAAK,IAAO,EAAI,GAC5C,IAAO,EAAK,MAAM,OAAO,CAAG,KAAK,EAAE,QAAQ,EAAI;KAInD,AAHI,GAAM,SAAS,SAAQ,IAAO;MAAE,QAAQ,EAAK;MAAM,MAAM,EAAK;KAAG,IAC5D,KAAQ,EAAK,YAAY,EAAK,gBACrC,IAAO;MAAE,QAAQ,EAAK;MAAa,MAAM,EAAK;KAAU,IAC1D,EAAK,SAAS,EAAE,WAAW,EAAK,CAAC;IACnC;GACF;GAEA,KAAK,KAAK,KAAK,GAAS,CAAI,GAAG,GAAS,CAAO;EAF/C;CAGF;CAEA,UAAU;EAIR,AAHA,KAAK,WAAW,oBAAoB,eAAe,KAAK,eAAe,EAAI,GAC3E,KAAK,WAAW,oBAAoB,eAAe,KAAK,aAAa,GACrE,KAAK,UAAU,QAAQ,GACvB,KAAK,KAAK,QAAQ;CACpB;AACF,GAEa,KAAmB,EAAW,UAAU,EAAqB,GCzFpE,KAAN,MAA0C;CAepB;CAdpB;CACA;CACA,0BAAkB,IAAI,IAAyC;CAC/D;CAGA,iBAAyB;EACvB,KAAK,IAAI,SAAS;CACpB;CAEA,0BAAkC;EAChC,AAAI,EAAgB,KAAK,IAAI,KAAG,KAAK,SAAS;CAChD;CAEA,YAAY,GAA0B;EAAlB,KAAA,OAAA;EAClB,IAAM,IAAM,EAAK,IAAI;EAOrB,AANA,KAAK,MAAM,EAAK,MAAM,MAAM,EAAsB,GAClD,KAAK,WAAW,EAAkB,CAAG,GACrC,EAAK,IAAI,YAAY,KAAK,SAAS,EAAE,GACrC,KAAK,MAAM,EAAI,cAAc,KAAK,GAClC,KAAK,IAAI,YAAY,qBACrB,KAAK,IAAI,aAAa,mBAAmB,OAAO,GAChD,KAAK,IAAI,SAAS;EAClB,KAAK,IAAM,KAAM,KAAK,KAAK;GACzB,IAAM,IAAM,EAAc,IACpB,IAAI,EAAI,cAAc,QAAQ;GA6BpC,AA5BA,EAAE,OAAO,UACT,EAAE,YAAY,yBACd,EAAE,QAAQ,EAAI,OACd,EAAE,aAAa,cAAc,EAAI,KAAK,GACtC,EAAE,YAAY,GAAQ,GAAK,EAAW,MAAO,EAAE,CAAC,GAChD,EAAE,iBAAiB,cAAc,MAAM,EAAE,eAAe,CAAC,GACzD,EAAE,iBAAiB,UAAU,MAAM;IACjC,EAAE,eAAe;IACjB,IAAM,IAAS,EAAQ,EAAgB,CAAI,GAIrC,IACJ,CAAC,KAAU,MAAO,SACd,EAAQ,CAAI,IACZ,CAAC,KAAU,MAAO,aAChB,GAAY,CAAI,IAChB;IACR,IAAI,GAAO;KACT,IAAM,IAAI,EAAE,sBAAsB;KAClC,KAAK,SAAS,UAAU,GAAO,EAAE,MAAM,EAAE,SAAS,CAAC;KACnD;IACF;IAGA,AAFA,EAAI,IAAI,CAAI,GACP,KAAQ,EAAK,MAAM,GACxB,KAAK,SAAS;GAChB,CAAC,GACD,KAAK,QAAQ,IAAI,GAAI,CAAC,GACtB,KAAK,IAAI,YAAY,CAAC;EACxB;EAOA,AAJA,EAAK,IAAI,YAAY,KAAK,GAAG,GAG7B,EAAI,iBAAiB,UAAU,KAAK,UAAU,EAAI,GAClD,EAAI,iBAAiB,mBAAmB,KAAK,iBAAiB;CAChE;CAEA,OAAO,GAAe;EAGpB,CAAI,EAAE,gBAAgB,EAAE,cAAc,EAAE,iBAAc,KAAK,SAAS;CACtE;CAOA,WAAmB;EACjB,KAAK,KAAK,eAAe;GACvB,KAAK;GACL,YAAY,KAAK,QAAQ;GACzB,QAAQ,MAAM,KAAK,MAAM,CAAC;EAC5B,CAAC;CACH;CAGA,eAA6D;EAC3D,IAAM,EAAE,YAAS,MACX,IAAM,EAAK,MAAM,UAAU;EACjC,IAAI,CAAC,EAAI,OAAO;GACd,IAAM,IAAO,EAAK,YAAY,EAAI,IAAI,GAChC,IAAK,EAAK,YAAY,EAAI,EAAE;GAElC,OADI,CAAC,KAAQ,CAAC,IAAW,OAClB;IACL,QAAQ;IACR,KAAK;KACH,MAAM,KAAK,IAAI,EAAK,MAAM,EAAG,IAAI;KACjC,OAAO,KAAK,IAAI,EAAK,OAAO,EAAG,KAAK;KACpC,KAAK,KAAK,IAAI,EAAK,KAAK,EAAG,GAAG;KAC9B,QAAQ,KAAK,IAAI,EAAK,QAAQ,EAAG,MAAM;IACzC;GACF;EACF;EACA,IAAI,CAAC,EAAiB,CAAI,GAAG,OAAO;EACpC,IAAM,IAAM,EAAK,IAAI,cAAc,aAAa;EAChD,IAAI,CAAC,KAAO,EAAI,eAAe,GAAG,OAAO;EACzC,IAAM,IAAI,EAAI,WAAW,CAAC,CAAC,CAAC,sBAAsB;EAClD,OAAO;GAAE,QAAQ;GAAM,KAAK;IAAE,MAAM,EAAE;IAAM,OAAO,EAAE;IAAO,KAAK,EAAE;IAAK,QAAQ,EAAE;GAAO;EAAE;CAC7F;CAEA,UAA6B;EAC3B,IAAM,EAAE,YAAS;EACjB,IAAI,EAAK,MAAM,MAAM,CAAgB,MAAM,OAAO,OAAO;EACzD,IAAM,IAAQ,KAAK,aAAa;EAChC,IAAI,CAAC,GAAO,OAAO;EACnB,IAAM,EAAE,QAAK,cAAW;EAGxB,IAAI,CAAC,KAAU,CAAC,EAAK,UAAU,OAAO;EAEtC,IAAM,IAAU,KAAK,IAAI,sBAAsB,GACzC,IAAK,EAAK,IAAI,cAAc,aAAa,cAAc,GACvD,KAAQ,EAAI,OAAO,EAAI,SAAS,GAChC,IAAY,EAAK,IAAI,sBAAsB,CAAC,CAAC,KAC7C,IAAW,EAAI,MAAM,EAAQ,SAAS,GACtC,IAAW,EAAI,SAAS,GAExB,IAAoC,CAAC,GACrC,IAAkC,CAAC;EACzC,KAAK,IAAM,KAAM,KAAK,KAAK;GACzB,IAAM,IAAM,EAAc,IAGpB,IAAM,MAAiB,EAAQ,EAAI,WAAW,EAAK,KAAK;GAE9D,AADA,EAAS,KAAM,GACf,EAAO,KAAM,CAAC,KAAO,CAAC,KAAU,EAAQ,EAAI,WAAW,EAAK,KAAK;EACnE;EAIA,OADI,KAAK,IAAI,OAAO,MAAO,EAAS,EAAG,IAAU,OAC1C;GACL,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,IAAO,EAAQ,QAAQ,GAAG,IAAK,EAAQ,QAAQ,CAAC,CAAC;GAC5E,KAAK,IAAW,IAAY,IAAI,IAAW;GAC3C;GACA;EACF;CACF;CAEA,MAAc,GAAc;EAC1B,IAAI,CAAC,GAAG;GACN,KAAK,IAAI,SAAS;GAClB;EACF;EAGA,AAFA,KAAK,IAAI,SAAS,IAClB,KAAK,IAAI,MAAM,OAAO,GAAG,EAAE,KAAK,KAChC,KAAK,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI;EAC9B,KAAK,IAAM,CAAC,GAAI,MAAM,KAAK,SAEzB,AADA,EAAE,WAAW,EAAE,SAAS,IACxB,EAAE,gBAAgB,eAAe,EAAE,OAAO,EAAI;CAElD;CAEA,UAAU;EACR,IAAM,IAAM,KAAK,KAAK,IAAI;EAI1B,AAHA,EAAI,oBAAoB,UAAU,KAAK,UAAU,EAAI,GACrD,EAAI,oBAAoB,mBAAmB,KAAK,iBAAiB,GACjE,KAAK,SAAS,QAAQ,GACtB,KAAK,IAAI,OAAO;CAClB;AACF,GASa,KAAe,EAAW,UAAU,EAAY,GC9LvD,KAAN,cAA0B,EAAW;CACd;CAArB,YAAY,GAA6B;EAApB,AACnB,MAAM,GADa,KAAA,QAAA;CAErB;CAEA,GAAY,GAAoB;EAC9B,OAAO,KAAK,UAAU,KAAK,KAAK,MAAM,KAAK,UAAU,EAAM,KAAK;CAClE;CAEA,QAAQ;EACN,IAAM,EAAE,SAAM,SAAM,cAAW,KAAK,OAC9B,IAAK,SAAS,cAAc,OAAO;EACzC,EAAG,YAAY;EAGf,IAAM,KAAQ,MAAgB,GAAa,EAAI,QAAQ,SAAS,GAAG,CAAC,GAE9D,IAAK,EAAG,YAAY,CAAC,CAAC,UAAU;EACtC,EAAK,SAAS,GAAM,MAAM;GACxB,IAAM,IAAK,SAAS,cAAc,IAAI;GAKtC,AAJA,EAAG,YAAY,EAAK,CAAI,CAAC,GACzB,EAAG,QAAQ,WAAW,KACtB,EAAG,QAAQ,WAAW,OAAO,CAAC,GAC9B,GAAM,GAAI,EAAO,EAAE,GACnB,EAAG,YAAY,CAAE;EACnB,CAAC;EAED,IAAM,IAAQ,EAAG,YAAY;EAW7B,OAVA,EAAK,SAAS,GAAK,MAAM;GACvB,IAAM,IAAK,EAAM,UAAU;GAC3B,KAAK,IAAI,IAAI,GAAG,IAAI,EAAK,QAAQ,KAAK;IACpC,IAAM,IAAK,EAAG,WAAW;IAIzB,AAHA,EAAG,YAAY,EAAK,EAAI,MAAM,EAAE,CAAC,GACjC,EAAG,QAAQ,WAAW,OAAO,IAAI,CAAC,GAClC,EAAG,QAAQ,WAAW,OAAO,CAAC,GAC9B,GAAM,GAAI,EAAO,EAAE;GACrB;EACF,CAAC,GACM;CACT;CAEA,cAAuB;EACrB,OAAO;CACT;AACF;AAEA,SAAS,GAAM,GAA4B,GAA0B;CACnE,AAAI,MAAO,EAAK,MAAM,YAAY;AACpC;AAQA,SAAS,GAAW,GAAkB,GAA+B;CACnE,IAAM,IAAQ,EAAI,OAAO,EAAK,IAAI,CAAC,CAAC,QAC9B,IAAO,EAAI,OAAO,EAAK,EAAE,CAAC,CAAC,QAC3B,IAAkB,CAAC;CACzB,KAAK,IAAI,IAAI,GAAO,KAAK,GAAM,KAAK,EAAM,KAAK,EAAI,KAAK,CAAC,CAAC,CAAC,IAAI;CAE/D,IAAM,IAAO,EAAU,CAAK;CAE5B,OADI,CAAC,KAAQ,EAAK,KAAK,WAAW,IAAU,OACrC;EAAE,MAAM,EAAK,KAAK;EAAK,MAAM,EAAK,KAAK,MAAM,CAAC;EAAG,QAAQ,EAAK;CAAO;AAC9E;AAEA,SAAS,GAAM,GAAmC;CAChD,IAAI,CAAC,EAAM,MAAM,CAAkB,CAAC,CAAC,QAAQ,OAAO,EAAW;CAC/D,IAAM,IAAW,EAAM,MAAM,CAAiB,MAAM,SAC9C,IAAO,EAAW,CAAK,GACvB,IAAK,EAAiB,EAAM,GAAG,GAC/B,IAAW,IAAW,OAAO,EAAc,CAAK,GAChD,IAA2B,CAAC;CA0BlC,OAxBA,EAAK,QAAQ,EACX,QAAQ,MAAS;EACf,IAAI,EAAK,SAAS,SAAS;EAC3B,IAAI,KAAM,EAAK,OAAO,EAAG,IAAI,OAAO;EAIpC,IAAI,GAAU;GACZ,IAAM,IAAQ,EAAM,IAAI,OAAO,EAAK,IAAI,CAAC,CAAC,QACpC,IAAO,EAAM,IAAI,OAAO,EAAK,EAAE,CAAC,CAAC;GACvC,KAAK,IAAI,IAAI,GAAO,KAAK,GAAM,KAC7B,IAAI,EAAS,IAAI,CAAC,GAAG,OAAO;EAEhC;EAEA,IAAM,IAAS,GAAW,EAAK,MAAM,EAAM,GAAG;EAC9C,IAAI,GAAQ;GACV,IAAM,IAAS,IAAW,IAAI,GAAoB,CAAM,IAAI,IAAI,GAAY,CAAM;GAClF,EAAI,KAAK,EAAW,QAAQ;IAAE;IAAQ,OAAO;GAAK,CAAC,CAAC,CAAC,MAAM,EAAK,MAAM,EAAK,EAAE,CAAC;EAChF;EACA,OAAO;CACT,EACF,CAAC,GAEM,EAAW,IAAI,GAAK,EAAI;AACjC;AAMA,IAAa,KAAa,EAAW,OAAsB;CACzD,QAAQ;CACR,SAAS,GAAO,MAMV,EAAG,WAAW,CAAe,IAAU,EAAM,IAAI,EAAG,OAAO,IAM3D,EAAG,MAAM,MAAM,CAAiB,MAAM,UACjC,EAAG,aAAa,GAAM,EAAG,KAAK,IAAI,EAAM,IAAI,EAAG,OAAO,IAExD,EAAG,cAAc,EAAG,YAAY,GAAM,EAAG,KAAK,IAAI;CAE3D,UAAU,MAAU,CAClB,EAAW,YAAY,KAAK,CAAK,GACjC,EAAW,aAAa,IAAI,MAAS,EAAK,MAAM,MAAM,CAAK,CAAC,CAC9D;AACF,CAAC,GC5HK,MACH,OACA,MAA8B;CAC7B,IAAI,EAAgB,CAAI,GAAG,OAAO;CAClC,IAAM,IAAM,EAAK,MAAM,UAAU;CACjC,IAAI,CAAC,EAAI,OAAO,OAAO;CACvB,IAAM,EAAE,WAAQ,EAAK,OACf,IAAO,EAAI,OAAO,EAAI,IAAI,GAC1B,IAAa,IAAU,EAAK,SAAS,IAAI,EAAK,SAAS;CAC7D,IAAI,IAAa,KAAK,IAAa,EAAI,OAAO,OAAO;CACrD,IAAM,IAAO,EAAI,KAAK,CAAU,GAE5B,IAAO,IACP,IAAK,IACL;CAWJ,IAVA,EAAK,MAAM,MAAM,EAAU,CAAC,CAAC,QAAQ,EAAK,MAAM,EAAK,KAAK,GAAG,GAAG,MAAS;EAGvE,IAAI,IAAU,MAAM,EAAK,OAAO,MAAM,EAAK,IAIzC,OAHA,IAAO,GACP,IAAK,GACL,IAAS,EAAK,KAAK,QACZ;CAEX,CAAC,GACG,IAAO,GAAG,OAAO;CAErB,IAAI,EAAK,MAAM,MAAM,CAAiB,MAAM,SAC1C,OAAO,aAAkB,MAAuB,EAAO,UAAU,IAAU,UAAU,MAAM;CAK7F,IAAM,IAAS,IAAU,EAAI,OAAO,CAAI,CAAC,CAAC,OAAO,EAAI,OAAO,CAAE,CAAC,CAAC;CAEhE,OADA,EAAK,SAAS;EAAE,WAAW,EAAE,UAAO;EAAG,WAAW;EAAU,gBAAgB;CAAK,CAAC,GAC3E;AACT,GAGW,KAA+B,GAAe,EAAI,GAElD,KAA+B,GAAe,EAAK,GAEnD,KAA+B,EAAK,KAC/C,GAAO,GAAG,CACR;CAAE,KAAK;CAAa,KAAK;AAAoB,GAC7C;CAAE,KAAK;CAAW,KAAK;AAAoB,CAC7C,CAAC,CACH,GCpEM,IAAO,4DAcA,KAAe,EAAW,MAAM;CAS3C,iBAAiB;EACf,YACE;EACF,YAAY;EACZ,SAAS;EAIT,oBAAoB;CACtB;CACA,cAAc;EAAE,aAAa;EAAK,cAAc;CAAI;CAEpD,uBAAuB,EAAE,YAAY,MAAM;CAC3C,kBAAkB;EAAE,UAAU;EAAU,YAAY;EAAa,YAAY;CAAS;CACtF,kBAAkB;EAAE,UAAU;EAAS,YAAY;EAAa,YAAY;CAAQ;CACpF,kBAAkB;EAAE,UAAU;EAAU,YAAY;EAAO,YAAY;CAAQ;CAC/E,kBAAkB;EAAE,UAAU;EAAO,YAAY;EAAO,YAAY;CAAQ;CAC5E,kBAAkB,EAAE,UAAU,QAAQ;CACtC,kBAAkB;EAAE,UAAU;EAAS,OAAO;CAA0B;CAExE,sBAAsB,EAAE,YAAY,MAAM;CAC1C,kBAAkB,EAAE,WAAW,SAAS;CACxC,sBAAsB,EAAE,gBAAgB,eAAe;CACvD,oBAAoB;EAClB,YAAY;EACZ,UAAU;EACV,SAAS;EACT,cAAc;EACd,YAAY;CACd;CAOA,oBAAoB;EAClB,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,SAAS;CACX;CAMA,wBAAwB;EACtB,YAAY;EACZ,qBAAqB;EACrB,sBAAsB;CACxB;CACA,2BAA2B;EACzB,eAAe;EACf,wBAAwB;EACxB,yBAAyB;CAC3B;CACA,qBAAqB,EAAE,OAAO,0BAA0B;CAExD,wBAAwB;EAAE,UAAU;EAAK,YAAY;CAAI;CAGzD,oBAAoB;EAClB,OAAO;EACP,gBAAgB;EAChB,QAAQ;CACV;CACA,wBAAwB,EAAE,OAAO,oBAAoB;CAErD,0BAA0B;EACxB,SAAS;EACT,SAAS;EACT,WAAW;CACb;CACA,yCAAyC,EAAE,QAAQ,IAAI;CAKvD,uBAAuB;EAAE,UAAU;EAAK,YAAY;CAAI;CAGxD,2BAA2B;EAAE,UAAU;EAAK,YAAY;CAAI;CAC5D,kBAAkB;EAChB,SAAS;EAKT,QAAQ;EACR,QAAQ;EACR,QAAQ;EAER,YACE;CACJ;CACA,qBAAqB;EACnB,YAAY;EAEZ,aAAa;EACb,OAAO;CACT;CAKA,uBAAuB;EACrB,YAAY;EACZ,SAAS;EACT,YACE;EACF,OAAO;CACT;CAKA,4BAA4B;EAC1B,YAAY;EACZ,sBAAsB;CACxB;CACA,4BAA4B;EAC1B,eAAe;EACf,yBAAyB;CAC3B;CACA,4BAA4B,EAAE,0BAA0B,qCAAqC;CAC7F,2BAA2B,EAAE,0BAA0B,oCAAoC;CAC3F,4BAA4B,EAAE,0BAA0B,qCAAqC;CAC7F,8BAA8B,EAC5B,0BAA0B,uCAC5B;CACA,+BAA+B,EAC7B,0BAA0B,wCAC5B;CACA,oCAAoC;EAClC,SAAS;EACT,SAAS;EACT,cAAc;EACd,UAAU;EACV,YAAY;EACZ,eAAe;EACf,eAAe;EACf,OAAO;CACT;CAEA,mDAAmD;EAAE,SAAS;EAAM,SAAS;CAAO;CAEpF,sBAAsB,EAAE,OAAO,0BAA0B;CAIzD,kBAAkB;EAChB,iBACE;EACF,kBAAkB;EAClB,oBAAoB;EACpB,gBAAgB;CAClB;CACA,wBAAwB;EACtB,QAAQ;EACR,eAAe;EACf,QAAQ;CACV;CACA,kBAAkB;EAChB,YAAY;EACZ,UAAU;EACV,OAAO;CACT;CACA,gCAAgC;EAC9B,SAAS;EACT,aAAa;EACb,YACE;EACF,UAAU;EACV,YAAY;EACZ,eAAe;EACf,eAAe;EACf,OAAO;CACT;CAEA,qBAAqB;EACnB,gBAAgB;EAChB,SAAS;EACT,UAAU;CACZ;CACA,wBAAwB;EACtB,SAAS;EACT,QAAQ;EACR,YAAY;EACZ,YAAY;CACd;CACA,wBAAwB;EACtB,SAAS;EACT,QAAQ;CACV;CAEA,iDAAiD,EAC/C,YAAY,+BACd;CAEA,4CAA4C;EAC1C,UAAU;EACV,QAAQ;EACR,SAAS;CACX;CACA,kDAAkD,EAChD,WAAW,oCACb;CAGA,0BAA0B;EACxB,UAAU;EACV,SAAS;EACT,UAAU;EAMV,SAAS;CACX;CACA,4BAA4B;EAC1B,UAAU;EACV,OAAO;EACP,eAAe;CACjB;CAKA,uBAAuB;EACrB,UAAU;EACV,SAAS;EACT,YAAY;EACZ,gBAAgB;EAChB,eAAe;EACf,SAAS;EACT,MAAM;EACN,QAAQ;EACR,YAAY;EACZ,QAAQ;EACR,SAAS;EACT,YAAY;CACd;CACA,6BAA6B;EAC3B,SAAS;EACT,YAAY;CACd;CACA,yBAAyB,EAAE,OAAO,SAAS;CAC3C,yBAAyB,EAAE,QAAQ,SAAS;CAK5C,uBAAuB;EACrB,OAAO;EACP,QAAQ;EACR,OAAO;EACP,YACE;EAEF,eAAe;CACjB;CACA,iDAAiD,EAAE,OAAO,oBAAoB;CAG9E,wBAAwB,EACtB,uBAAuB,EAAE,SAAS,MAAM,EAC1C;CAMA,oBAAoB;EAClB,UAAU;EACV,OAAO;EACP,QAAQ;EACR,eAAe;CACjB;CACA,0BAA0B;EACxB,UAAU;EACV,UAAU;EACV,SAAS;EACT,SAAS;EACT,eAAe;EACf,eAAe;EACf,YAAY;EACZ,QAAQ;EACR,cAAc;EACd,WAAW;EACX,MAAM;CACR;CACA,wBAAwB;EACtB,QAAQ;EACR,QAAQ;EACR,YAAY;CACd;CACA,yBAAyB;EACvB,KAAK;EACL,SAAS;EACT,YAAY;EACZ,KAAK;EACL,SAAS;EACT,cAAc;EACd,UAAU;EACV,QAAQ;EACR,YAAY;CACd;CACA,6BAA6B;EAC3B,OAAO;EACP,QAAQ;EACR,MAAM;EACN,OAAO;CACT;CACA,8CAA8C,EAC5C,YAAY,2DACd;CACA,kCAAkC;EAAE,SAAS;EAAO,QAAQ;CAAU;CAItE,sCAAsC;EAAE,OAAO;EAAuB,YAAY;CAAM;CACxF,0CAA0C,EAAE,OAAO,sBAAsB;CACzE,kCAAkC;EAChC,SAAS;EACT,YAAY;EACZ,aAAa;CACf;CACA,0BAA0B;EACxB,SAAS;EACT,WAAW;EACX,OAAO;EACP,UAAU;EACV,QAAQ;EACR,SAAS;EACT,QAAQ;EACR,cAAc;EACd,UAAU;EACV,YAAY;EACZ,YAAY;EACZ,OAAO;EACP,YAAY;EACZ,SAAS;CACX;CACA,gCAAgC,EAAE,aAAa,oBAAoB;CAMnE,sBAAsB;EACpB,UAAU;EACV,QAAQ;EACR,SAAS;EACT,KAAK;EACL,SAAS;EACT,YAAY;EACZ,QAAQ;EACR,cAAc;EACd,WAAW;CACb;CACA,8BAA8B;EAAE,YAAY;EAAU,eAAe;CAAO;CAC5E,0BAA0B;EACxB,KAAK;EACL,SAAS;EACT,SAAS;EACT,cAAc;EACd,QAAQ;EACR,OAAO;CACT;CACA,8BAA8B;EAAE,OAAO;EAAU,QAAQ;EAAU,SAAS;CAAQ;CACpF,gCAAgC;EAC9B,YAAY;EACZ,OAAO;CACT;CACA,uCAAuC;EACrC,OAAO;EACP,YAAY;CACd;CASA,4BAA4B;EAC1B,0BAA0B;GAAE,UAAU;GAAQ,SAAS;EAAS;EAChE,yBAAyB;GAAE,SAAS;GAAc,UAAU;EAAM;EAClE,6BAA6B;GAAE,OAAO;GAAU,QAAQ;EAAS;EACjE,wBAAwB,EAAE,QAAQ,cAAc;EAChD,0BAA0B;GAAE,SAAS;GAAc,UAAU;EAAM;EACnE,sBAAsB;GAAE,KAAK;GAAU,SAAS;EAAS;EACzD,0BAA0B;GAAE,SAAS;GAAU,UAAU;GAAQ,gBAAgB;EAAS;EAC1F,8BAA8B;GAAE,OAAO;GAAU,QAAQ;EAAS;CACpE;CAGA,0DAA0D;EACxD,QAAQ;EACR,YAAY;CACd;CACA,wBAAwB;EACtB,UAAU;EACV,SAAS;EACT,cAAc;EACd,YAAY;EACZ,QAAQ;EACR,WAAW;EACX,OAAO;EACP,UAAU;EACV,YAAY;EACZ,WAAW;CACb;AACF,CAAC,GC1YK,KAAgB;AAQtB,SAAS,GAAkB,GAAmB,GAAW,GAAmB;CAC1E,IAAM,IAAO,EAAK,YACZ,IAAM,EAAK,aAAa,UAAU;CACxC,IAAI,CAAC,KAAQ,EAAK,aAAa,KAAK,aAAa,MAAQ,GAAG,OAAO;CAEnE,IAAM,IAAM,EAAK,eAGb,IAAoB,MACpB,IAAS;CACb,IAAI,EAAI,wBAAwB;EAC9B,IAAM,IAAI,EAAI,uBAAuB,GAAG,CAAC;EACzC,AAAI,MAAG,CAAC,GAAM,KAAU,CAAC,EAAE,YAAY,EAAE,MAAM;CACjD,OAAO,IAAI,EAAI,qBAAqB;EAClC,IAAM,IAAI,EAAI,oBAAoB,GAAG,CAAC;EACtC,AAAI,MAAG,CAAC,GAAM,KAAU,CAAC,EAAE,gBAAgB,EAAE,WAAW;CAC1D;CAIA,OAFI,MAAS,IAAa,KAAK,IAAI,GAAQ,CAAG,IAC1C,MAAS,KAAa,IAAS,IAAI,IAAM;AAE/C;AAWA,SAAgB,GAAiB,IAAuB,CAAC,GAAc;CACrE,IAAM,IAAO,GAAmB,EAAK,SAAS,WAAW;CACzD,OAAO;EACL,EAAmB,GAAG,GAAe,EAAK,OAAO,CAAC;EAClD,EAAkB,GAAG,EAAK,SAAS,SAAS,QAAQ;EACpD,EAAgB,GAAG,EAAK,SAAS,UAAU,OAAO;EAClD,GAAc,GAAG,EAAK,eAAe,IAAI;EACzC,EAAmB,GAAG,EAAK,OAAO;EAClC,EAAgB,GAAG,EAAK,MAAM;EAC9B,EAAiB,GAAG,EAAK,SAAS,eAAe,MAAM;EACvD,GAAuB,GAAG,GAAyB,EAAK,SAAS,iBAAiB,CAAC;EACnF,GAAmB;EAGnB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,EAAK,KAAK,EAAY;EACtB,EAAW,iBAAiB;GAC1B,UAAU,GAAO,GAAM;IACrB,IAAM,IAAS,EAAM;IAGrB,IAAI,GAAQ,QAAQ,wBAAwB,GAAG,OAAO;IACtD,IAAM,IAAS,GAAQ,QAAqB,EAAa;IACzD,IAAI,CAAC,GAAQ,OAAO;IACpB,IAAI,IAAM,EAAK,SAAS,CAAM;IAC9B,IAAI,IAAM,GAAG,OAAO;IAGpB,IAAM,IAAO,GAAQ,QAAqB,kBAAkB;IAC5D,IAAI,KAAQ,EAAO,SAAS,CAAI,GAAG;KACjC,IAAM,IAAK,GACT,EAAK,MAAM,KACX,GACA,OAAO,EAAK,QAAQ,QAAQ,GAC5B,OAAO,EAAK,QAAQ,QAAQ,CAC9B;KACA,AAAI,KAAM,SAAM,IAAM,IAAK,GAAkB,GAAM,EAAM,SAAS,EAAM,OAAO;IACjF;IAGA,OAFA,EAAK,MAAM,GACX,EAAK,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAI,EAAE,CAAC,GACrC;GACT;GACA,MAAM,GAAO;IACX,IAAI,CAAC,EAAK,iBAAiB,OAAO;IAClC,IAAM,IAAM,EAAM,QAA+B,QAAQ,uBAAuB;IAGhF,OAFK,KACL,EAAK,gBAAgB,EAAG,aAAa,qBAAqB,KAAK,EAAE,GADjD;GAGlB;EACF,CAAC;CACH;AACF;;;ACnHA,SAAgB,GAAY,EAC1B,UACA,aACA,aACA,gBACA,oBACA,gBACA,YACA,kBACA,WACA,mBACmB;CACnB,IAAM,IAAW,GAAO,CAAe;CACvC,EAAS,UAAU;CACnB,IAAM,IAAU,GAAO,CAAW;CAClC,EAAQ,UAAU;CAGlB,IAAM,CAAC,KAAc,SAAe,CAClC,GAAiB;EACf,kBAAkB,MAAW,EAAS,UAAU,CAAM;EACtD,cAAc,MAAS,EAAQ,UAAU,CAAI;EAC7C;CACF,CAAC,CACH,CAAC,GAEK,IAAM,GAAc;EACxB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CACD,OAAO,mBAAC,OAAD;EAAK,WAAW,EAAO;EAAc;CAAM,CAAA;AACpD"}