@bendyline/squisq 1.5.2 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/README.md +63 -10
  2. package/dist/{Doc-BBVGq1_9.d.ts → Doc-ylqWKDc_.d.ts} +248 -37
  3. package/dist/{ImageEditDoc-FuyGtt6o.d.ts → ImageEditDoc-D828IXJ1.d.ts} +1 -1
  4. package/dist/annotationCoercion-Dr_DY9Hx.d.ts +86 -0
  5. package/dist/{chunk-T5UK6YOB.js → chunk-2PWOO4ZE.js} +60 -17
  6. package/dist/chunk-2PWOO4ZE.js.map +1 -0
  7. package/dist/{chunk-VWUFZ6ZG.js → chunk-3E5F2XMR.js} +2 -29
  8. package/dist/chunk-3E5F2XMR.js.map +1 -0
  9. package/dist/chunk-4X3JQXNM.js +35 -0
  10. package/dist/chunk-4X3JQXNM.js.map +1 -0
  11. package/dist/{chunk-P3K7NLHF.js → chunk-5DKBFXPY.js} +31 -121
  12. package/dist/chunk-5DKBFXPY.js.map +1 -0
  13. package/dist/{chunk-DLXZMS5K.js → chunk-5J4HKRJF.js} +51 -3
  14. package/dist/chunk-5J4HKRJF.js.map +1 -0
  15. package/dist/chunk-5UYI3RJB.js +2503 -0
  16. package/dist/chunk-5UYI3RJB.js.map +1 -0
  17. package/dist/{chunk-BEQODJWV.js → chunk-66QO7XFB.js} +11 -291
  18. package/dist/chunk-66QO7XFB.js.map +1 -0
  19. package/dist/{chunk-HWVFJAAH.js → chunk-AMIR72JP.js} +28 -10
  20. package/dist/chunk-AMIR72JP.js.map +1 -0
  21. package/dist/chunk-CY2R2VPR.js +884 -0
  22. package/dist/chunk-CY2R2VPR.js.map +1 -0
  23. package/dist/chunk-FVJUUTEM.js +74 -0
  24. package/dist/chunk-FVJUUTEM.js.map +1 -0
  25. package/dist/{chunk-Q3ROPT5H.js → chunk-GZY66SDN.js} +1 -1
  26. package/dist/{chunk-Q3ROPT5H.js.map → chunk-GZY66SDN.js.map} +1 -1
  27. package/dist/chunk-JOQYPRDZ.js +127 -0
  28. package/dist/chunk-JOQYPRDZ.js.map +1 -0
  29. package/dist/{chunk-A4O7GIWE.js → chunk-MMPBOUK7.js} +10 -73
  30. package/dist/chunk-MMPBOUK7.js.map +1 -0
  31. package/dist/{chunk-LDQ2HJIX.js → chunk-PXLVXTLW.js} +252 -54
  32. package/dist/chunk-PXLVXTLW.js.map +1 -0
  33. package/dist/{chunk-TQWLI6S2.js → chunk-Q7LROV2H.js} +4 -2
  34. package/dist/{chunk-TQWLI6S2.js.map → chunk-Q7LROV2H.js.map} +1 -1
  35. package/dist/{chunk-GPLTCSXO.js → chunk-R2GC6RLD.js} +7 -7
  36. package/dist/chunk-R2GC6RLD.js.map +1 -0
  37. package/dist/chunk-R2YZTCLO.js +292 -0
  38. package/dist/chunk-R2YZTCLO.js.map +1 -0
  39. package/dist/chunk-S7A5D7ZJ.js +174 -0
  40. package/dist/chunk-S7A5D7ZJ.js.map +1 -0
  41. package/dist/chunk-TFJVXUHH.js +2358 -0
  42. package/dist/chunk-TFJVXUHH.js.map +1 -0
  43. package/dist/{chunk-LTN6I7QW.js → chunk-TUWMK62B.js} +55 -4
  44. package/dist/chunk-TUWMK62B.js.map +1 -0
  45. package/dist/{chunk-IMSCRLLV.js → chunk-VR7UPJ7C.js} +35 -25
  46. package/dist/chunk-VR7UPJ7C.js.map +1 -0
  47. package/dist/{chunk-KKNUBQ6Y.js → chunk-W4O2TX5I.js} +157 -92
  48. package/dist/chunk-W4O2TX5I.js.map +1 -0
  49. package/dist/{chunk-5TYS5V3G.js → chunk-X6DUONGT.js} +4204 -3560
  50. package/dist/chunk-X6DUONGT.js.map +1 -0
  51. package/dist/doc/index.d.ts +2334 -5
  52. package/dist/doc/index.js +127 -33
  53. package/dist/generate/index.d.ts +7 -2
  54. package/dist/generate/index.js +1 -1
  55. package/dist/imageEdit/index.d.ts +9 -6
  56. package/dist/imageEdit/index.js +3 -3
  57. package/dist/index.d.ts +12 -10
  58. package/dist/index.js +246 -80
  59. package/dist/jsonForm/index.d.ts +7 -3
  60. package/dist/jsonForm/index.js +9 -4
  61. package/dist/markdown/index.d.ts +6 -70
  62. package/dist/markdown/index.js +13 -9
  63. package/dist/narration/index.d.ts +618 -0
  64. package/dist/narration/index.js +82 -0
  65. package/dist/recommend/index.d.ts +15 -1
  66. package/dist/recommend/index.js +2 -2
  67. package/dist/schemas/index.d.ts +28 -6
  68. package/dist/schemas/index.js +15 -13
  69. package/dist/spatial/index.d.ts +0 -1
  70. package/dist/spatial/index.js +1 -1
  71. package/dist/storage/index.js +1 -1
  72. package/dist/{themeLibrary-CehcJhzz.d.ts → themeLibrary-RjVgLpUi.d.ts} +10 -11
  73. package/dist/timing/index.js +5 -3
  74. package/dist/transform/index.d.ts +35 -24
  75. package/dist/transform/index.js +9 -10
  76. package/dist/{types-DlAZ7MW4.d.ts → types-BwMPl2CB.d.ts} +1 -1
  77. package/dist/{types-D98li1gV.d.ts → types-C4kiRn_k.d.ts} +3 -1
  78. package/dist/versions/index.d.ts +2 -1
  79. package/dist/versions/index.js +2 -2
  80. package/package.json +6 -6
  81. package/src/__tests__/applyNarrationTiming.test.ts +190 -0
  82. package/src/__tests__/applyRenderStyle.test.ts +3 -3
  83. package/src/__tests__/asciiDiagramBattle.test.ts +246 -0
  84. package/src/__tests__/asciiDiagramDetect.test.ts +162 -0
  85. package/src/__tests__/asciiDiagramMapping.test.ts +38 -0
  86. package/src/__tests__/asciiDiagramParse.test.ts +233 -0
  87. package/src/__tests__/asciiDiagramPipeline.test.ts +273 -0
  88. package/src/__tests__/asciiDiagramRender.test.ts +162 -0
  89. package/src/__tests__/asciiDiagramRepair.test.ts +84 -0
  90. package/src/__tests__/asciiTimelineDetect.test.ts +157 -0
  91. package/src/__tests__/asciiTimelineParse.test.ts +205 -0
  92. package/src/__tests__/asciiTimelinePipeline.test.ts +349 -0
  93. package/src/__tests__/asciiTimelineRender.test.ts +376 -0
  94. package/src/__tests__/attrTokens.test.ts +5 -0
  95. package/src/__tests__/contentContainer.test.ts +43 -0
  96. package/src/__tests__/customTemplatesFrontmatter.test.ts +0 -15
  97. package/src/__tests__/customThemesFrontmatter.test.ts +1 -0
  98. package/src/__tests__/dataTable.test.ts +25 -15
  99. package/src/__tests__/diagramBlock.test.ts +3 -3
  100. package/src/__tests__/diagramText.test.ts +26 -0
  101. package/src/__tests__/docToMarkdownMedia.test.ts +83 -0
  102. package/src/__tests__/drawingBlock.test.ts +3 -3
  103. package/src/__tests__/fixtures/asciiDiagramBattle.ts +512 -0
  104. package/src/__tests__/fixtures/asciiDiagrams.ts +287 -0
  105. package/src/__tests__/fixtures/asciiTimelines.ts +35 -0
  106. package/src/__tests__/fixtures/treeviewFixtures.ts +243 -0
  107. package/src/__tests__/getLayers.test.ts +32 -18
  108. package/src/__tests__/getLayersFallback.test.ts +8 -8
  109. package/src/__tests__/imageEditVersions.test.ts +2 -0
  110. package/src/__tests__/jsonForm.pointer.test.ts +47 -1
  111. package/src/__tests__/layoutBlock.test.ts +3 -3
  112. package/src/__tests__/majorApiTypes.test.ts +18 -0
  113. package/src/__tests__/markdown.test.ts +54 -4
  114. package/src/__tests__/markdownSanitize.test.ts +7 -5
  115. package/src/__tests__/matchFontFamily.test.ts +114 -0
  116. package/src/__tests__/materializeBlockLayers.test.ts +135 -0
  117. package/src/__tests__/materializeTestUtils.ts +17 -0
  118. package/src/__tests__/narrationAlign.test.ts +150 -0
  119. package/src/__tests__/narrationFeatures.test.ts +71 -0
  120. package/src/__tests__/narrationNuclei.test.ts +45 -0
  121. package/src/__tests__/narrationPacing.test.ts +189 -0
  122. package/src/__tests__/narrationScript.test.ts +149 -0
  123. package/src/__tests__/narrationSessionRepro.test.ts +62 -0
  124. package/src/__tests__/narrationSidecar.test.ts +88 -0
  125. package/src/__tests__/narrationSyllables.test.ts +65 -0
  126. package/src/__tests__/narrationTestSignals.ts +167 -0
  127. package/src/__tests__/narrationVad.test.ts +66 -0
  128. package/src/__tests__/resolveDocTheme.test.ts +16 -2
  129. package/src/__tests__/rootExports.test.ts +18 -0
  130. package/src/__tests__/scopedContentContainer.test.ts +20 -0
  131. package/src/__tests__/shapeGeometry.test.ts +12 -0
  132. package/src/__tests__/templateAnnotationParse.test.ts +10 -0
  133. package/src/__tests__/templateInputs.test.ts +69 -0
  134. package/src/__tests__/templateMetadata.test.ts +2 -1
  135. package/src/__tests__/templates.test.ts +143 -17
  136. package/src/__tests__/themeCompile.test.ts +49 -22
  137. package/src/__tests__/transformProvenance.test.ts +160 -0
  138. package/src/__tests__/transformV2.test.ts +40 -14
  139. package/src/__tests__/treeviewBattle.test.ts +76 -0
  140. package/src/__tests__/treeviewDetect.test.ts +168 -0
  141. package/src/__tests__/treeviewParse.test.ts +118 -0
  142. package/src/__tests__/treeviewPipeline.test.ts +183 -0
  143. package/src/__tests__/treeviewRender.test.ts +91 -0
  144. package/src/__tests__/versions.test.ts +44 -0
  145. package/src/doc/applyNarrationTiming.ts +244 -0
  146. package/src/doc/asciiDiagram/chars.ts +210 -0
  147. package/src/doc/asciiDiagram/detect.ts +175 -0
  148. package/src/doc/asciiDiagram/index.ts +38 -0
  149. package/src/doc/asciiDiagram/mapping.ts +225 -0
  150. package/src/doc/asciiDiagram/parse.ts +1095 -0
  151. package/src/doc/asciiDiagram/render.ts +963 -0
  152. package/src/doc/asciiDiagram/repair.ts +400 -0
  153. package/src/doc/asciiDiagram/types.ts +65 -0
  154. package/src/doc/asciiTimeline/detect.ts +138 -0
  155. package/src/doc/asciiTimeline/index.ts +26 -0
  156. package/src/doc/asciiTimeline/mapping.ts +43 -0
  157. package/src/doc/asciiTimeline/parse.ts +870 -0
  158. package/src/doc/asciiTimeline/render.ts +427 -0
  159. package/src/doc/asciiTimeline/types.ts +73 -0
  160. package/src/doc/asciiTimeline/wrappedFlow.ts +427 -0
  161. package/src/doc/audioMapping.ts +60 -46
  162. package/src/doc/customTemplatesFrontmatter.ts +0 -41
  163. package/src/doc/docToMarkdown.ts +70 -2
  164. package/src/doc/index.ts +76 -4
  165. package/src/doc/markdownToDoc.ts +138 -2
  166. package/src/doc/materializeBlockLayers.ts +304 -0
  167. package/src/doc/mediaAnnotations.ts +20 -0
  168. package/src/doc/resolveDocTheme.ts +8 -7
  169. package/src/doc/templateInputs.ts +185 -2
  170. package/src/doc/templates/__tests__/customTemplateRegistry.test.ts +22 -8
  171. package/src/doc/templates/__tests__/listBlock.test.ts +64 -0
  172. package/src/doc/templates/diagramBlock.ts +237 -38
  173. package/src/doc/templates/fallbackBlock.ts +1 -1
  174. package/src/doc/templates/index.ts +134 -279
  175. package/src/doc/templates/inputDescriptors.ts +20 -1
  176. package/src/doc/templates/listBlock.ts +88 -30
  177. package/src/doc/templates/metadata.ts +10 -0
  178. package/src/doc/templates/persistentLayers.ts +12 -126
  179. package/src/doc/templates/registry.ts +88 -0
  180. package/src/doc/templates/templateNames.ts +22 -0
  181. package/src/doc/templates/timelineBlock.ts +613 -0
  182. package/src/doc/templates/treeBlock.ts +131 -0
  183. package/src/doc/treeview/chars.ts +72 -0
  184. package/src/doc/treeview/detect.ts +145 -0
  185. package/src/doc/treeview/index.ts +30 -0
  186. package/src/doc/treeview/mapping.ts +95 -0
  187. package/src/doc/treeview/parse.ts +201 -0
  188. package/src/doc/treeview/render.ts +41 -0
  189. package/src/doc/treeview/types.ts +43 -0
  190. package/src/doc/utils/applyRenderStyle.ts +2 -9
  191. package/src/doc/utils/diagramText.ts +78 -0
  192. package/src/doc/utils/shapeGeometry.ts +67 -5
  193. package/src/doc/validate.ts +1 -1
  194. package/src/generate/templateMapper.ts +7 -0
  195. package/src/imageEdit/export.ts +6 -5
  196. package/src/imageEdit/versionPaths.ts +13 -26
  197. package/src/imageEdit/versions.ts +21 -100
  198. package/src/index.ts +1 -0
  199. package/src/internal/immutable.ts +58 -0
  200. package/src/jsonForm/index.ts +9 -1
  201. package/src/jsonForm/pointer.ts +68 -23
  202. package/src/markdown/attrTokens.ts +7 -5
  203. package/src/markdown/index.ts +1 -0
  204. package/src/markdown/stringify.ts +4 -9
  205. package/src/markdown/utils.ts +36 -14
  206. package/src/narration/align.ts +514 -0
  207. package/src/narration/features.ts +231 -0
  208. package/src/narration/index.ts +86 -0
  209. package/src/narration/nuclei.ts +118 -0
  210. package/src/narration/pacing.ts +211 -0
  211. package/src/narration/script.ts +239 -0
  212. package/src/narration/session.ts +100 -0
  213. package/src/narration/sidecar.ts +187 -0
  214. package/src/narration/syllables.ts +85 -0
  215. package/src/narration/trace.ts +50 -0
  216. package/src/narration/types.ts +299 -0
  217. package/src/narration/vad.ts +131 -0
  218. package/src/recommend/numberHighlight.ts +25 -0
  219. package/src/recommend/templates.ts +108 -12
  220. package/src/schemas/BlockTemplates.ts +156 -7
  221. package/src/schemas/Doc.ts +72 -9
  222. package/src/schemas/Media.ts +12 -2
  223. package/src/schemas/Theme.ts +45 -25
  224. package/src/schemas/Viewport.ts +2 -2
  225. package/src/schemas/fontStacks.ts +79 -0
  226. package/src/schemas/themeCompile.ts +15 -0
  227. package/src/schemas/themeConstants.ts +2 -0
  228. package/src/schemas/themeLibrary.ts +25 -19
  229. package/src/schemas/themeValidator.ts +1 -1
  230. package/src/schemas/themes/gezellig.json +1 -1
  231. package/src/spatial/Geohash.ts +0 -3
  232. package/src/storage/ContentContainer.ts +17 -9
  233. package/src/storage/ScopedContentContainer.ts +45 -15
  234. package/src/transform/applyTransform.ts +5 -5
  235. package/src/transform/index.ts +3 -1
  236. package/src/transform/registry.ts +169 -49
  237. package/src/transform/templateSelector.ts +21 -2
  238. package/src/transform/timingAllocator.ts +152 -21
  239. package/src/transform/types.ts +14 -1
  240. package/src/versions/gitignore.ts +34 -0
  241. package/src/versions/index.ts +2 -0
  242. package/src/versions/operations.ts +18 -104
  243. package/src/versions/paths.ts +13 -28
  244. package/src/versions/snapshotStore.ts +202 -0
  245. package/src/versions/types.ts +3 -1
  246. package/dist/chunk-5TYS5V3G.js.map +0 -1
  247. package/dist/chunk-A4O7GIWE.js.map +0 -1
  248. package/dist/chunk-BEQODJWV.js.map +0 -1
  249. package/dist/chunk-DLXZMS5K.js.map +0 -1
  250. package/dist/chunk-GPLTCSXO.js.map +0 -1
  251. package/dist/chunk-HWVFJAAH.js.map +0 -1
  252. package/dist/chunk-IMSCRLLV.js.map +0 -1
  253. package/dist/chunk-JELIRVDP.js +0 -24
  254. package/dist/chunk-JELIRVDP.js.map +0 -1
  255. package/dist/chunk-KKNUBQ6Y.js.map +0 -1
  256. package/dist/chunk-LDQ2HJIX.js.map +0 -1
  257. package/dist/chunk-LTN6I7QW.js.map +0 -1
  258. package/dist/chunk-P3K7NLHF.js.map +0 -1
  259. package/dist/chunk-T5UK6YOB.js.map +0 -1
  260. package/dist/chunk-UY7KGQ5R.js +0 -192
  261. package/dist/chunk-UY7KGQ5R.js.map +0 -1
  262. package/dist/chunk-VLJJHDAC.js +0 -218
  263. package/dist/chunk-VLJJHDAC.js.map +0 -1
  264. package/dist/chunk-VWUFZ6ZG.js.map +0 -1
  265. package/dist/story/index.d.ts +0 -1801
  266. package/dist/story/index.js +0 -279
  267. package/src/doc/getLayers.ts +0 -195
  268. /package/dist/{story → narration}/index.js.map +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/doc/asciiDiagram/chars.ts","../src/doc/asciiDiagram/parse.ts","../src/doc/asciiDiagram/detect.ts","../src/doc/asciiTimeline/wrappedFlow.ts","../src/doc/asciiTimeline/parse.ts","../src/doc/asciiTimeline/detect.ts","../src/doc/treeview/chars.ts","../src/doc/treeview/parse.ts","../src/doc/treeview/detect.ts","../src/recommend/numberHighlight.ts","../src/recommend/templates.ts"],"sourcesContent":["/**\n * Character classification for ASCII/Unicode box-and-line diagram art.\n *\n * The parse side accepts a superset (light/rounded/heavy/double Unicode\n * box-drawing plus ASCII `+ - |` and both arrow families); the render\n * side always emits one of the two `StyleVocab` tables below.\n *\n * Internal to the asciiDiagram module — not exported from the barrel.\n */\n\nconst TL_CORNERS = new Set(['┌', '╭', '┏', '╔']);\nconst TR_CORNERS = new Set(['┐', '╮', '┓', '╗']);\nconst BL_CORNERS = new Set(['└', '╰', '┗', '╚']);\nconst BR_CORNERS = new Set(['┘', '╯', '┛', '╝']);\nconst HORIZ = new Set(['─', '━', '═', '-']);\nconst VERT = new Set(['│', '┃', '║', '|']);\nconst JUNCTIONS = new Set([\n '├',\n '┤',\n '┬',\n '┴',\n '┼',\n '┣',\n '┫',\n '┳',\n '┻',\n '╋',\n '╠',\n '╣',\n '╦',\n '╩',\n '╬',\n '╞',\n '╡',\n '╥',\n '╨',\n '╫',\n '╪',\n]);\n/** Junctions whose stems include a vertical component (legal on side borders). */\nconst SIDE_JUNCTIONS = new Set(['├', '┤', '┼', '┣', '┫', '╋', '╠', '╣', '╬', '╞', '╡', '╫', '╪']);\n/** Junctions whose stems include a horizontal component (legal on top/bottom borders). */\nconst FLAT_JUNCTIONS = new Set(['┬', '┴', '┼', '┳', '┻', '╋', '╦', '╩', '╬', '╥', '╨', '╫', '╪']);\n\nconst ARROW_UP = new Set(['▲', '↑']);\nconst ARROW_DOWN = new Set(['▼', '↓']);\nconst ARROW_LEFT = new Set(['◄', '←', '◀']);\nconst ARROW_RIGHT = new Set(['►', '→', '▶']);\n\nexport type ArrowDirection = 'up' | 'down' | 'left' | 'right';\n\nexport function isTlCorner(ch: string): boolean {\n return TL_CORNERS.has(ch);\n}\nexport function isTrCorner(ch: string): boolean {\n return TR_CORNERS.has(ch);\n}\nexport function isBlCorner(ch: string): boolean {\n return BL_CORNERS.has(ch);\n}\nexport function isBrCorner(ch: string): boolean {\n return BR_CORNERS.has(ch);\n}\nexport function isAnyCorner(ch: string): boolean {\n return TL_CORNERS.has(ch) || TR_CORNERS.has(ch) || BL_CORNERS.has(ch) || BR_CORNERS.has(ch);\n}\nexport function isHoriz(ch: string): boolean {\n return HORIZ.has(ch);\n}\nexport function isVert(ch: string): boolean {\n return VERT.has(ch);\n}\nexport function isJunction(ch: string): boolean {\n return JUNCTIONS.has(ch);\n}\nexport function isPlus(ch: string): boolean {\n return ch === '+';\n}\n\n/** Acceptable interior of a top/bottom border walk (corners excluded). */\nexport function isFlatBorderChar(ch: string): boolean {\n return isHoriz(ch) || FLAT_JUNCTIONS.has(ch) || isPlus(ch);\n}\n\n/** Acceptable interior of a left/right border walk (corners excluded). */\nexport function isSideBorderChar(ch: string): boolean {\n return isVert(ch) || SIDE_JUNCTIONS.has(ch) || isPlus(ch);\n}\n\n/**\n * Direction of an unconditional (Unicode) arrowhead, or null. ASCII\n * `^ v < >` are ambiguous with prose and must be gated on an adjacent\n * line character by the caller — use {@link asciiArrowDirection}.\n */\nexport function arrowDirection(ch: string): ArrowDirection | null {\n if (ARROW_UP.has(ch)) return 'up';\n if (ARROW_DOWN.has(ch)) return 'down';\n if (ARROW_LEFT.has(ch)) return 'left';\n if (ARROW_RIGHT.has(ch)) return 'right';\n return null;\n}\n\n/** Direction for ASCII arrow candidates (`^ v V < >`); caller applies the adjacency gate. */\nexport function asciiArrowDirection(ch: string): ArrowDirection | null {\n if (ch === '^') return 'up';\n if (ch === 'v' || ch === 'V') return 'down';\n if (ch === '<') return 'left';\n if (ch === '>') return 'right';\n return null;\n}\n\n/** True for any character that can be part of an edge polyline (lines, turns, junctions). */\nexport function isLineChar(ch: string): boolean {\n return isHoriz(ch) || isVert(ch) || isJunction(ch) || isPlus(ch) || isAnyCorner(ch);\n}\n\n/** True for structural Unicode box-drawing characters (used for the style vote). */\nexport function isUnicodeStructural(ch: string): boolean {\n const code = ch.codePointAt(0) ?? 0;\n // Box Drawing block U+2500–U+257F plus the arrow glyphs we emit.\n return (\n (code >= 0x2500 && code <= 0x257f) ||\n ARROW_UP.has(ch) ||\n ARROW_DOWN.has(ch) ||\n ch === '←' ||\n ch === '→' ||\n ch === '◄' ||\n ch === '►' ||\n ch === '◀' ||\n ch === '▶'\n );\n}\n\n/** True for structural ASCII drawing characters (used for the style vote). */\nexport function isAsciiStructural(ch: string): boolean {\n return ch === '+' || ch === '-' || ch === '|';\n}\n\nexport interface StyleVocab {\n tl: string;\n tr: string;\n bl: string;\n br: string;\n h: string;\n v: string;\n /** Horizontal border cell with a stem descending below it (e.g. a line leaving a bottom border). */\n stemDown: string;\n /** Horizontal border cell with a stem ascending above it (e.g. a line arriving at a top border). */\n stemUp: string;\n /** Vertical border cell with a stem extending leftward. */\n stemLeft: string;\n /** Vertical border cell with a stem extending rightward. */\n stemRight: string;\n cross: string;\n arrowUp: string;\n arrowDown: string;\n arrowLeft: string;\n arrowRight: string;\n /** Turn glyphs for routed edges: connects the two named directions. */\n turnDownRight: string;\n turnDownLeft: string;\n turnUpRight: string;\n turnUpLeft: string;\n}\n\nexport const UNICODE_VOCAB: StyleVocab = {\n tl: '┌',\n tr: '┐',\n bl: '└',\n br: '┘',\n h: '─',\n v: '│',\n stemDown: '┬',\n stemUp: '┴',\n stemLeft: '┤',\n stemRight: '├',\n cross: '┼',\n arrowUp: '▲',\n arrowDown: '▼',\n arrowLeft: '◄',\n arrowRight: '►',\n // Named by the pair of open sides: e.g. turnDownRight opens downward and\n // to the right (a line coming from below turning to the right) = '┌'.\n turnDownRight: '┌',\n turnDownLeft: '┐',\n turnUpRight: '└',\n turnUpLeft: '┘',\n};\n\nexport const ASCII_VOCAB: StyleVocab = {\n tl: '+',\n tr: '+',\n bl: '+',\n br: '+',\n h: '-',\n v: '|',\n stemDown: '+',\n stemUp: '+',\n stemLeft: '+',\n stemRight: '+',\n cross: '+',\n arrowUp: '^',\n arrowDown: 'v',\n arrowLeft: '<',\n arrowRight: '>',\n turnDownRight: '+',\n turnDownLeft: '+',\n turnUpRight: '+',\n turnUpLeft: '+',\n};\n","/**\n * ASCII diagram parser: box-and-line art → semantic nodes/edges.\n *\n * Pure and deterministic; never throws. Unparseable input degrades to an\n * empty diagram (plus warnings), never an exception — callers decide what\n * to do with sparse results (the detector requires ≥2 nodes, for example).\n *\n * Pipeline: normalize → char grid → box tracing (corner walks; `+` is\n * resolved smallest-rectangle-first) → containment tree → labels/ids →\n * edge extraction (mask box perimeters + leaf interiors, then connected\n * components of line/arrow cells with label \"bridges\") → loose text.\n */\n\nimport {\n arrowDirection,\n asciiArrowDirection,\n isAsciiStructural,\n isBlCorner,\n isBrCorner,\n isFlatBorderChar,\n isHoriz,\n isJunction,\n isLineChar,\n isPlus,\n isSideBorderChar,\n isTlCorner,\n isTrCorner,\n isUnicodeStructural,\n isVert,\n type ArrowDirection,\n} from './chars.js';\nimport type { AsciiDiagram, AsciiDiagramEdge, AsciiDiagramNode } from './types.js';\n\n/** Internal stats consumed by the detector (loose-content ratio etc.). */\nexport interface AsciiParseStats {\n totalNonSpaceCells: number;\n looseNonSpaceCells: number;\n hasWideChars: boolean;\n}\n\nexport interface Rect {\n r0: number;\n c0: number;\n r1: number;\n c1: number;\n}\n\ninterface ParsedBox extends Rect {\n /** Title embedded in the top border (`┌── Title ──┐`), if any. */\n borderTitle?: string;\n parentIdx: number;\n labelLines: string[];\n id: string;\n}\n\nconst MAX_TITLE_RUN = 60;\nconst MAX_BRIDGE_GAP = 40;\nconst MAX_LOOSE_WARNINGS = 10;\n/**\n * Consecutive non-border cells tolerated while walking a box's side wall.\n * Hand-drawn art frequently has ragged side borders — a label line that\n * overflowed its box (e.g. a rename widened the text) leaves a space where\n * the `│` should be. The four corners plus the solid top/bottom borders are\n * the real box anchors, so a short run of gaps in a side wall shouldn't stop\n * the wall from reaching its corner. Kept small so two unrelated horizontal\n * rules can't span into a phantom box.\n */\nconst MAX_WALL_GAP = 3;\n/** Larger side-wall gap budget for the opt-in repair pass (badly-drawn art). */\nconst REPAIR_WALL_GAP = 10;\n\n/** True crossings: vertical and horizontal runs pass through independently. */\nconst CROSS_CHARS = new Set(['┼', '╋', '╬', '╫', '╪']);\n\nexport function parseAsciiDiagram(text: string): AsciiDiagram {\n return parseAsciiDiagramWithStats(text).diagram;\n}\n\nexport function parseAsciiDiagramWithStats(text: string): {\n diagram: AsciiDiagram;\n stats: AsciiParseStats;\n} {\n const warnings: string[] = [];\n const grid = buildGrid(text, warnings);\n const H = grid.length;\n const W = H > 0 ? grid[0].length : 0;\n\n let totalNonSpaceCells = 0;\n let hasWideChars = false;\n for (let r = 0; r < H; r++) {\n for (let c = 0; c < W; c++) {\n const ch = grid[r][c];\n if (ch !== ' ') totalNonSpaceCells++;\n if (!hasWideChars && isWideChar(ch)) hasWideChars = true;\n }\n }\n if (hasWideChars) warnings.push('wide-chars');\n\n const style = detectStyle(grid);\n\n // ---- Boxes -------------------------------------------------------------\n const rects = traceBoxes(grid);\n const boxes = buildBoxes(grid, rects, warnings);\n\n // ---- Mask: box perimeters, leaf interiors, container label text --------\n const mask = new Uint8Array(W * H);\n const perimeterOwners = new Map<number, number[]>(); // cell index → box indices\n for (let b = 0; b < boxes.length; b++) {\n const box = boxes[b];\n for (let c = box.c0; c <= box.c1; c++) {\n for (const r of [box.r0, box.r1]) {\n mask[r * W + c] = 1;\n const owners = perimeterOwners.get(r * W + c) ?? [];\n owners.push(b);\n perimeterOwners.set(r * W + c, owners);\n }\n }\n for (let r = box.r0 + 1; r <= box.r1 - 1; r++) {\n for (const c of [box.c0, box.c1]) {\n mask[r * W + c] = 1;\n const owners = perimeterOwners.get(r * W + c) ?? [];\n owners.push(b);\n perimeterOwners.set(r * W + c, owners);\n }\n }\n }\n const isContainer = boxes.map((_, i) => boxes.some((b) => b.parentIdx === i));\n for (let b = 0; b < boxes.length; b++) {\n const box = boxes[b];\n if (!isContainer[b]) {\n // Leaf: whole interior is label space.\n for (let r = box.r0 + 1; r <= box.r1 - 1; r++) {\n for (let c = box.c0 + 1; c <= box.c1 - 1; c++) mask[r * W + c] = 1;\n }\n } else {\n // Container: only the label text cells above the topmost child.\n const minChildR0 = Math.min(\n ...boxes.filter((child) => child.parentIdx === b).map((child) => child.r0),\n );\n for (let r = box.r0 + 1; r < minChildR0; r++) {\n for (let c = box.c0 + 1; c <= box.c1 - 1; c++) {\n const ch = grid[r][c];\n if (ch !== ' ' && !isLineChar(ch) && arrowDirection(ch) === null) mask[r * W + c] = 1;\n }\n }\n }\n }\n\n // ---- Edges ---------------------------------------------------------------\n const { edges, edgeCells } = extractEdges(grid, mask, perimeterOwners, boxes, warnings);\n\n // ---- Loose text ---------------------------------------------------------\n let looseNonSpaceCells = 0;\n const looseRuns: string[] = [];\n for (let r = 0; r < H; r++) {\n let run = '';\n const flush = () => {\n if (run.trim().length > 0) looseRuns.push(`@${r}: ${truncate(run.trim(), 30)}`);\n run = '';\n };\n const isLooseCell = (c: number): boolean => {\n if (c < 0 || c >= W) return false;\n const idx = r * W + c;\n return grid[r][c] !== ' ' && !mask[idx] && !edgeCells.has(idx);\n };\n for (let c = 0; c < W; c++) {\n if (isLooseCell(c)) {\n run += grid[r][c];\n looseNonSpaceCells++;\n } else if (run !== '' && grid[r][c] === ' ' && isLooseCell(c + 1)) {\n run += ' '; // single interior space keeps phrases together\n } else {\n flush();\n }\n }\n flush();\n }\n for (const runText of looseRuns.slice(0, MAX_LOOSE_WARNINGS)) {\n warnings.push(`loose-text ${runText}`);\n }\n if (looseRuns.length > MAX_LOOSE_WARNINGS) {\n warnings.push(`loose-text (+${looseRuns.length - MAX_LOOSE_WARNINGS} more)`);\n }\n\n // ---- Assemble -----------------------------------------------------------\n const nodes: AsciiDiagramNode[] = boxes.map((box) => ({\n id: box.id,\n label: box.labelLines.join('\\n'),\n col: box.c0,\n row: box.r0,\n wCols: box.c1 - box.c0 + 1,\n hRows: box.r1 - box.r0 + 1,\n ...(box.parentIdx >= 0 ? { containerId: boxes[box.parentIdx].id } : {}),\n }));\n\n return {\n diagram: { nodes, edges, style, warnings },\n stats: { totalNonSpaceCells, looseNonSpaceCells, hasWideChars },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Grid\n// ---------------------------------------------------------------------------\n\nfunction buildGrid(text: string, warnings: string[]): string[][] {\n const rawLines = text.replace(/\\r\\n?/g, '\\n').split('\\n');\n let hadTab = false;\n const rows: string[][] = rawLines.map((line) => {\n const cells: string[] = [];\n for (const ch of line) {\n if (ch === '\\t') {\n hadTab = true;\n do {\n cells.push(' ');\n } while (cells.length % 4 !== 0);\n } else {\n cells.push(ch);\n }\n }\n return cells;\n });\n if (hadTab) warnings.push('tabs-expanded');\n let width = 0;\n for (const row of rows) width = Math.max(width, row.length);\n for (const row of rows) {\n while (row.length < width) row.push(' ');\n }\n return rows;\n}\n\nfunction isWideChar(ch: string): boolean {\n const c = ch.codePointAt(0) ?? 0;\n return (\n (c >= 0x1100 && c <= 0x115f) ||\n (c >= 0x2e80 && c <= 0x303e) ||\n (c >= 0x3041 && c <= 0x33ff) ||\n (c >= 0x3400 && c <= 0x4dbf) ||\n (c >= 0x4e00 && c <= 0x9fff) ||\n (c >= 0xac00 && c <= 0xd7a3) ||\n (c >= 0xf900 && c <= 0xfaff) ||\n (c >= 0xfe30 && c <= 0xfe4f) ||\n (c >= 0xff00 && c <= 0xff60) ||\n (c >= 0x1f300 && c <= 0x1faff)\n );\n}\n\nfunction detectStyle(grid: string[][]): 'unicode' | 'ascii' {\n let unicode = 0;\n let ascii = 0;\n for (const row of grid) {\n for (const ch of row) {\n if (isUnicodeStructural(ch)) unicode++;\n else if (isAsciiStructural(ch)) ascii++;\n }\n }\n return ascii > unicode ? 'ascii' : 'unicode';\n}\n\n// ---------------------------------------------------------------------------\n// Box tracing\n// ---------------------------------------------------------------------------\n\nexport interface TracedRect extends Rect {\n borderTitle?: string;\n}\n\n/**\n * Trace every box rectangle in the grid. `repair` mode is the aggressive\n * variant used only by the opt-in `repairAsciiDiagram` pass: it lets a side\n * wall cross edge-routing chars (a hand-drawn box whose label overflowed can\n * push arrows/lines through where its `│` should be), so more boxes of\n * genuinely-broken art are recovered. Conservative auto-detection never uses\n * it (a phantom box there would hide real code).\n */\nexport function traceBoxes(grid: string[][], repair = false): TracedRect[] {\n const H = grid.length;\n const W = H > 0 ? grid[0].length : 0;\n const found: TracedRect[] = [];\n for (let r = 0; r < H; r++) {\n for (let c = 0; c < W; c++) {\n if (!isTlCandidate(grid, r, c)) continue;\n const rect = traceBoxFrom(grid, r, c, repair);\n if (rect) found.push(rect);\n }\n }\n return found;\n}\n\n/** Build the code-point grid for a fence's text (CRLF/tab-normalized, padded). */\nexport function toGrid(text: string): string[][] {\n return buildGrid(text, []);\n}\n\nfunction isTlCandidate(grid: string[][], r: number, c: number): boolean {\n const ch = grid[r][c];\n if (isTlCorner(ch)) return true;\n // `+` (ASCII) and junction chars (Unicode `├ ┬ ┼` on shared borders /\n // sectioned cards) can open a box when a border continues right + down.\n if (!isPlus(ch) && !isJunction(ch)) return false;\n const right = grid[r][c + 1] ?? ' ';\n const below = grid[r + 1]?.[c] ?? ' ';\n const rightOk = isFlatBorderChar(right) || isTrCorner(right);\n const belowOk = isSideBorderChar(below) || isBlCorner(below);\n return rightOk && belowOk;\n}\n\n/**\n * Attempt to confirm a full rectangle starting at a top-left corner.\n * Smallest-rectangle-first: the first (nearest) TR/bottom-row combination\n * that closes wins, so `+` lattices decompose into cells and stacked\n * shared-border boxes parse as siblings.\n */\nfunction traceBoxFrom(grid: string[][], r0: number, c0: number, repair = false): TracedRect | null {\n const H = grid.length;\n const W = grid[0]?.length ?? 0;\n\n // -- Top border walk: collect TR candidates; allow one embedded title run.\n const trCandidates: number[] = [];\n let titleRun: { from: number; to: number } | null = null;\n let c = c0 + 1;\n while (c < W) {\n const ch = grid[r0][c];\n if (isTrCorner(ch)) {\n trCandidates.push(c);\n break; // a Unicode TR corner definitively ends the border\n }\n if (isPlus(ch) || isJunction(ch)) {\n trCandidates.push(c); // ambiguous: candidate AND possible continuation\n c++;\n continue;\n }\n if (isFlatBorderChar(ch)) {\n c++;\n continue;\n }\n // An arrowhead embedded in the border (`┌───▼──┐`, `┌─▼──▼──▼─┐`) is a\n // stem where an edge attaches, not a title — walk through it so the box\n // still closes (and so a border can hold several arrival points). Edge\n // extraction connects the line above/below to this box.\n if (arrowDirection(ch) !== null) {\n c++;\n continue;\n }\n // Possible embedded title (`┌── Title ──┐`): a single non-border run\n // bounded by border chars on both sides.\n if (titleRun) break;\n let end = c;\n let sawText = false;\n while (end < W && end - c <= MAX_TITLE_RUN) {\n const tch = grid[r0][end];\n if (isFlatBorderChar(tch) || isTrCorner(tch) || arrowDirection(tch) !== null) break;\n if (tch !== ' ') sawText = true;\n end++;\n }\n if (end >= W || end - c > MAX_TITLE_RUN || !sawText || end === c) break;\n titleRun = { from: c, to: end - 1 };\n c = end;\n }\n if (trCandidates.length === 0) return null;\n\n // -- Left wall (same for every TR candidate).\n const leftCandidates = walkSideWall(grid, c0, r0, H, isBlCorner, repair);\n if (leftCandidates.length === 0) return null;\n const leftSet = new Set(leftCandidates);\n\n for (const c1 of trCandidates) {\n if (c1 < c0 + 2) continue; // minimum width 3\n\n // -- Right wall for this candidate.\n const rightCandidates = walkSideWall(grid, c1, r0, H, isBrCorner, repair);\n\n for (const r1 of rightCandidates) {\n if (r1 < r0 + 2) continue; // minimum height 3\n if (!leftSet.has(r1)) continue;\n // -- Bottom border must be solid.\n let ok = true;\n for (let bc = c0 + 1; bc <= c1 - 1; bc++) {\n if (!isFlatBorderChar(grid[r1][bc])) {\n ok = false;\n break;\n }\n }\n if (!ok) continue;\n // -- Anti-phantom guard for the gap tolerance: a real box has an actual\n // side-border char on EACH wall's interior. A rectangle bridged purely\n // through gap cells (e.g. the `┌──┴──┐`/`└──┬──┘` routing corners of a\n // fan-out/fan-in, whose sides are empty) has none, and must not become a\n // box. Clean boxes always pass — their interior rows carry `│`/`├`/`┤`.\n // Repair mode widens the check to a ±1 column window so a uniformly\n // SHIFTED side border (corners at c1 but the `│` a column over — common\n // in hand-drawn art) still counts as evidence; a phantom's empty sides\n // stay empty in the window too, so it's still rejected.\n const win = repair ? 1 : 0;\n let leftBorders = 0;\n let rightBorders = 0;\n for (let ir = r0 + 1; ir <= r1 - 1; ir++) {\n if (hasSideBorderNear(grid[ir], c0, win)) leftBorders++;\n if (hasSideBorderNear(grid[ir], c1, win)) rightBorders++;\n }\n if (leftBorders === 0 || rightBorders === 0) continue;\n const title =\n titleRun && titleRun.to < c1\n ? grid[r0]\n .slice(titleRun.from, titleRun.to + 1)\n .join('')\n .trim()\n : undefined;\n return { r0, c0, r1, c1, ...(title ? { borderTitle: title } : {}) };\n }\n }\n return null;\n}\n\n/**\n * Walk one side wall of a box down from just below its top corner, collecting\n * corner-candidate rows (and junction rows, which double as shared-border\n * candidates). Tolerates up to {@link MAX_WALL_GAP} consecutive non-border\n * cells so a ragged / overflowed side border (hand-drawn art, or a rename\n * that widened a label past its box) still reaches the bottom corner. The\n * caller still requires the intersecting BL/BR corners and a solid bottom\n * border, so the gap tolerance can't invent a box out of empty columns.\n */\n/** True when a side-border char sits within `win` columns of `col` on `row`. */\nfunction hasSideBorderNear(row: string[], col: number, win: number): boolean {\n for (let c = col - win; c <= col + win; c++) {\n const ch = row[c];\n if (ch !== undefined && isSideBorderChar(ch)) return true;\n }\n return false;\n}\n\nfunction walkSideWall(\n grid: string[][],\n col: number,\n r0: number,\n H: number,\n isCorner: (ch: string) => boolean,\n repair = false,\n): number[] {\n const candidates: number[] = [];\n const maxGap = repair ? REPAIR_WALL_GAP : MAX_WALL_GAP;\n let gap = 0;\n for (let r = r0 + 1; r < H; r++) {\n const ch = grid[r][col];\n if (isCorner(ch)) {\n candidates.push(r);\n break;\n }\n if (isPlus(ch) || isJunction(ch)) {\n candidates.push(r);\n gap = 0;\n continue;\n }\n if (isSideBorderChar(ch)) {\n gap = 0;\n continue;\n }\n // Only spaces / overflow label text are tolerable ragged-wall gaps. A\n // line or arrowhead sitting in the wall path is edge routing crossing\n // here (e.g. a fan-in `▼` between a source box and the collector), not a\n // box wall — stop, so routing can't bridge into a phantom box. In the\n // opt-in repair pass we tolerate even that (badly-drawn boxes push routing\n // through their walls); the side-border-evidence guard still applies.\n if (!repair && (isLineChar(ch) || arrowDirection(ch) !== null)) break;\n if (++gap > maxGap) break;\n }\n return candidates;\n}\n\n// ---------------------------------------------------------------------------\n// Containment, labels, ids\n// ---------------------------------------------------------------------------\n\nfunction strictlyContains(parent: Rect, child: Rect): boolean {\n return (\n parent.r0 < child.r0 && parent.c0 < child.c0 && parent.r1 > child.r1 && parent.c1 > child.c1\n );\n}\n\n/**\n * True when the boxes' INTERIORS overlap. Sharing a border line (stacked\n * `+--+ / +--+` cards, lattices) is legal and must not warn.\n */\nfunction interiorsOverlap(a: Rect, b: Rect): boolean {\n return (\n a.r0 + 1 <= b.r1 - 1 && b.r0 + 1 <= a.r1 - 1 && a.c0 + 1 <= b.c1 - 1 && b.c0 + 1 <= a.c1 - 1\n );\n}\n\nfunction area(rect: Rect): number {\n return (rect.r1 - rect.r0 + 1) * (rect.c1 - rect.c0 + 1);\n}\n\nfunction buildBoxes(grid: string[][], rects: TracedRect[], warnings: string[]): ParsedBox[] {\n // Reading order: row, then col.\n const sorted = [...rects].sort((a, b) => a.r0 - b.r0 || a.c0 - b.c0);\n\n // Parents: smallest strictly-containing box; ties → first in reading order.\n const parentIdx = sorted.map((child, i) => {\n let best = -1;\n let bestArea = Infinity;\n for (let j = 0; j < sorted.length; j++) {\n if (j === i) continue;\n if (!strictlyContains(sorted[j], child)) continue;\n const a = area(sorted[j]);\n if (a < bestArea) {\n bestArea = a;\n best = j;\n }\n }\n return best;\n });\n\n // Overlap (interiors intersect, neither contains) → keep both + warning.\n let warnedOverlap = false;\n for (let i = 0; i < sorted.length && !warnedOverlap; i++) {\n for (let j = i + 1; j < sorted.length; j++) {\n if (\n interiorsOverlap(sorted[i], sorted[j]) &&\n !strictlyContains(sorted[i], sorted[j]) &&\n !strictlyContains(sorted[j], sorted[i])\n ) {\n warnings.push('overlapping-boxes');\n warnedOverlap = true;\n break;\n }\n }\n }\n\n const hasChildren = sorted.map((_, i) => parentIdx.includes(i));\n\n const usedIds = new Map<string, number>();\n const boxes: ParsedBox[] = sorted.map((rect, i) => {\n const labelLines: string[] = [];\n if (rect.borderTitle) labelLines.push(rect.borderTitle);\n if (!hasChildren[i]) {\n for (let r = rect.r0 + 1; r <= rect.r1 - 1; r++) {\n const rowText = grid[r].slice(rect.c0 + 1, rect.c1).join('');\n if (isDividerRow(rowText)) continue;\n const trimmed = rowText.trim();\n if (trimmed.length > 0) labelLines.push(trimmed);\n }\n } else {\n const minChildR0 = Math.min(\n ...sorted.filter((_, j) => parentIdx[j] === i).map((child) => child.r0),\n );\n for (let r = rect.r0 + 1; r < minChildR0; r++) {\n const rowText = grid[r]\n .slice(rect.c0 + 1, rect.c1)\n .map((ch) => (isLineChar(ch) || arrowDirection(ch) !== null ? ' ' : ch))\n .join('')\n .trim();\n if (rowText.length > 0) labelLines.push(rowText);\n }\n }\n const base = slugify(labelLines[0] ?? '');\n const count = usedIds.get(base) ?? 0;\n usedIds.set(base, count + 1);\n const id = count === 0 ? base : `${base}-${count + 1}`;\n return { ...rect, parentIdx: parentIdx[i], labelLines, id };\n });\n return boxes;\n}\n\n/** A leaf interior row that is purely a horizontal divider (`├────┤` style). */\nfunction isDividerRow(rowText: string): boolean {\n let sawLine = false;\n for (const ch of rowText) {\n if (ch === ' ') continue;\n if (isHoriz(ch) || isJunction(ch) || isPlus(ch)) {\n sawLine = true;\n continue;\n }\n return false;\n }\n return sawLine;\n}\n\nfunction slugify(s: string): string {\n const slug = s\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return slug || 'node';\n}\n\n// ---------------------------------------------------------------------------\n// Edge extraction\n// ---------------------------------------------------------------------------\n\ninterface EdgeCellInfo {\n arrow: ArrowDirection | null;\n bridgeLabel?: string;\n}\n\nfunction extractEdges(\n grid: string[][],\n mask: Uint8Array,\n perimeterOwners: Map<number, number[]>,\n boxes: ParsedBox[],\n warnings: string[],\n): { edges: AsciiDiagramEdge[]; edgeCells: Set<number> } {\n const H = grid.length;\n const W = H > 0 ? grid[0].length : 0;\n\n // -- Eligible cells: line/arrow chars outside the mask.\n const cells = new Map<number, EdgeCellInfo>();\n for (let r = 0; r < H; r++) {\n for (let c = 0; c < W; c++) {\n const idx = r * W + c;\n if (mask[idx]) continue;\n const ch = grid[r][c];\n const uni = arrowDirection(ch);\n if (uni) {\n cells.set(idx, { arrow: uni });\n continue;\n }\n const asc = asciiArrowDirection(ch);\n if (asc && asciiArrowGate(grid, r, c, asc)) {\n cells.set(idx, { arrow: asc });\n continue;\n }\n if (isLineChar(ch)) cells.set(idx, { arrow: null });\n }\n }\n\n // -- Bridges: `──label──` glue (label + interior spaces become cells).\n for (let r = 0; r < H; r++) {\n let c = 0;\n while (c < W) {\n const idx = r * W + c;\n if (!cells.has(idx) || !isHoriz(grid[r][c])) {\n c++;\n continue;\n }\n // End of this horizontal run.\n let runEnd = c;\n while (runEnd + 1 < W && cells.has(r * W + runEnd + 1) && isHoriz(grid[r][runEnd + 1])) {\n runEnd++;\n }\n // Candidate gap after the run.\n let g = runEnd + 1;\n let sawText = false;\n let failed = false;\n while (g < W && g - runEnd - 1 <= MAX_BRIDGE_GAP) {\n const gch = grid[r][g];\n const gidx = r * W + g;\n if (mask[gidx] || isVert(gch)) {\n failed = true;\n break;\n }\n if (isHoriz(gch)) break;\n if (isLineChar(gch) || arrowDirection(gch) !== null) {\n failed = true;\n break;\n }\n const asc = asciiArrowDirection(gch);\n if (asc && asciiArrowGate(grid, r, g, asc)) {\n failed = true;\n break;\n }\n if (gch !== ' ') sawText = true;\n g++;\n }\n if (\n !failed &&\n g < W &&\n g > runEnd + 1 &&\n sawText &&\n isHoriz(grid[r][g]) &&\n !mask[r * W + g]\n ) {\n const label = grid[r]\n .slice(runEnd + 1, g)\n .join('')\n .trim();\n for (let bc = runEnd + 1; bc < g; bc++) {\n cells.set(r * W + bc, { arrow: null, bridgeLabel: label });\n }\n c = g;\n } else {\n c = runEnd + 1;\n }\n }\n }\n\n // -- Connected components (4-connectivity), with cross cells (`┼`)\n // acting as PASS-THROUGH: at a cross, the vertical and horizontal runs\n // connect independently, so two edges crossing each other stay two\n // edges instead of merging into one four-armed blob. (ASCII `+` cannot\n // be disambiguated from a turn, so it stays fully connective.)\n const isCrossCell = (idx: number): boolean => CROSS_CHARS.has(grid[Math.floor(idx / W)][idx % W]);\n // State key = idx * 2 + channel (0 = horizontal, 1 = vertical); non-cross\n // cells always live on channel 0.\n const stateKey = (idx: number, channel: 0 | 1): number => idx * 2 + channel;\n const visited = new Set<number>();\n const components: number[][] = [];\n const seeds: Array<[number, 0 | 1]> = [];\n for (const idx of cells.keys()) {\n seeds.push([idx, 0]);\n if (isCrossCell(idx)) seeds.push([idx, 1]);\n }\n for (const [seedIdx, seedChannel] of seeds) {\n if (visited.has(stateKey(seedIdx, seedChannel))) continue;\n const componentCells = new Set<number>();\n const queue: Array<[number, 0 | 1]> = [[seedIdx, seedChannel]];\n visited.add(stateKey(seedIdx, seedChannel));\n while (queue.length > 0) {\n const [idx, channel] = queue.pop() as [number, 0 | 1];\n componentCells.add(idx);\n const r = Math.floor(idx / W);\n const c = idx % W;\n const neighbors: Array<[number, number]> =\n isCrossCell(idx) && channel === 1\n ? [\n [r - 1, c],\n [r + 1, c],\n ]\n : isCrossCell(idx)\n ? [\n [r, c - 1],\n [r, c + 1],\n ]\n : [\n [r - 1, c],\n [r + 1, c],\n [r, c - 1],\n [r, c + 1],\n ];\n for (const [nr, nc] of neighbors) {\n if (nr < 0 || nr >= H || nc < 0 || nc >= W) continue;\n const nidx = nr * W + nc;\n if (!cells.has(nidx)) continue;\n const nChannel: 0 | 1 = isCrossCell(nidx) ? (nr !== r ? 1 : 0) : 0;\n const key = stateKey(nidx, nChannel);\n if (!visited.has(key)) {\n visited.add(key);\n queue.push([nidx, nChannel]);\n }\n }\n }\n components.push([...componentCells].sort((a, b) => a - b));\n }\n components.sort((a, b) => a[0] - b[0]);\n\n // -- Component → edges.\n const edges: AsciiDiagramEdge[] = [];\n const seen = new Set<string>();\n let mergedParallel = false;\n const looseComponents = new Set<number>();\n const sideLabelCells = new Set<number>();\n\n for (const component of components) {\n const inComponent = new Set(component);\n // Endpoints: ≤1 neighbor within the component, plus every arrow cell.\n const endpoints: number[] = [];\n for (const idx of component) {\n const r = Math.floor(idx / W);\n const c = idx % W;\n let neighbors = 0;\n for (const [nr, nc] of [\n [r - 1, c],\n [r + 1, c],\n [r, c - 1],\n [r, c + 1],\n ]) {\n if (inComponent.has(nr * W + nc)) neighbors++;\n }\n const info = cells.get(idx) as EdgeCellInfo;\n if (neighbors <= 1 || info.arrow !== null) endpoints.push(idx);\n }\n\n // Attachments: endpoint adjacent (Chebyshev ≤ 1) to a box perimeter.\n interface Attachment {\n boxIdx: number;\n isArrowEnd: boolean;\n }\n const attachmentsByBox = new Map<number, Attachment>();\n let dangling = false;\n for (const idx of endpoints) {\n const r = Math.floor(idx / W);\n const c = idx % W;\n const info = cells.get(idx) as EdgeCellInfo;\n const boxIdx = snapEndpoint(r, c, info.arrow, perimeterOwners, boxes, W, H);\n if (boxIdx === null) {\n dangling = true;\n continue;\n }\n const existing = attachmentsByBox.get(boxIdx);\n if (existing) {\n existing.isArrowEnd = existing.isArrowEnd || info.arrow !== null;\n } else {\n attachmentsByBox.set(boxIdx, { boxIdx, isArrowEnd: info.arrow !== null });\n }\n }\n const nearestOwner = (r: number, c: number): number | null => {\n const owners = perimeterOwners.get(r * W + c) ?? [];\n if (owners.length === 0) return null;\n return [...owners].sort(\n (a, b) => boxes[a].r0 - boxes[b].r0 || boxes[a].c0 - boxes[b].c0 || a - b,\n )[0];\n };\n\n // Junction cells touching a perimeter are attachments too — the\n // `┌──┴──┐` bus-split shape connects to the box it branched from even\n // though the junction cell has 2+ neighbors and no arrowhead.\n for (const idx of component) {\n const r = Math.floor(idx / W);\n const c = idx % W;\n const ch = grid[r][c];\n if (!isJunction(ch) && !isPlus(ch)) continue;\n for (const [dr, dc] of [\n [-1, 0],\n [1, 0],\n [0, -1],\n [0, 1],\n ]) {\n const boxIdx = nearestOwner(r + dr, c + dc);\n if (boxIdx !== null && !attachmentsByBox.has(boxIdx)) {\n attachmentsByBox.set(boxIdx, { boxIdx, isArrowEnd: false });\n }\n }\n }\n\n // Arrow cells attach to the box on the side OPPOSITE the arrowhead:\n // a tight vertical stack (`└─┬─┘` / `▼` / `┌───┐`, boxes one row apart)\n // is a single arrow cell whose only endpoint snaps to the pointed box —\n // without this the source box is missed and the edge drops. Very common\n // in AI output.\n for (const idx of component) {\n const r = Math.floor(idx / W);\n const c = idx % W;\n const info = cells.get(idx) as EdgeCellInfo;\n if (info.arrow === null) continue;\n const [dr, dc] =\n info.arrow === 'down'\n ? [-1, 0]\n : info.arrow === 'up'\n ? [1, 0]\n : info.arrow === 'right'\n ? [0, -1]\n : [0, 1];\n const boxIdx = nearestOwner(r + dr, c + dc);\n if (boxIdx !== null && !attachmentsByBox.has(boxIdx)) {\n attachmentsByBox.set(boxIdx, { boxIdx, isArrowEnd: false });\n }\n }\n\n const attachments = [...attachmentsByBox.values()].sort(\n (a, b) => boxes[a.boxIdx].r0 - boxes[b.boxIdx].r0 || boxes[a.boxIdx].c0 - boxes[b.boxIdx].c0,\n );\n\n if (attachments.length === 0) {\n for (const idx of component) looseComponents.add(idx);\n warnings.push('dangling-edge');\n continue;\n }\n if (attachments.length === 1) {\n warnings.push('dangling-edge');\n continue;\n }\n if (dangling) warnings.push('dangling-edge');\n\n // Label: first bridge in the component, else a side label — a text run\n // sitting one space to the right of one of the component's vertical\n // cells (`│ born`), the way labels attach to vertical drops.\n const bridgeLabels: string[] = [];\n for (const idx of component) {\n const info = cells.get(idx) as EdgeCellInfo;\n if (info.bridgeLabel && !bridgeLabels.includes(info.bridgeLabel)) {\n bridgeLabels.push(info.bridgeLabel);\n }\n }\n // A label run stops at a box border, an arrow, or a structural line —\n // but an ASCII hyphen (`-`) inside a word (`on-fail`, `read-only`) is\n // label text, not a line, so it's allowed. The leading-space gate keeps\n // real lines (which abut the `│` directly) from being read as labels.\n const isLabelStop = (ch: string): boolean =>\n (isLineChar(ch) && ch !== '-') || arrowDirection(ch) !== null;\n const hasAlnum = (s: string): boolean => /[a-z0-9]/i.test(s);\n\n let label = bridgeLabels[0];\n if (!label) {\n // Try the right side (`│ born`) then the left side (`born │`) of\n // each vertical cell, topmost-first.\n outer: for (const idx of component) {\n const r = Math.floor(idx / W);\n const c = idx % W;\n if (!isVert(grid[r][c])) continue;\n if ((grid[r][c + 1] ?? '') === ' ') {\n let end = c + 2;\n let run = '';\n while (end < W) {\n const ch = grid[r][end];\n if (mask[r * W + end] || isLabelStop(ch)) break;\n if (ch === ' ' && (grid[r][end + 1] ?? ' ') === ' ') break;\n run += ch;\n end++;\n }\n const clean = run.trim().replace(/^-+|-+$/g, '');\n if (clean.length > 0 && clean.length <= MAX_BRIDGE_GAP && hasAlnum(clean)) {\n label = clean;\n for (let lc = c + 2; lc < end; lc++) sideLabelCells.add(r * W + lc);\n break outer;\n }\n }\n if ((grid[r][c - 1] ?? '') === ' ') {\n let start = c - 2;\n let run = '';\n while (start >= 0) {\n const ch = grid[r][start];\n if (mask[r * W + start] || isLabelStop(ch)) break;\n if (ch === ' ' && (grid[r][start - 1] ?? ' ') === ' ') break;\n run = ch + run;\n start--;\n }\n const clean = run.trim().replace(/^-+|-+$/g, '');\n if (clean.length > 0 && clean.length <= MAX_BRIDGE_GAP && hasAlnum(clean)) {\n label = clean;\n for (let lc = start + 1; lc <= c - 2; lc++) sideLabelCells.add(r * W + lc);\n break outer;\n }\n }\n }\n }\n if (bridgeLabels.length > 1) warnings.push('multiple-edge-labels');\n\n const pushEdge = (sourceIdx: number, targetIdx: number, directed: boolean) => {\n const edge: AsciiDiagramEdge = {\n source: boxes[sourceIdx].id,\n target: boxes[targetIdx].id,\n ...(label ? { label } : {}),\n directed,\n };\n const key = `${edge.source}|${edge.target}|${edge.directed}|${edge.label ?? ''}`;\n if (seen.has(key)) {\n mergedParallel = true;\n return;\n }\n seen.add(key);\n edges.push(edge);\n };\n\n const arrowEnds = attachments.filter((a) => a.isArrowEnd);\n const plainEnds = attachments.filter((a) => !a.isArrowEnd);\n\n if (attachments.length === 2) {\n const [a, b] = attachments;\n if (arrowEnds.length === 2) {\n pushEdge(a.boxIdx, b.boxIdx, true);\n pushEdge(b.boxIdx, a.boxIdx, true);\n } else if (arrowEnds.length === 1) {\n const target = arrowEnds[0];\n const source = a === target ? b : a;\n pushEdge(source.boxIdx, target.boxIdx, true);\n } else {\n pushEdge(a.boxIdx, b.boxIdx, false);\n }\n } else if (plainEnds.length === 1 && arrowEnds.length >= 1) {\n for (const target of arrowEnds) pushEdge(plainEnds[0].boxIdx, target.boxIdx, true); // fan-out\n } else if (arrowEnds.length === 1 && plainEnds.length >= 1) {\n for (const source of plainEnds) pushEdge(source.boxIdx, arrowEnds[0].boxIdx, true); // fan-in\n } else if (arrowEnds.length === 0) {\n warnings.push('ambiguous-bus');\n for (let i = 1; i < attachments.length; i++) {\n pushEdge(attachments[0].boxIdx, attachments[i].boxIdx, false);\n }\n } else {\n warnings.push('ambiguous-bus');\n for (const target of arrowEnds) {\n if (plainEnds.length > 0) pushEdge(plainEnds[0].boxIdx, target.boxIdx, true);\n }\n }\n }\n\n if (mergedParallel) warnings.push('parallel-edges-merged');\n\n edges.sort(\n (a, b) =>\n a.source.localeCompare(b.source) ||\n a.target.localeCompare(b.target) ||\n (a.label ?? '').localeCompare(b.label ?? ''),\n );\n\n // Edge cells for loose-text accounting: everything in a component that\n // produced (or tried to produce) an edge, minus fully-detached art,\n // plus consumed side-label runs.\n const edgeCells = new Set<number>();\n for (const component of components) {\n for (const idx of component) {\n if (!looseComponents.has(idx)) edgeCells.add(idx);\n }\n }\n for (const idx of sideLabelCells) edgeCells.add(idx);\n return { edges, edgeCells };\n}\n\n/** ASCII arrow chars count only when a matching line char sits behind them. */\nfunction asciiArrowGate(grid: string[][], r: number, c: number, dir: ArrowDirection): boolean {\n const behind =\n dir === 'down'\n ? grid[r - 1]?.[c]\n : dir === 'up'\n ? grid[r + 1]?.[c]\n : dir === 'right'\n ? grid[r]?.[c - 1]\n : grid[r]?.[c + 1];\n if (behind === undefined) return false;\n return dir === 'down' || dir === 'up' ? isVert(behind) : isHoriz(behind);\n}\n\n/**\n * Snap an endpoint cell to a box: prefer a perimeter cell in the arrow's\n * pointing direction, else the nearest (Chebyshev ≤ 1) perimeter owner,\n * ties broken by reading order.\n */\nfunction snapEndpoint(\n r: number,\n c: number,\n arrow: ArrowDirection | null,\n perimeterOwners: Map<number, number[]>,\n boxes: ParsedBox[],\n W: number,\n H: number,\n): number | null {\n const ownersAt = (rr: number, cc: number): number[] => {\n if (rr < 0 || rr >= H || cc < 0 || cc >= W) return [];\n return perimeterOwners.get(rr * W + cc) ?? [];\n };\n if (arrow) {\n const [dr, dc] =\n arrow === 'down' ? [1, 0] : arrow === 'up' ? [-1, 0] : arrow === 'right' ? [0, 1] : [0, -1];\n // Pointed cell at distance 1, then 2 (`--> ` with a space before the box).\n for (const dist of [1, 2]) {\n const pointed = ownersAt(r + dr * dist, c + dc * dist);\n if (pointed.length > 0) {\n // The pointed-at box: the one whose border faces the arrow.\n const sorted = [...pointed].sort((a, b) => {\n const da = directionDepth(boxes[a], r + dr * dist, c + dc * dist, arrow);\n const db = directionDepth(boxes[b], r + dr * dist, c + dc * dist, arrow);\n return db - da || a - b;\n });\n return sorted[0];\n }\n }\n }\n const candidates = new Map<number, number>(); // boxIdx → priority (0 = orthogonal, 1 = diagonal, 2 = one space away)\n for (const [dr, dc, priority] of [\n [-1, 0, 0],\n [1, 0, 0],\n [0, -1, 0],\n [0, 1, 0],\n [-1, -1, 1],\n [-1, 1, 1],\n [1, -1, 1],\n [1, 1, 1],\n [-2, 0, 2],\n [2, 0, 2],\n [0, -2, 2],\n [0, 2, 2],\n ]) {\n for (const owner of ownersAt(r + dr, c + dc)) {\n const existing = candidates.get(owner);\n if (existing === undefined || priority < existing) candidates.set(owner, priority);\n }\n }\n if (candidates.size === 0) return null;\n const ranked = [...candidates.entries()].sort(\n (a, b) =>\n a[1] - b[1] ||\n boxes[a[0]].r0 - boxes[b[0]].r0 ||\n boxes[a[0]].c0 - boxes[b[0]].c0 ||\n a[0] - b[0],\n );\n return ranked[0][0];\n}\n\n/** How deep the cell sits toward a box's interior along the arrow direction (higher = more pointed-at). */\nfunction directionDepth(box: Rect, r: number, c: number, arrow: ArrowDirection): number {\n switch (arrow) {\n case 'down':\n return box.r0 === r ? 1 : 0; // arrow points down at the box's TOP border\n case 'up':\n return box.r1 === r ? 1 : 0;\n case 'right':\n return box.c0 === c ? 1 : 0;\n case 'left':\n return box.c1 === c ? 1 : 0;\n }\n}\n\nfunction truncate(s: string, max: number): string {\n return s.length > max ? `${s.slice(0, max - 1)}…` : s;\n}\n","/**\n * ASCII diagram detection: is this fence content a box-and-line diagram?\n *\n * False positives are the expensive failure (they hide real code behind a\n * canvas / template); false negatives just leave a code block alone. Every\n * rejection path records a machine-greppable reason so the corpus tests\n * act as the contract for any future threshold tuning.\n */\n\nimport type { MarkdownCodeBlock } from '../../markdown/types.js';\nimport { parseAsciiDiagramWithStats } from './parse.js';\nimport type { AsciiDiagramDetection } from './types.js';\n\n/** Fence languages eligible for diagram detection (plus no language at all). */\nexport const ASCII_DIAGRAM_FENCE_LANGS: ReadonlySet<string> = new Set([\n 'text',\n 'txt',\n 'plaintext',\n 'plain',\n 'ascii',\n 'diagram',\n]);\n\nconst MAX_LINES = 400;\nconst MAX_COLS = 400;\nconst MIN_LINES = 3;\nconst MAX_LOOSE_RATIO = 0.25;\n\n/**\n * Box-drawing corners, junctions, and (Unicode) verticals — characters that\n * signal a box border leaked into a node's label, i.e. a mis-aligned parse.\n * ASCII `|`/`+`/`-` and the horizontal `─` are excluded: they occur in real\n * label text (`stdin | stdout`, `read-only`, `A + B`).\n */\nconst STRUCTURAL_IN_LABEL = /[│┃║┌┐└┘├┤┬┴┼╭╮╰╯┏┓┗┛╔╗╚╝┣┫┳┻╋╠╣╦╩╬╞╡╥╨╫╪]/;\n\nexport function isEligibleAsciiFenceLang(lang: string | null | undefined): boolean {\n if (lang === null || lang === undefined) return true;\n const normalized = lang.trim().toLowerCase();\n return normalized === '' || ASCII_DIAGRAM_FENCE_LANGS.has(normalized);\n}\n\n/**\n * True when the fence LANGUAGE is the explicit `diagram` tag — an author-set\n * \"this is a diagram\" marker that survives round-trips (the language class\n * round-trips; fence meta does not). Detection of a tagged fence is lenient\n * (≥1 box, no lattice rejector) so a degenerate diagram stays a diagram.\n */\nexport function isExplicitDiagramLang(lang: string | null | undefined): boolean {\n return typeof lang === 'string' && lang.trim().toLowerCase() === 'diagram';\n}\n\nexport interface DetectDiagramOptions {\n /** The fence is explicitly `diagram`-tagged: accept ≥1 box, skip rejectors. */\n explicit?: boolean;\n}\n\nexport function detectAsciiDiagram(\n text: string,\n opts: DetectDiagramOptions = {},\n): AsciiDiagramDetection {\n const explicit = opts.explicit === true;\n const reasons: string[] = [];\n\n // ---- Cheap prefilter (no parse) ----------------------------------------\n const lines = text.replace(/\\r\\n?/g, '\\n').split('\\n');\n if (lines.length < MIN_LINES) {\n return { isDiagram: false, reasons: [`too-few-lines(${lines.length})`] };\n }\n if (lines.length > MAX_LINES) {\n return { isDiagram: false, reasons: [`too-many-lines(${lines.length})`] };\n }\n let maxCols = 0;\n for (const line of lines) maxCols = Math.max(maxCols, line.length);\n if (maxCols > MAX_COLS) {\n return { isDiagram: false, reasons: [`too-wide(${maxCols})`] };\n }\n\n if (!explicit) {\n let tlCandidates = 0;\n for (const line of lines) {\n // Unicode TL corners, junction-started shared borders (`├──`), and\n // ASCII `+-` starts. Junctions over-count (file trees use `├──`), but\n // the prefilter only gates the full parse — box tracing decides.\n const unicodeMatches = line.match(/[┌╭┏╔]|[├┬┼┣┳╋╠╦╬][─━═]/gu);\n tlCandidates += unicodeMatches ? unicodeMatches.length : 0;\n const plusMatches = line.match(/\\+[-+]/g);\n tlCandidates += plusMatches ? plusMatches.length : 0;\n }\n if (tlCandidates < 2) {\n return { isDiagram: false, reasons: [`too-few-corner-candidates(${tlCandidates})`] };\n }\n }\n\n // Markdown/GFM table shape: mostly `| … |` rows plus a separator row.\n const nonBlank = lines.filter((l) => l.trim().length > 0);\n const pipeRows = nonBlank.filter((l) => /^\\s*\\|.*\\|\\s*$/.test(l)).length;\n const hasGfmSeparator = nonBlank.some((l) => /^\\s*\\|?[\\s:|-]+\\|?\\s*$/.test(l) && l.includes('-'));\n if (pipeRows > nonBlank.length / 2 && hasGfmSeparator) {\n return { isDiagram: false, reasons: ['markdown-table'] };\n }\n\n // ---- Full parse + acceptance -------------------------------------------\n const { diagram, stats } = parseAsciiDiagramWithStats(text);\n\n const minBoxes = explicit ? 1 : 2;\n if (diagram.nodes.length < minBoxes) {\n return { isDiagram: false, reasons: [`too-few-boxes(${diagram.nodes.length})`] };\n }\n\n // Garbled-label guard: a clean box label never contains box-drawing\n // corners/junctions/verticals — those only leak in when the label columns\n // are desynced from the box borders (hand-drawn art whose labels overflow\n // their boxes and shove every following column out of alignment row-to-row,\n // so no parser can map the text back to the boxes). When a meaningful share\n // of labels are corrupt this way, the \"diagram\" would render as garbage, so\n // decline detection and let the fence fall back to a faithful code block.\n const garbled = diagram.nodes.filter((n) => STRUCTURAL_IN_LABEL.test(n.label)).length;\n if (garbled > 0 && garbled >= diagram.nodes.length * 0.25) {\n return { isDiagram: false, reasons: [`garbled-labels(${garbled}/${diagram.nodes.length})`] };\n }\n\n if (!explicit) {\n // Table-lattice rejector: an edge-less shared-border grid of ≥2×2 boxes\n // is a psql/MySQL-style result table, not a diagram. Single-column\n // stacks still pass (a legitimate \"layer stack\" diagram).\n if (diagram.edges.length === 0 && diagram.nodes.length >= 4 && isLattice(diagram)) {\n return { isDiagram: false, reasons: ['table-lattice'] };\n }\n if (stats.totalNonSpaceCells > 0) {\n const looseRatio = stats.looseNonSpaceCells / stats.totalNonSpaceCells;\n if (looseRatio > MAX_LOOSE_RATIO) {\n return { isDiagram: false, reasons: [`loose-ratio(${looseRatio.toFixed(2)})`] };\n }\n }\n }\n\n reasons.push(`boxes(${diagram.nodes.length})`, `edges(${diagram.edges.length})`);\n if (explicit) reasons.push('explicit');\n return { isDiagram: true, diagram, reasons };\n}\n\n/** Convenience gate for pipeline callers: lang allowlist + content detection. */\nexport function isAsciiDiagramFence(node: MarkdownCodeBlock): boolean {\n if (node.type !== 'code') return false;\n if (!isEligibleAsciiFenceLang(node.lang)) return false;\n return detectAsciiDiagram(node.value, { explicit: isExplicitDiagramLang(node.lang) }).isDiagram;\n}\n\nfunction isLattice(diagram: {\n nodes: ReadonlyArray<{\n col: number;\n row: number;\n wCols: number;\n hRows: number;\n containerId?: string;\n }>;\n}): boolean {\n const leaves = diagram.nodes.filter((n) => !n.containerId);\n if (leaves.length < 4) return false;\n const rowBands = new Set(leaves.map((n) => n.row));\n const colBands = new Set(leaves.map((n) => n.col));\n if (rowBands.size < 2 || colBands.size < 2) return false;\n // Every box shares a border line with some other box.\n return leaves.every((a) =>\n leaves.some((b) => {\n if (a === b) return false;\n const aR1 = a.row + a.hRows - 1;\n const aC1 = a.col + a.wCols - 1;\n const bR1 = b.row + b.hRows - 1;\n const bC1 = b.col + b.wCols - 1;\n return a.row === bR1 || aR1 === b.row || a.col === bC1 || aC1 === b.col;\n }),\n );\n}\n","/**\n * Conservative parser for two-or-more-lane flow art whose last edge wraps\n * around the right margin. This dialect is common in AI-authored architecture\n * notes and sequence sketches:\n *\n * CLIENT KERNEL\n * ────── ──────\n * input ──► command ────► validate\n * ├─ invalid → rejected ─┐\n * surfaced ◄─────────────────────────────────────┘\n *\n * It is intentionally strict. Every nonblank row must be a heading,\n * underline, connector-only row, parenthetical continuation, or prose joined\n * by an explicit arrow. Accepted art is converted to the ordinary timeline\n * model, after which the canonical timeline renderer owns the authored form.\n */\n\nimport type {\n AsciiTimeline,\n AsciiTimelineEvent,\n AsciiTimelineLink,\n AsciiTimelineTrack,\n} from './types.js';\n\ninterface TextSegment {\n text: string;\n start: number;\n end: number;\n trackIndex: number;\n}\n\ninterface TrackBand {\n id: string;\n label: string;\n row: number;\n start: number;\n end: number;\n}\n\ninterface EventDraft {\n id: string;\n label: string;\n description?: string;\n trackIndex: number;\n order: number;\n}\n\ninterface LinkDraft {\n source: string;\n target: string;\n label?: string;\n}\n\ninterface PendingDescription {\n eventId: string;\n text: string;\n}\n\nconst UNDERLINE_RE = /[─━═-]{6,}/gu;\nconst FLOW_CHAR_RE = /[─━═│|►◄→←┌┐└┘├┤]/u;\nconst ARROW_RE = /[►◄→←]/u;\nconst LEFT_ARROW_RE = /[◄←]/u;\nconst RIGHT_ARROW_RE = /[►→]/u;\nconst CONNECTOR_ONLY_RE = /^[\\s─━═│|►◄→←┌┐└┘├┤]+$/u;\nconst HEADER_RE = /^[A-Z][A-Z0-9 _/-]*(?:\\s+\\([^)]*\\))?$/u;\n\n/** Parse the wrapped-flow dialect, or return null without claiming the art. */\nexport function parseWrappedFlowTimeline(text: string): AsciiTimeline | null {\n const lines = text.replace(/\\r\\n?/g, '\\n').split('\\n');\n const header = findHeader(lines);\n if (!header || header.tracks.length < 2) return null;\n\n const drafts: EventDraft[] = [];\n const links: LinkDraft[] = [];\n const usedIds = new Set<string>();\n const lastByTrack = new Map<number, string>();\n let pendingDescription: PendingDescription | null = null;\n let activeBranchRoot: string | null = null;\n let wrapSource: string | null = null;\n let arrowCount = 0;\n let hasLeftArrow = false;\n let hasRightArrow = false;\n let hasWrapTop = false;\n let hasWrapBottom = false;\n\n const addEvent = (segment: TextSegment): EventDraft => {\n const label = normalizeText(segment.text);\n const id = uniqueId(label, usedIds);\n const draft: EventDraft = {\n id,\n label,\n trackIndex: segment.trackIndex,\n order: drafts.length,\n };\n drafts.push(draft);\n return draft;\n };\n const addLink = (source: string | undefined, target: string | undefined, label?: string) => {\n if (!source || !target || source === target) return;\n if (\n links.some((link) => link.source === source && link.target === target && link.label === label)\n ) {\n return;\n }\n links.push({ source, target, ...(label ? { label } : {}) });\n };\n\n for (let row = header.underlineRow + 1; row < lines.length; row++) {\n const original = lines[row];\n if (!original.trim()) continue;\n if (CONNECTOR_ONLY_RE.test(original)) {\n hasWrapTop ||= original.includes('┐');\n hasWrapBottom ||= original.includes('┘');\n continue;\n }\n\n const trimmed = original.trim();\n if (trimmed.startsWith('(') && !ARROW_RE.test(original)) {\n const trackIndex = trackIndexAt(header.tracks, firstContentColumn(original));\n const eventId = lastByTrack.get(trackIndex);\n if (!eventId) return null;\n pendingDescription = {\n eventId,\n text: normalizeText(original.replace(/[│|]+\\s*$/u, '')),\n };\n continue;\n }\n\n let line = original;\n let continuationTarget: string | null = null;\n if (pendingDescription) {\n const firstArrow = firstArrowColumn(line);\n if (firstArrow < 0) return null;\n const continuation = normalizeText(Array.from(line).slice(0, firstArrow).join(''));\n const event = drafts.find((candidate) => candidate.id === pendingDescription?.eventId);\n if (!event) return null;\n event.description = normalizeText(`${pendingDescription.text} ${continuation}`);\n continuationTarget = event.id;\n line = `${' '.repeat(firstArrow)}${Array.from(line).slice(firstArrow).join('')}`;\n pendingDescription = null;\n }\n\n const segments = extractSegments(line, header.tracks);\n if (segments.length === 0) return null;\n if (segments.some((segment) => !/[\\p{L}\\p{N}]/u.test(segment.text))) return null;\n\n const previousByTrack = new Map(lastByTrack);\n const events = segments.map(addEvent);\n const directions: Array<'left' | 'right' | null> = [];\n for (let index = 0; index < segments.length - 1; index++) {\n const between = Array.from(line)\n .slice(segments[index].end + 1, segments[index + 1].start)\n .join('');\n const direction = LEFT_ARROW_RE.test(between)\n ? 'left'\n : RIGHT_ARROW_RE.test(between)\n ? 'right'\n : null;\n directions.push(direction);\n if (direction) arrowCount++;\n hasLeftArrow ||= direction === 'left';\n hasRightArrow ||= direction === 'right';\n if (direction === 'left') addLink(events[index + 1].id, events[index].id);\n if (direction === 'right') addLink(events[index].id, events[index + 1].id);\n }\n\n const leadingBranch = /^[\\s│|]*[├└]/u.exec(original)?.[0] ?? '';\n if (leadingBranch) {\n if (!activeBranchRoot) {\n activeBranchRoot = previousByTrack.get(events[0].trackIndex) ?? null;\n }\n addLink(activeBranchRoot ?? undefined, events[0].id);\n if (leadingBranch.includes('└')) activeBranchRoot = null;\n } else {\n activeBranchRoot = null;\n }\n\n const allLeft = directions.length > 0 && directions.every((direction) => direction === 'left');\n const ordered = allLeft ? [...events].reverse() : events;\n const first = ordered[0];\n if (!leadingBranch && !original.includes('┘')) {\n addLink(previousByTrack.get(first.trackIndex), first.id);\n }\n if (continuationTarget) addLink(ordered[ordered.length - 1]?.id, continuationTarget);\n\n for (const event of ordered) lastByTrack.set(event.trackIndex, event.id);\n\n if (original.includes('┐')) {\n hasWrapTop = true;\n wrapSource = events[events.length - 1]?.id ?? null;\n }\n if (original.includes('┘')) {\n hasWrapBottom = true;\n const target = allLeft ? events[0]?.id : events[events.length - 1]?.id;\n addLink(wrapSource ?? undefined, target);\n }\n }\n\n if (pendingDescription || drafts.length < 6) return null;\n if (arrowCount < 4 || !hasLeftArrow || !hasRightArrow || !hasWrapTop || !hasWrapBottom) {\n return null;\n }\n if (!hasCrossTrackLink(drafts, links)) return null;\n\n const columns = assignColumns(drafts, links);\n const endColumn = Math.max(10, ...columns.values());\n const tracks: AsciiTimelineTrack[] = header.tracks.map((band, trackIndex) => {\n const trackEvents = drafts\n .filter((event) => event.trackIndex === trackIndex)\n .sort(\n (left, right) =>\n (columns.get(left.id) ?? 0) - (columns.get(right.id) ?? 0) || left.order - right.order,\n );\n let previousColumn = -1;\n const events: AsciiTimelineEvent[] = trackEvents.map((event, index) => {\n const ideal = columns.get(event.id) ?? index * 10;\n const column = Math.max(previousColumn + 1, ideal);\n previousColumn = column;\n return {\n id: event.id,\n label: event.label,\n ...(event.description ? { description: event.description } : {}),\n column,\n side: index % 2 === 0 ? 'above' : 'below',\n marker: 'filled',\n };\n });\n return {\n id: band.id,\n label: band.label,\n row: band.row,\n startColumn: 0,\n endColumn,\n events,\n };\n });\n const width = Math.max(0, ...lines.map((line) => Array.from(line).length));\n links.sort(\n (left, right) =>\n left.source.localeCompare(right.source) ||\n left.target.localeCompare(right.target) ||\n (left.label ?? '').localeCompare(right.label ?? ''),\n );\n return {\n tracks,\n links: links satisfies AsciiTimelineLink[],\n width,\n height: lines.length,\n style: 'unicode',\n warnings: [],\n };\n}\n\n/** High-confidence predicate used by the editor's lossless rewrite gate. */\nexport function isWrappedFlowTimelineSource(text: string): boolean {\n return parseWrappedFlowTimeline(text) !== null;\n}\n\nfunction findHeader(\n lines: readonly string[],\n): { tracks: TrackBand[]; underlineRow: number } | null {\n for (let row = 1; row < Math.min(lines.length, 5); row++) {\n const runs = Array.from(lines[row].matchAll(UNDERLINE_RE)).map((match) => ({\n start: match.index,\n end: (match.index ?? 0) + Array.from(match[0]).length - 1,\n }));\n if (runs.length < 2) continue;\n const headings = splitHeader(lines[row - 1]);\n if (\n headings.length !== runs.length ||\n headings.some((heading) => !HEADER_RE.test(heading.text))\n ) {\n continue;\n }\n const tracks = runs.map((run, index): TrackBand => {\n const heading = headings[index];\n const base = heading.text.replace(/\\s+\\([^)]*\\)\\s*$/u, '').trim();\n return {\n id: safeId(base),\n label: heading.text,\n row: row - 1,\n start: run.start,\n end: run.end,\n };\n });\n return { tracks, underlineRow: row };\n }\n return null;\n}\n\nfunction splitHeader(line: string): Array<{ text: string; start: number; end: number }> {\n const chars = Array.from(line);\n const segments: Array<{ text: string; start: number; end: number }> = [];\n let start = -1;\n let spaces = 0;\n for (let index = 0; index <= chars.length; index++) {\n const char = chars[index];\n if (char === ' ') {\n spaces++;\n if (start >= 0 && spaces >= 3) {\n const end = index - spaces;\n const text = chars\n .slice(start, end + 1)\n .join('')\n .trim();\n if (text) segments.push({ text, start, end });\n start = -1;\n }\n continue;\n }\n spaces = 0;\n if (char !== undefined && start < 0) start = index;\n if (char === undefined && start >= 0) {\n const text = chars.slice(start).join('').trim();\n if (text) segments.push({ text, start, end: chars.length - 1 });\n }\n }\n return segments;\n}\n\nfunction extractSegments(line: string, tracks: readonly TrackBand[]): TextSegment[] {\n const chars = Array.from(line);\n const segments: TextSegment[] = [];\n let start = -1;\n for (let index = 0; index <= chars.length; index++) {\n const structural = index === chars.length || FLOW_CHAR_RE.test(chars[index] ?? '');\n if (!structural && start < 0) start = index;\n if (!structural || start < 0) continue;\n const raw = chars.slice(start, index).join('');\n const leading = raw.length - raw.trimStart().length;\n const text = normalizeText(raw);\n if (text) {\n const segmentStart = start + leading;\n const segmentEnd = segmentStart + Array.from(text).length - 1;\n segments.push({\n text,\n start: segmentStart,\n end: segmentEnd,\n trackIndex: trackIndexAt(tracks, segmentStart),\n });\n }\n start = -1;\n }\n return segments;\n}\n\nfunction trackIndexAt(tracks: readonly TrackBand[], column: number): number {\n for (let index = 1; index < tracks.length; index++) {\n if (column < tracks[index].start) return index - 1;\n }\n return tracks.length - 1;\n}\n\nfunction firstContentColumn(line: string): number {\n const chars = Array.from(line);\n const index = chars.findIndex((char) => /[\\p{L}\\p{N}(]/u.test(char));\n return Math.max(0, index);\n}\n\nfunction firstArrowColumn(line: string): number {\n return Array.from(line).findIndex((char) => ARROW_RE.test(char));\n}\n\nfunction normalizeText(value: string): string {\n return value\n .normalize('NFC')\n .replace(/^[\\s:]+|[\\s:]+$/gu, '')\n .replace(/\\s+/gu, ' ')\n .trim();\n}\n\nfunction safeId(value: string): string {\n return (\n value\n .normalize('NFC')\n .toLowerCase()\n .replace(/[^a-z0-9_.~-]+/gu, '-')\n .replace(/^-+|-+$/gu, '') || 'event'\n );\n}\n\nfunction uniqueId(label: string, used: Set<string>): string {\n const base = safeId(label);\n if (!used.has(base)) {\n used.add(base);\n return base;\n }\n let suffix = 2;\n while (used.has(`${base}-${suffix}`)) suffix++;\n const id = `${base}-${suffix}`;\n used.add(id);\n return id;\n}\n\nfunction hasCrossTrackLink(events: readonly EventDraft[], links: readonly LinkDraft[]): boolean {\n const trackById = new Map(events.map((event) => [event.id, event.trackIndex]));\n return links.some((link) => trackById.get(link.source) !== trackById.get(link.target));\n}\n\nfunction assignColumns(\n events: readonly EventDraft[],\n links: readonly LinkDraft[],\n): Map<string, number> {\n const outgoing = new Map<string, string[]>();\n const indegree = new Map(events.map((event) => [event.id, 0]));\n for (const link of links) {\n outgoing.set(link.source, [...(outgoing.get(link.source) ?? []), link.target]);\n indegree.set(link.target, (indegree.get(link.target) ?? 0) + 1);\n }\n const ranks = new Map(events.map((event) => [event.id, 0]));\n const queue = events.filter((event) => indegree.get(event.id) === 0).map((event) => event.id);\n let visited = 0;\n while (queue.length > 0) {\n const source = queue.shift() as string;\n visited++;\n for (const target of outgoing.get(source) ?? []) {\n ranks.set(target, Math.max(ranks.get(target) ?? 0, (ranks.get(source) ?? 0) + 1));\n const next = (indegree.get(target) ?? 1) - 1;\n indegree.set(target, next);\n if (next === 0) queue.push(target);\n }\n }\n if (visited < events.length) {\n for (const event of events) ranks.set(event.id, event.order);\n }\n return new Map(Array.from(ranks, ([id, rank]) => [id, rank * 10]));\n}\n","/** ASCII timeline parser: horizontal tracks + point/callout art -> model. */\n\nimport type {\n AsciiTimeline,\n AsciiTimelineEvent,\n AsciiTimelineLink,\n AsciiTimelineMarker,\n AsciiTimelineSide,\n AsciiTimelineStyle,\n AsciiTimelineTrack,\n} from './types.js';\nimport { parseWrappedFlowTimeline } from './wrappedFlow.js';\n\nconst STRONG_MARKERS = new Set(['●', '○', '◉', '◆', '◇', '•']);\nconst ASCII_MARKERS = new Set(['*', 'o', 'O']);\nconst HORIZONTAL = new Set(['─', '━', '═', '╌', '╍', '┄', '┅', '┈', '┉', '-']);\nconst END_ARROWS = new Set(['►', '▶', '▷', '→', '>']);\nconst POINTERS = new Set(['▲', '△', '▼', '▽', '^', 'v']);\nconst CONNECTOR_ANCHORS = new Set(['└', '┌', '├', '┬', '┘', '┐', '╰', '╭', '╯', '╮']);\n\nexport interface AsciiTimelineStats {\n axisLines: number;\n markerCount: number;\n strongMarkerCount: number;\n horizontalChars: number;\n pointerCount: number;\n branchDeclarations: number;\n /** True for high-confidence multi-lane flow art with a return edge. */\n wrappedFlow?: boolean;\n}\n\ninterface AxisAnalysis {\n row: number;\n id?: string;\n startColumn: number;\n endColumn: number;\n markerColumns: number[];\n markerGlyphs: string[];\n inline: Array<{\n label?: string;\n description?: string;\n id?: string;\n column?: number;\n side?: AsciiTimelineSide;\n descriptionSide?: AsciiTimelineSide;\n callout?: boolean;\n }>;\n label?: string;\n endLabel?: string;\n horizontalChars: number;\n strongMarkerCount: number;\n}\n\ninterface PendingBranch {\n source: string;\n target: string;\n label?: string;\n}\n\ninterface Segment {\n start: number;\n end: number;\n text: string;\n}\n\nexport function parseAsciiTimeline(text: string): AsciiTimeline {\n return parseAsciiTimelineWithStats(text).timeline;\n}\n\nexport function parseAsciiTimelineWithStats(text: string): {\n timeline: AsciiTimeline;\n stats: AsciiTimelineStats;\n} {\n const lines = text.replace(/\\r\\n?/g, '\\n').split('\\n');\n const width = Math.max(0, ...lines.map((line) => Array.from(line).length));\n const wrappedFlow = parseWrappedFlowTimeline(text);\n if (wrappedFlow) {\n const markerCount = wrappedFlow.tracks.reduce((sum, track) => sum + track.events.length, 0);\n return {\n timeline: wrappedFlow,\n stats: {\n axisLines: wrappedFlow.tracks.length,\n markerCount,\n strongMarkerCount: markerCount,\n horizontalChars: Array.from(text).filter((char) => HORIZONTAL.has(char)).length,\n pointerCount: 0,\n branchDeclarations: wrappedFlow.links.length,\n wrappedFlow: true,\n },\n };\n }\n const style = detectStyle(lines);\n const pendingBranches: PendingBranch[] = [];\n const axes: AxisAnalysis[] = [];\n\n for (let row = 0; row < lines.length; row++) {\n const branch = parseBranchDeclaration(lines[row]);\n if (branch) {\n pendingBranches.push(branch);\n continue;\n }\n const axis = analyzeAxisLine(lines[row], row, style);\n if (axis) {\n axes.push(axis);\n continue;\n }\n const cadence = analyzeCadenceLine(lines[row], row);\n if (cadence) axes.push(cadence);\n }\n\n const tracks: AsciiTimelineTrack[] = axes.map((axis, index) => ({\n id: axis.id ?? slug(axis.label || `track-${index + 1}`),\n ...(axis.label ? { label: axis.label } : {}),\n ...(axis.endLabel ? { endLabel: axis.endLabel } : {}),\n row: axis.row,\n startColumn: axis.startColumn,\n endColumn: axis.endColumn,\n events: axis.markerColumns.map((markerColumn, eventIndex) => {\n const inline = axis.inline[eventIndex];\n return {\n id: inline.id ?? '',\n label: inline.label ?? '',\n ...(inline.description ? { description: inline.description } : {}),\n column: inline.column ?? markerColumn,\n ...(inline.side ? { side: inline.side } : {}),\n ...(inline.descriptionSide ? { descriptionSide: inline.descriptionSide } : {}),\n ...(inline.callout === false ? { callout: false } : {}),\n marker: markerKind(axis.markerGlyphs[eventIndex]),\n } satisfies AsciiTimelineEvent;\n }),\n }));\n\n // Labels immediately above an axis are the common authored form. Match by\n // source column, conservatively: a prose prefix (\"kernel ticks:\") must not\n // steal the first event just because it shares the same line.\n for (let i = 0; i < axes.length; i++) {\n const axis = axes[i];\n const track = tracks[i];\n const aboveRow = previousNonBlankRow(lines, axis.row - 1);\n if (aboveRow >= 0 && !axes.some((candidate) => candidate.row === aboveRow)) {\n const segments = splitPlainSegments(lines[aboveRow]);\n const pointEvents = track.events.filter((event) => !event.label);\n const aligned = alignedEventSegments(segments, pointEvents);\n if (aligned) {\n for (let eventIndex = 0; eventIndex < pointEvents.length; eventIndex++) {\n pointEvents[eventIndex].label = cleanProseText(aligned[eventIndex].text);\n pointEvents[eventIndex].side = 'above';\n }\n // A prose prefix ending in `:` on the label row is a stronger track\n // name than a generic axis suffix such as \"sim time\".\n const firstAligned = segments.indexOf(aligned[0]);\n const prefix = firstAligned > 0 ? segments[firstAligned - 1] : undefined;\n if (prefix?.text.trim().endsWith(':')) {\n track.label = stripTrailingColon(prefix.text);\n track.id = slug(track.label);\n }\n }\n for (const event of track.events) {\n if (event.label) continue;\n const gap = nearestEventGap(track.events, event.column);\n const threshold = Math.max(3, Math.min(8, gap * 0.38));\n const nearest = nearestSegment(segments, event.column, threshold);\n if (!nearest) continue;\n event.label = cleanProseText(nearest.text);\n event.side = 'above';\n }\n }\n }\n\n // Anchored pointers (▲/▼) are fractional events: unlike milestone dots,\n // they may intentionally sit between snapshots/ticks.\n let pointerCount = 0;\n for (let row = 0; row < lines.length; row++) {\n if (axes.some((axis) => axis.row === row)) continue;\n const chars = Array.from(lines[row]);\n const pointerColumns = chars\n .map((char, column) => ({ char, column }))\n .filter(({ column }) => isPointerAt(chars, column))\n .map(({ column }) => column);\n for (let pointerIndex = 0; pointerIndex < pointerColumns.length; pointerIndex++) {\n const column = pointerColumns[pointerIndex];\n // Canonical pointer callouts carry semantic `column=` metadata while\n // their glyph remains aligned to the physical marker on the pretty\n // rail. Prefer an as-yet-unclaimed marker at that source column before\n // falling back to the general nearest-track heuristic.\n const track =\n nearestUnclaimedMarkerTrack(tracks, row, column) ?? nearestTrack(tracks, row, column);\n if (!track) continue;\n pointerCount++;\n const nextPointer = pointerColumns[pointerIndex + 1] ?? chars.length;\n const after = cleanProseText(chars.slice(column + 1, nextPointer).join(''));\n // A prose prefix belongs only to the first pointer on a row. Subsequent\n // pointers own the text to their right, preventing `▲ A ▲ B` from\n // contaminating both labels with the whole row.\n const prefix = pointerIndex === 0 ? cleanProseText(chars.slice(0, column).join('')) : '';\n const parsed = /\\{[^{}]*#[^{}\\s]+[^{}]*\\}\\s*$/u.test(after)\n ? parseInlineEvent(after)\n : { label: after || undefined };\n const label =\n stripTrailingColon(prefix) || parsed.label || after || `Event ${track.events.length + 1}`;\n const description = prefix && after ? after : parsed.description;\n const side: AsciiTimelineSide = parsed.side ?? (row < track.row ? 'above' : 'below');\n const existing =\n track.events.find((event) => !event.id && Math.abs(event.column - column) <= 1) ??\n track.events.find(\n (event) => event.callout !== false && Math.abs(event.column - column) <= 1,\n );\n if (existing) {\n if (parsed.id) existing.id = parsed.id;\n if (parsed.column !== undefined) existing.column = parsed.column;\n if (!existing.label) existing.label = label;\n if (parsed.label) existing.label = parsed.label;\n if (description && !existing.description) existing.description = description;\n if (parsed.description) existing.description = parsed.description;\n if (parsed.descriptionSide) existing.descriptionSide = parsed.descriptionSide;\n else if (description && !parsed.id) existing.descriptionSide ??= side;\n if (parsed.callout !== undefined) existing.callout = parsed.callout;\n existing.side = side;\n } else {\n track.events.push({\n id: parsed.id ?? '',\n label,\n ...(description ? { description } : {}),\n column: parsed.column ?? column,\n side,\n ...(parsed.descriptionSide\n ? { descriptionSide: parsed.descriptionSide }\n : description && !parsed.id\n ? { descriptionSide: side }\n : {}),\n ...(parsed.callout !== undefined ? { callout: parsed.callout } : {}),\n marker: 'hollow',\n });\n }\n }\n }\n\n // Elbow-led callouts (`└─Δ28`, `└─ interpolate ...`) attach descriptions\n // to the closest point on the closest track. This covers interval labels\n // and multi-line explanatory callouts in the motivating sample.\n for (let row = 0; row < lines.length; row++) {\n if (axes.some((axis) => axis.row === row)) continue;\n const callouts = extractConnectorCallouts(lines[row]);\n const prefix =\n callouts.length > 0\n ? cleanProseText(Array.from(lines[row]).slice(0, callouts[0].start).join(''))\n : '';\n for (let calloutIndex = 0; calloutIndex < callouts.length; calloutIndex++) {\n const callout = callouts[calloutIndex];\n const track = nearestTrack(tracks, row, callout.start);\n if (!track || track.events.length === 0) continue;\n const event = nearestEvent(track.events, callout.start);\n if (!event) continue;\n const calloutText = cleanProseText(callout.text);\n const cleaned = calloutIndex === 0 && prefix ? `${prefix} ${calloutText}` : calloutText;\n if (!cleaned || cleaned === event.label) continue;\n if (event.callout === false) {\n // A cadence point becomes a real annotated event when the author\n // attaches an elbow callout to it; leaving `callout:false` would make\n // the template silently hide that authored text.\n event.callout = true;\n event.label = cleaned;\n event.side = row < track.row ? 'above' : 'below';\n continue;\n }\n event.description = event.description ? `${event.description} ${cleaned}` : cleaned;\n event.descriptionSide ??= row < track.row ? 'above' : 'below';\n event.side ??= row < track.row ? 'above' : 'below';\n }\n }\n\n const warnings: string[] = [];\n const usedTrackIds = new Map<string, number>();\n for (const track of tracks) track.id = dedupe(track.id, usedTrackIds);\n\n // Finalize ids only after labels/callouts have been associated.\n const usedEventIds = new Map<string, number>();\n for (const track of tracks) {\n track.events.sort((a, b) => a.column - b.column);\n for (let i = 0; i < track.events.length; i++) {\n const event = track.events[i];\n if (!event.label) {\n event.label = `Event ${i + 1}`;\n warnings.push(`unlabeled-event(${track.id}:${event.column})`);\n }\n event.id = dedupe(event.id || slug(event.label), usedEventIds);\n event.side ??= i % 2 === 0 ? 'above' : 'below';\n }\n }\n\n const eventIds = new Set(tracks.flatMap((track) => track.events.map((event) => event.id)));\n const labelToId = new Map<string, string>();\n for (const track of tracks) {\n for (const event of track.events) {\n labelToId.set(slug(event.label), event.id);\n labelToId.set(event.id, event.id);\n }\n }\n const links: AsciiTimelineLink[] = [];\n for (const branch of pendingBranches) {\n const source = labelToId.get(slug(branch.source)) ?? branch.source;\n const target = labelToId.get(slug(branch.target)) ?? branch.target;\n if (!eventIds.has(source) || !eventIds.has(target)) {\n warnings.push(`unresolved-link(${branch.source}->${branch.target})`);\n continue;\n }\n links.push({ source, target, ...(branch.label ? { label: branch.label } : {}) });\n }\n\n const stats: AsciiTimelineStats = {\n axisLines: axes.length,\n markerCount: axes.reduce((sum, axis) => sum + axis.markerColumns.length, 0),\n strongMarkerCount: axes.reduce((sum, axis) => sum + axis.strongMarkerCount, 0),\n horizontalChars: axes.reduce((sum, axis) => sum + axis.horizontalChars, 0),\n pointerCount,\n branchDeclarations: pendingBranches.length,\n wrappedFlow: false,\n };\n\n return {\n timeline: { tracks, links, width, height: lines.length, style, warnings },\n stats,\n };\n}\n\n/**\n * Many terminal timelines put labels at a consistent offset from every dot\n * (the motivating sample uses +6 columns), rather than centering them. When\n * the last N text segments have one stable offset, pair them in order.\n */\nfunction alignedEventSegments(\n segments: readonly Segment[],\n events: readonly AsciiTimelineEvent[],\n): Segment[] | undefined {\n if (events.length < 2 || segments.length < events.length) return undefined;\n const candidates = segments.slice(-events.length);\n if (candidates.some((segment) => cleanCalloutText(segment.text).length > 40)) return undefined;\n const offsets = candidates.map(\n (segment, index) => (segment.start + segment.end) / 2 - events[index].column,\n );\n const spread = Math.max(...offsets) - Math.min(...offsets);\n return spread <= 3 ? [...candidates] : undefined;\n}\n\nfunction analyzeAxisLine(\n line: string,\n row: number,\n style: AsciiTimelineStyle,\n): AxisAnalysis | null {\n const chars = Array.from(line);\n const markerColumns: number[] = [];\n const markerGlyphs: string[] = [];\n let horizontalChars = 0;\n let strongMarkerCount = 0;\n for (let i = 0; i < chars.length; i++) {\n const ch = chars[i];\n if (HORIZONTAL.has(ch)) horizontalChars++;\n if (isMarkerAt(chars, i, style)) {\n markerColumns.push(i);\n markerGlyphs.push(ch);\n if (STRONG_MARKERS.has(ch)) strongMarkerCount++;\n }\n }\n if (markerColumns.length === 0 || horizontalChars < 2) return null;\n\n const firstMarker = markerColumns[0];\n const colon = chars.slice(0, firstMarker).lastIndexOf(':');\n let startColumn: number;\n if (colon >= 0) {\n startColumn = colon + 1;\n while (chars[startColumn] === ' ') startColumn++;\n } else {\n let i = firstMarker - 1;\n while (i >= 0 && (HORIZONTAL.has(chars[i]) || chars[i] === ' ')) i--;\n startColumn = i + 1;\n while (chars[startColumn] === ' ') startColumn++;\n }\n\n let endColumn = markerColumns[markerColumns.length - 1];\n // Inline prose may contain `>` / `->`. A track terminator is structural\n // only when it follows a rail (allowing spaces between the rail and arrow).\n // Search directly from the last marker: brace-delimited prose may legally\n // occur in an end label, so a blind `lastIndexOf('}')` is not an attrs gate.\n const arrowSearchStart = endColumn + 1;\n const arrowColumn = chars.findIndex(\n (ch, index) =>\n index >= arrowSearchStart &&\n END_ARROWS.has(ch) &&\n hasRailBefore(chars, index, ch === '>' ? 3 : 2),\n );\n let payloadEndExclusive: number;\n if (arrowColumn >= 0) {\n endColumn = arrowColumn;\n // Do not feed the structural arrow into the event payload parser. This\n // lets internal prose arrows survive untouched.\n payloadEndExclusive = arrowColumn;\n } else {\n // With no structural arrow, all trailing prose belongs to the last event.\n const lastNonSpace = findLastNonSpace(chars);\n endColumn = Math.max(endColumn, lastNonSpace);\n payloadEndExclusive = endColumn + 1;\n }\n\n const prefix = parseTrackPrefix(stripTrailingColon(chars.slice(0, startColumn).join('').trim()));\n const suffix = cleanProseText(chars.slice(endColumn + 1).join(''));\n const label = prefix.label;\n const inline = markerColumns.map((column, index) => {\n const next = index + 1 < markerColumns.length ? markerColumns[index + 1] : payloadEndExclusive;\n return parseInlineEvent(chars.slice(column + 1, next).join(''));\n });\n\n return {\n row,\n ...(prefix.id ? { id: prefix.id } : {}),\n startColumn: prefix.startColumn ?? startColumn,\n endColumn: prefix.endColumn ?? Math.max(endColumn, startColumn + 1),\n markerColumns,\n markerGlyphs,\n inline,\n ...(label ? { label } : {}),\n ...(suffix ? { endLabel: suffix } : {}),\n horizontalChars,\n strongMarkerCount,\n };\n}\n\n/**\n * Recognize dense cadence rows such as\n * `client frames (120 Hz): f f f f f f`. They are timelines without an\n * authored rail: every repeated one-character token is a hollow point, while\n * `callout: false` keeps the visual timeline from labeling every frame.\n */\nfunction analyzeCadenceLine(line: string, row: number): AxisAnalysis | null {\n const chars = Array.from(line);\n const colon = chars.indexOf(':');\n if (colon < 0) return null;\n const label = chars.slice(0, colon).join('').trim();\n if (!label) return null;\n\n const tokens: Array<{ value: string; column: number }> = [];\n let index = colon + 1;\n while (index < chars.length) {\n while (index < chars.length && /\\s/u.test(chars[index])) index++;\n if (index >= chars.length) break;\n const start = index;\n while (index < chars.length && !/\\s/u.test(chars[index])) index++;\n tokens.push({ value: chars.slice(start, index).join(''), column: start });\n }\n if (\n tokens.length < 4 ||\n tokens[0].value.length !== 1 ||\n tokens.some((token) => token.value !== tokens[0].value)\n ) {\n return null;\n }\n\n return {\n row,\n startColumn: tokens[0].column,\n endColumn: tokens[tokens.length - 1].column,\n markerColumns: tokens.map((token) => token.column),\n markerGlyphs: tokens.map(() => '○'),\n inline: tokens.map((token, tokenIndex) => ({\n label: token.value,\n id: `${slug(label)}-${tokenIndex + 1}`,\n column: token.column,\n callout: false,\n })),\n label,\n horizontalChars: 0,\n strongMarkerCount: 0,\n };\n}\n\nfunction parseInlineEvent(raw: string): {\n label?: string;\n description?: string;\n id?: string;\n column?: number;\n side?: AsciiTimelineSide;\n descriptionSide?: AsciiTimelineSide;\n callout?: boolean;\n} {\n // Separator rails only have structural meaning at the payload edges.\n // Internal prose such as `release--candidate` and `A > B` is content.\n let text = stripEdgeRails(raw).replace(/\\s+/g, ' ').trim();\n if (!text) return {};\n\n let id: string | undefined;\n let column: number | undefined;\n let side: AsciiTimelineSide | undefined;\n let descriptionSide: AsciiTimelineSide | undefined;\n let callout: boolean | undefined;\n const attrs = /\\{([^{}]+)\\}\\s*$/.exec(text);\n if (attrs) {\n let recognized = false;\n for (const token of attrs[1].trim().split(/\\s+/)) {\n if (token.startsWith('#') && token.length > 1) {\n id = token.slice(1);\n recognized = true;\n } else if (token === 'side=above') {\n side = 'above';\n recognized = true;\n } else if (token === 'side=below') {\n side = 'below';\n recognized = true;\n } else if (token === 'descriptionSide=above') {\n descriptionSide = 'above';\n recognized = true;\n } else if (token === 'descriptionSide=below') {\n descriptionSide = 'below';\n recognized = true;\n } else if (token.startsWith('column=')) {\n const parsed = parseCoordinate(token.slice(7));\n if (parsed !== undefined) {\n column = parsed;\n recognized = true;\n }\n } else if (token === 'callout=false') {\n callout = false;\n recognized = true;\n } else if (token === 'callout=true') {\n callout = true;\n recognized = true;\n }\n }\n if (recognized) text = text.slice(0, attrs.index).trim();\n }\n if (text.startsWith('^ ')) {\n side = 'above';\n text = text.slice(2).trim();\n } else if (/^[vV]\\s+/.test(text)) {\n side = 'below';\n text = text.slice(2).trim();\n }\n const separator = text.indexOf('::');\n const label = (separator >= 0 ? text.slice(0, separator) : text).trim();\n const description = separator >= 0 ? text.slice(separator + 2).trim() : undefined;\n return {\n ...(label ? { label } : {}),\n ...(description ? { description } : {}),\n ...(id ? { id } : {}),\n ...(column !== undefined ? { column } : {}),\n ...(side ? { side } : {}),\n ...(descriptionSide ? { descriptionSide } : {}),\n ...(callout !== undefined ? { callout } : {}),\n };\n}\n\nfunction parseTrackPrefix(text: string): {\n label?: string;\n id?: string;\n startColumn?: number;\n endColumn?: number;\n hasMetadata: boolean;\n} {\n let label = text.trim();\n let id: string | undefined;\n let startColumn: number | undefined;\n let endColumn: number | undefined;\n let recognized = false;\n const attrs = /\\{([^{}]+)\\}\\s*$/.exec(label);\n if (attrs) {\n for (const token of attrs[1].trim().split(/\\s+/)) {\n if (token.startsWith('#') && token.length > 1) {\n id = token.slice(1);\n recognized = true;\n } else if (token.startsWith('start=')) {\n startColumn = parseCoordinate(token.slice(6));\n recognized ||= startColumn !== undefined;\n } else if (token.startsWith('end=')) {\n endColumn = parseCoordinate(token.slice(4));\n recognized ||= endColumn !== undefined;\n }\n }\n if (recognized) label = label.slice(0, attrs.index).trim();\n }\n return {\n ...(label ? { label } : {}),\n ...(id ? { id } : {}),\n ...(startColumn !== undefined ? { startColumn } : {}),\n ...(endColumn !== undefined ? { endColumn } : {}),\n hasMetadata: recognized,\n };\n}\n\nfunction parseCoordinate(value: string): number | undefined {\n if (!value.trim()) return undefined;\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\nfunction stripEdgeRails(raw: string): string {\n const chars = Array.from(raw);\n let start = 0;\n let end = chars.length - 1;\n\n // A structural leading rail either touches the marker (`●── label`) or is\n // followed by whitespace (`● ── label`). A payload that begins after a\n // space with `-1.5`, `--watch`, or `─phase` is authored prose and stays.\n let firstNonSpace = 0;\n while (firstNonSpace <= end && /\\s/u.test(chars[firstNonSpace])) firstNonSpace++;\n let leadingRailEnd = firstNonSpace;\n while (leadingRailEnd <= end && HORIZONTAL.has(chars[leadingRailEnd])) leadingRailEnd++;\n const hasLeadingRail = leadingRailEnd > firstNonSpace;\n const structuralLeadingRail =\n hasLeadingRail &&\n (firstNonSpace === 0 || leadingRailEnd > end || /\\s/u.test(chars[leadingRailEnd] ?? ''));\n start = structuralLeadingRail ? leadingRailEnd : firstNonSpace;\n while (start <= end && /\\s/u.test(chars[start])) start++;\n\n while (end >= start && /\\s/u.test(chars[end])) end--;\n const trailingRailEnd = end;\n while (end >= start && HORIZONTAL.has(chars[end])) end--;\n const hasTrailingRail = end < trailingRailEnd;\n // Separators are normally preceded by whitespace; a long/Unicode run is\n // also safely structural in compact `label───●` authored art.\n const trailingRun = hasTrailingRail ? chars.slice(end + 1, trailingRailEnd + 1) : [];\n const structuralTrailingRail =\n hasTrailingRail &&\n (end < start ||\n /\\s/u.test(chars[end] ?? '') ||\n trailingRun.length >= 3 ||\n trailingRun.some((char) => char !== '-'));\n if (!structuralTrailingRail) end = trailingRailEnd;\n while (end >= start && /\\s/u.test(chars[end])) end--;\n return chars.slice(start, end + 1).join('');\n}\n\nfunction hasRailBefore(chars: readonly string[], column: number, minimum: number): boolean {\n let index = column - 1;\n while (index >= 0 && /\\s/u.test(chars[index])) index--;\n let count = 0;\n while (index >= 0 && HORIZONTAL.has(chars[index])) {\n count++;\n index--;\n }\n return count >= minimum;\n}\n\nfunction findLastNonSpace(chars: readonly string[]): number {\n for (let index = chars.length - 1; index >= 0; index--) {\n if (!/\\s/u.test(chars[index])) return index;\n }\n return -1;\n}\n\nfunction parseBranchDeclaration(line: string): PendingBranch | null {\n const match =\n /^\\s*(?:branch|link)\\s*:\\s*([^\\s:]+)\\s*(?:->|=>|→)\\s*([^\\s:]+)(?:\\s*:\\s*(.+))?\\s*$/i.exec(line);\n if (!match) return null;\n return {\n source: match[1],\n target: match[2],\n ...(match[3]?.trim() ? { label: match[3].trim() } : {}),\n };\n}\n\nfunction splitPlainSegments(line: string): Segment[] {\n const chars = Array.from(line);\n const out: Segment[] = [];\n let start = -1;\n let spaces = 0;\n for (let i = 0; i <= chars.length; i++) {\n const ch = chars[i];\n if (ch === ' ') {\n spaces++;\n if (start >= 0 && spaces >= 2) {\n const end = i - spaces;\n const text = chars\n .slice(start, end + 1)\n .join('')\n .trim();\n if (text) out.push({ start, end, text });\n start = -1;\n }\n continue;\n }\n spaces = 0;\n if (ch !== undefined && start < 0) start = i;\n if (ch === undefined && start >= 0) {\n const text = chars.slice(start).join('').trim();\n if (text) out.push({ start, end: chars.length - 1, text });\n }\n }\n return out.filter((segment) => cleanCalloutText(segment.text).length > 0);\n}\n\nfunction extractConnectorCallouts(line: string): Segment[] {\n const chars = Array.from(line);\n const out: Segment[] = [];\n for (let i = 0; i < chars.length; i++) {\n if (!CONNECTOR_ANCHORS.has(chars[i])) continue;\n let j = i + 1;\n const railStart = j;\n while (j < chars.length && (HORIZONTAL.has(chars[j]) || chars[j] === ' ')) j++;\n const railEnd = j;\n // In `└─-1.5` / `└─--watch`, the Unicode rail is structural but the\n // following ASCII hyphen run is authored prose. Preserve that suffix.\n const afterRail = chars[j];\n if (afterRail !== undefined && !/\\s/u.test(afterRail)) {\n let lastNonAsciiRail = -1;\n for (let railIndex = railStart; railIndex < j; railIndex++) {\n if (HORIZONTAL.has(chars[railIndex]) && chars[railIndex] !== '-') {\n lastNonAsciiRail = railIndex;\n }\n }\n if (lastNonAsciiRail >= railStart && lastNonAsciiRail + 1 < j) {\n j = lastNonAsciiRail + 1;\n } else if (lastNonAsciiRail < 0 && j - railStart >= 3) {\n j--;\n }\n }\n const textStart = j;\n if (j < railEnd) while (j < chars.length && chars[j] === '-') j++;\n while (j < chars.length && !HORIZONTAL.has(chars[j]) && !CONNECTOR_ANCHORS.has(chars[j])) j++;\n const text = chars.slice(textStart, j).join('').trim();\n if (text) out.push({ start: i, end: Math.max(i, j - 1), text });\n }\n return out;\n}\n\nfunction nearestTrack(\n tracks: readonly AsciiTimelineTrack[],\n row: number,\n column: number,\n): AsciiTimelineTrack | undefined {\n return tracks\n .filter((track) => column >= track.startColumn - 2 && column <= track.endColumn + 2)\n .sort((a, b) => Math.abs(a.row - row) - Math.abs(b.row - row))[0];\n}\n\nfunction isPointerAt(chars: readonly string[], column: number): boolean {\n const char = chars[column];\n if (!POINTERS.has(char)) return false;\n if (char !== '^' && char !== 'v') return true;\n return (\n (column === 0 || /\\s/u.test(chars[column - 1] ?? '')) &&\n (column + 1 >= chars.length || /\\s/u.test(chars[column + 1] ?? ''))\n );\n}\n\nfunction nearestUnclaimedMarkerTrack(\n tracks: readonly AsciiTimelineTrack[],\n row: number,\n column: number,\n): AsciiTimelineTrack | undefined {\n return tracks\n .filter((track) =>\n track.events.some((event) => !event.id && Math.abs(event.column - column) <= 1),\n )\n .sort((a, b) => Math.abs(a.row - row) - Math.abs(b.row - row))[0];\n}\n\nfunction nearestEvent(\n events: readonly AsciiTimelineEvent[],\n column: number,\n): AsciiTimelineEvent | undefined {\n return [...events].sort(\n (a, b) =>\n Math.abs(a.column - column) - Math.abs(b.column - column) ||\n Number(a.callout === false) - Number(b.callout === false),\n )[0];\n}\n\nfunction nearestSegment(\n segments: readonly Segment[],\n column: number,\n threshold: number,\n): Segment | undefined {\n return [...segments]\n .map((segment) => ({ segment, distance: Math.abs((segment.start + segment.end) / 2 - column) }))\n .filter((candidate) => candidate.distance <= threshold)\n .sort((a, b) => a.distance - b.distance)[0]?.segment;\n}\n\nfunction nearestEventGap(events: readonly AsciiTimelineEvent[], column: number): number {\n const gaps = events\n .filter((event) => event.column !== column)\n .map((event) => Math.abs(event.column - column));\n return gaps.length > 0 ? Math.min(...gaps) : 12;\n}\n\nfunction previousNonBlankRow(lines: readonly string[], from: number): number {\n for (let row = from; row >= 0; row--) if (lines[row].trim()) return row;\n return -1;\n}\n\nfunction markerKind(glyph: string): AsciiTimelineMarker {\n if (glyph === '◆' || glyph === '◇') return 'diamond';\n if (glyph === '○' || glyph === 'o' || glyph === 'O') return 'hollow';\n return 'filled';\n}\n\nfunction isMarkerAt(chars: readonly string[], index: number, style: AsciiTimelineStyle): boolean {\n const glyph = chars[index];\n if (STRONG_MARKERS.has(glyph)) return true;\n if (style !== 'ascii' || !ASCII_MARKERS.has(glyph)) return false;\n // ASCII marker glyphs are ordinary prose/code characters too. Only treat\n // them as points when they touch a real rail run. Requiring two rail cells\n // plus a prose boundary avoids turning `Go-live`, `foo--bar`, or\n // `release-o` into phantom dots.\n const leftRail = railRun(chars, index, -1);\n const rightRail = railRun(chars, index, 1);\n const beforeIsWord = /[\\p{L}\\p{N}_]/u.test(chars[index - 1] ?? '');\n const afterIsWord = /[\\p{L}\\p{N}_]/u.test(chars[index + 1] ?? '');\n return (leftRail >= 2 && !afterIsWord) || (rightRail >= 2 && !beforeIsWord);\n}\n\nfunction railRun(chars: readonly string[], index: number, direction: -1 | 1): number {\n let count = 0;\n for (let cursor = index + direction; HORIZONTAL.has(chars[cursor] ?? ''); cursor += direction) {\n count++;\n }\n return count;\n}\n\nfunction cleanCalloutText(text: string): string {\n return text\n .replace(/^[\\s│|└┌├┬┘┐╰╭╯╮─━═╌╍┄┅┈┉-]+/u, '')\n .replace(/[\\s│|└┌├┬┘┐╰╭╯╮─━═╌╍┄┅┈┉►▶▷→>-]+$/u, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\n/** Normalize already-separated prose without stripping meaningful `-`/rails. */\nfunction cleanProseText(text: string): string {\n return text\n .replace(/^[\\s│|]+/u, '')\n .replace(/[\\s│|]+$/u, '')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction stripTrailingColon(text: string): string {\n return text.replace(/:\\s*$/, '').trim();\n}\n\nfunction slug(text: string): string {\n return (\n text\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'event'\n );\n}\n\nfunction dedupe(base: string, used: Map<string, number>): string {\n const count = used.get(base) ?? 0;\n used.set(base, count + 1);\n return count === 0 ? base : `${base}-${count + 1}`;\n}\n\nfunction detectStyle(lines: readonly string[]): AsciiTimelineStyle {\n for (const line of lines) {\n for (const ch of line) {\n if (\n STRONG_MARKERS.has(ch) ||\n (HORIZONTAL.has(ch) && ch !== '-') ||\n ['►', '▶', '▷', '→'].includes(ch)\n ) {\n // Unicode structural vocabulary is unambiguous. Prefer it even when\n // labels/descriptions contain many ordinary ASCII `o`, `-`, or `>`\n // characters; those prose characters must not flip marker parsing.\n return 'unicode';\n }\n }\n }\n return 'ascii';\n}\n","/** Conservative detection for authored ASCII timeline fences. */\n\nimport type { MarkdownCodeBlock } from '../../markdown/types.js';\nimport { parseAsciiDiagramWithStats } from '../asciiDiagram/parse.js';\nimport { parseAsciiTimelineWithStats } from './parse.js';\nimport type { AsciiTimelineDetection } from './types.js';\n\nexport const ASCII_TIMELINE_FENCE_LANGS: ReadonlySet<string> = new Set([\n 'text',\n 'txt',\n 'plaintext',\n 'plain',\n 'ascii',\n 'timeline',\n]);\n\nconst MAX_LINES = 400;\nconst MAX_CANONICAL_LINES = 2000;\nconst MAX_COLS = 400;\nconst MAX_EXPLICIT_COLS = 4096;\nconst BOX_TOP_EDGE_RE = /[┌┏╔╭].*[┐┓╗╮]/u;\nconst CANONICAL_TRACK_RE = /\\{#[^{}\\s]+ start=[^{}\\s]+ end=[^{}\\s]+\\}:\\s/u;\n\nexport function isEligibleAsciiTimelineFenceLang(lang: string | null | undefined): boolean {\n if (lang === null || lang === undefined) return true;\n const normalized = lang.trim().toLowerCase();\n return normalized === '' || ASCII_TIMELINE_FENCE_LANGS.has(normalized);\n}\n\nexport function isExplicitTimelineLang(lang: string | null | undefined): boolean {\n return typeof lang === 'string' && lang.trim().toLowerCase() === 'timeline';\n}\n\nexport interface DetectAsciiTimelineOptions {\n /** Explicit `timeline` language: allow one-point/ASCII-marker tracks. */\n explicit?: boolean;\n}\n\nexport function detectAsciiTimeline(\n text: string,\n options: DetectAsciiTimelineOptions = {},\n): AsciiTimelineDetection {\n const explicit = options.explicit === true;\n const lines = text.replace(/\\r\\n?/g, '\\n').split('\\n');\n const canonicalTrackRows = lines.filter((line) => CANONICAL_TRACK_RE.test(line)).length;\n const canonicalLineBudget = Math.min(\n MAX_CANONICAL_LINES,\n canonicalTrackRows * 6 +\n lines.filter((line) => /^\\s*(?:branch|link)\\s*:/iu.test(line)).length +\n 2,\n );\n if (\n lines.length > MAX_LINES &&\n (canonicalTrackRows === 0 || lines.length > canonicalLineBudget)\n ) {\n return { isTimeline: false, reasons: [`too-many-lines(${lines.length})`] };\n }\n const maxCols = Math.max(0, ...lines.map((line) => Array.from(line).length));\n // Canonical renderer output carries bounded track metadata on every long\n // row. Permit that high-confidence form up to the explicit-fence cap while\n // retaining the conservative 400-column limit for arbitrary untagged art.\n const canonicalLongForm =\n canonicalTrackRows > 0 &&\n lines.every((line) => Array.from(line).length <= MAX_COLS || CANONICAL_TRACK_RE.test(line));\n const maxAllowedCols = explicit || canonicalLongForm ? MAX_EXPLICIT_COLS : MAX_COLS;\n if (maxCols > maxAllowedCols) {\n return { isTimeline: false, reasons: [`too-wide(${maxCols})`] };\n }\n\n const nonBlank = lines.filter((line) => line.trim().length > 0);\n const pipeRows = nonBlank.filter((line) => /^\\s*\\|.*\\|\\s*$/.test(line)).length;\n const hasGfmSeparator = nonBlank.some(\n (line) => /^\\s*\\|?[\\s:|-]+\\|?\\s*$/.test(line) && line.includes('-'),\n );\n if (pipeRows > nonBlank.length / 2 && hasGfmSeparator) {\n return { isTimeline: false, reasons: ['markdown-table'] };\n }\n\n if (!explicit && lines.some((line) => BOX_TOP_EDGE_RE.test(line))) {\n return { isTimeline: false, reasons: ['has-box-corners'] };\n }\n\n // Closed boxes own the art even if their borders happen to contain dots.\n // Untagged detection rejects even one box; the diagram auto-template needs\n // two, but silently turning a single boxed callout into a timeline is worse\n // than leaving it as authored code. An explicit timeline may use one boxed\n // callout, while two or more still belong to the diagram codec.\n const boxes = parseAsciiDiagramWithStats(text).diagram.nodes.length;\n if (boxes >= (explicit ? 2 : 1)) {\n return { isTimeline: false, reasons: [`has-boxes(${boxes})`] };\n }\n\n // A tree item may itself contain a marker rail in its label. Connector\n // prefixes (`├── ●──●`, `|-- ●--●`) identify the outer structure as a\n // tree, so conservative untagged detection must not claim that row.\n if (!explicit && /^[ \\t]*(?:[│|][ \\t]*)*[├└+|`][─━═-]{1,4}[ \\t]+[●○◉◆◇•]/mu.test(text)) {\n return { isTimeline: false, reasons: ['tree-connector-prefix'] };\n }\n\n const { timeline, stats } = parseAsciiTimelineWithStats(text);\n if (stats.wrappedFlow) {\n return {\n isTimeline: true,\n timeline,\n reasons: [`tracks(${stats.axisLines})`, `events(${stats.markerCount})`, 'wrapped-flow'],\n };\n }\n if (stats.axisLines === 0) return { isTimeline: false, reasons: ['no-axis-lines'] };\n const explicitCadence = explicit && stats.horizontalChars === 0 && stats.markerCount >= 4;\n if (!explicitCadence && stats.horizontalChars < (explicit ? 2 : 8)) {\n return { isTimeline: false, reasons: [`too-few-horizontal(${stats.horizontalChars})`] };\n }\n if (stats.markerCount < (explicit ? 1 : 2)) {\n return { isTimeline: false, reasons: [`too-few-markers(${stats.markerCount})`] };\n }\n // Untagged auto-detection requires unmistakable Unicode point markers.\n // `foo * bar *` or `o---o` in real code therefore stays ordinary code.\n if (!explicit && stats.strongMarkerCount < 2) {\n return { isTimeline: false, reasons: [`too-few-strong-markers(${stats.strongMarkerCount})`] };\n }\n\n return {\n isTimeline: true,\n timeline,\n reasons: [\n `tracks(${stats.axisLines})`,\n `events(${stats.markerCount + stats.pointerCount})`,\n explicit ? 'explicit' : 'strong-markers',\n ],\n };\n}\n\nexport function isAsciiTimelineFence(node: MarkdownCodeBlock): boolean {\n if (node.type !== 'code') return false;\n if (!isEligibleAsciiTimelineFenceLang(node.lang)) return false;\n return detectAsciiTimeline(node.value, { explicit: isExplicitTimelineLang(node.lang) })\n .isTimeline;\n}\n","/**\n * Character classification + render vocabularies for ASCII tree art.\n *\n * The parser accepts a superset (Unicode light/heavy/rounded branches plus\n * ASCII `|-- ` / `` `-- `` / `+-- `); the renderer emits one `TreeVocab`.\n * Internal to the treeview module.\n */\n\n/** Vertical rail glyphs (an ancestor line continuing downward). */\nconst RAIL_CHARS = new Set(['│', '┃', '╎', '╏', '║', '|']);\n/** Branch-tee glyphs (a node that has a following sibling). */\nconst BRANCH_TEE = new Set(['├', '┣', '┠', '┝', '╠', '╞']);\n/** Branch-elbow glyphs (the last child). */\nconst BRANCH_ELBOW = new Set(['└', '┗', '╰', '╚', '╘']);\n/** Horizontal dash glyphs used in a branch arm. */\nconst DASH_CHARS = new Set(['─', '━', '═', '-']);\n\nexport function isRailChar(ch: string): boolean {\n return RAIL_CHARS.has(ch);\n}\nexport function isBranchTee(ch: string): boolean {\n return BRANCH_TEE.has(ch);\n}\nexport function isBranchElbow(ch: string): boolean {\n return BRANCH_ELBOW.has(ch);\n}\nexport function isUnicodeBranch(ch: string): boolean {\n return BRANCH_TEE.has(ch) || BRANCH_ELBOW.has(ch);\n}\nexport function isDashChar(ch: string): boolean {\n return DASH_CHARS.has(ch);\n}\n\n/** Structural glyphs used for the style vote. */\nexport function isUnicodeTreeChar(ch: string): boolean {\n return (\n BRANCH_TEE.has(ch) ||\n BRANCH_ELBOW.has(ch) ||\n ch === '│' ||\n ch === '┃' ||\n ch === '─' ||\n ch === '━'\n );\n}\nexport function isAsciiTreeChar(ch: string): boolean {\n return ch === '|' || ch === '`' || ch === '+' || ch === '-';\n}\n\nexport interface TreeVocab {\n /** Branch to a node that has a later sibling (`├── `). */\n tee: string;\n /** Branch to the last child (`└── `). */\n elbow: string;\n /** Ancestor rail column (`│ `). */\n rail: string;\n /** Ended-ancestor gap column (` `). */\n gap: string;\n}\n\nexport const UNICODE_TREE_VOCAB: TreeVocab = {\n tee: '├── ',\n elbow: '└── ',\n rail: '│ ',\n gap: ' ',\n};\n\nexport const ASCII_TREE_VOCAB: TreeVocab = {\n tee: '|-- ',\n elbow: '`-- ',\n rail: '| ',\n gap: ' ',\n};\n","/**\n * ASCII tree parser: file-tree / outline art → nested nodes.\n *\n * Pure, deterministic, never throws. Handles the many renditions AI emits:\n * Unicode connectors (`├── `/`└── `/`│ `), ASCII (`|-- `/`` `-- ``/`+-- `),\n * bullet-indented (`- `/`* `), and pure indentation. Depth is recovered by\n * finding where each line's LABEL begins (after any connector/indent\n * prefix) and running the standard outline indent-stack — this unifies all\n * renditions and tolerates ragged dedents.\n */\n\nimport {\n isBranchElbow,\n isBranchTee,\n isDashChar,\n isRailChar,\n isAsciiTreeChar,\n isUnicodeTreeChar,\n} from './chars.js';\nimport type { Tree, TreeNode } from './types.js';\n\n/** Internal per-line analysis fed to the reconstruction stack. */\nexport interface TreeLineStats {\n /** Non-blank content lines. */\n contentLines: number;\n /** Lines carrying a connector branch (`├──`/`└──`/`|--`/`` `--``/`+--`). */\n connectorLines: number;\n /** Lines that could not be analyzed as a node (loose text). */\n looseLines: number;\n /** Distinct label-start columns observed (a hierarchy has ≥2). */\n indentLevels: number;\n}\n\ninterface AnalyzedLine {\n indent: number; // column where the label begins\n label: string;\n comment?: string;\n hadConnector: boolean;\n}\n\nexport function parseTree(text: string): Tree {\n return parseTreeWithStats(text).tree;\n}\n\nexport function parseTreeWithStats(text: string): { tree: Tree; stats: TreeLineStats } {\n const warnings: string[] = [];\n const rawLines = text.replace(/\\r\\n?/g, '\\n').split('\\n');\n\n const style = detectStyle(rawLines);\n const stats: TreeLineStats = {\n contentLines: 0,\n connectorLines: 0,\n looseLines: 0,\n indentLevels: 0,\n };\n const indentSet = new Set<number>();\n\n const analyzed: AnalyzedLine[] = [];\n for (const raw of rawLines) {\n if (raw.trim().length === 0) continue;\n stats.contentLines++;\n const a = analyzeLine(raw);\n if (!a || a.label.length === 0) {\n stats.looseLines++;\n continue;\n }\n if (a.hadConnector) stats.connectorLines++;\n indentSet.add(a.indent);\n analyzed.push(a);\n }\n stats.indentLevels = indentSet.size;\n\n // ---- Reconstruct the hierarchy via an indent stack --------------------\n const roots: TreeNode[] = [];\n const stack: Array<{ indent: number; node: TreeNode }> = [];\n for (const a of analyzed) {\n const node: TreeNode = {\n id: '',\n label: a.label,\n children: [],\n ...(a.comment ? { comment: a.comment } : {}),\n };\n // Pop ancestors that are at the same or deeper indent.\n while (stack.length > 0 && stack[stack.length - 1].indent >= a.indent) stack.pop();\n if (stack.length === 0) {\n roots.push(node);\n } else {\n stack[stack.length - 1].node.children.push(node);\n }\n stack.push({ indent: a.indent, node });\n }\n\n // ---- Post-pass: isDir + stable ids ------------------------------------\n const usedIds = new Map<string, number>();\n const finalize = (node: TreeNode): void => {\n node.isDir = node.label.endsWith('/') || node.children.length > 0;\n const base = slugify(stripTrailingSlash(node.label));\n const count = usedIds.get(base) ?? 0;\n usedIds.set(base, count + 1);\n node.id = count === 0 ? base : `${base}-${count + 1}`;\n for (const child of node.children) finalize(child);\n };\n for (const root of roots) finalize(root);\n\n if (analyzed.length > 0 && stats.looseLines > 0) {\n warnings.push(`loose-lines(${stats.looseLines})`);\n }\n\n return { tree: { roots, style, warnings }, stats };\n}\n\n// ---------------------------------------------------------------------------\n// Line analysis\n// ---------------------------------------------------------------------------\n\n/**\n * Strip a line's connector / indent prefix and return the column where the\n * label begins plus the cleaned label + trailing comment. Returns null for\n * a rails-only spacer line.\n */\nfunction analyzeLine(line: string): AnalyzedLine | null {\n const chars = Array.from(line);\n let i = 0;\n let hadConnector = false;\n\n // Consume leading whitespace + vertical rails. A rail is a rail glyph NOT\n // immediately followed by a dash (which would make it an ASCII branch).\n for (;;) {\n while (i < chars.length && (chars[i] === ' ' || chars[i] === '\\t')) i++;\n const ch = chars[i];\n if (ch === undefined) return null; // blank / rails-only\n if (isRailChar(ch) && !isDashChar(chars[i + 1] ?? '')) {\n i++;\n continue;\n }\n break;\n }\n\n // Optional branch: a Unicode tee/elbow + dashes, or ASCII `|`/`` ` ``/`+`\n // + dashes. The label follows (after any trailing spaces).\n const ch = chars[i];\n if (ch !== undefined) {\n if (isBranchTee(ch) || isBranchElbow(ch)) {\n i++;\n while (i < chars.length && (isDashChar(chars[i]) || isRailChar(chars[i]))) i++;\n hadConnector = true;\n } else if ((ch === '|' || ch === '`' || ch === '+') && isDashChar(chars[i + 1] ?? '')) {\n i++;\n while (i < chars.length && isDashChar(chars[i])) i++;\n hadConnector = true;\n } else if ((ch === '-' || ch === '*' || ch === '+') && (chars[i + 1] ?? '') === ' ') {\n // Markdown-style bullet (indent-based rendition).\n i++;\n hadConnector = false;\n }\n }\n while (i < chars.length && (chars[i] === ' ' || chars[i] === '\\t')) i++;\n\n const indent = i;\n let label = chars.slice(i).join('').replace(/\\s+$/u, '');\n if (label.length === 0) return null;\n\n // Trailing comment: ` # …`, ` <-- …`, or ` // …` (needs a leading space).\n let comment: string | undefined;\n const commentMatch = /\\s+(?:#|<--|\\/\\/)\\s?(.*)$/.exec(label);\n if (commentMatch) {\n comment = commentMatch[1].trim() || undefined;\n label = label.slice(0, commentMatch.index).replace(/\\s+$/u, '');\n }\n if (label.length === 0) return null;\n\n return { indent, label, hadConnector, ...(comment ? { comment } : {}) };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction detectStyle(lines: string[]): 'unicode' | 'ascii' {\n let unicode = 0;\n let ascii = 0;\n for (const line of lines) {\n for (const ch of line) {\n if (isUnicodeTreeChar(ch)) unicode++;\n else if (isAsciiTreeChar(ch)) ascii++;\n }\n }\n return ascii > unicode ? 'ascii' : 'unicode';\n}\n\nfunction stripTrailingSlash(s: string): string {\n return s.endsWith('/') ? s.slice(0, -1) : s;\n}\n\nfunction slugify(s: string): string {\n const slug = s\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return slug || 'node';\n}\n","/**\n * ASCII tree detection: is this fence content a file-tree / outline?\n *\n * The mirror image of the diagram detector. A diagram has ≥2 closed boxes;\n * a tree has ZERO closed boxes plus connector-branch structure. The two\n * partition the `├──` glyph space cleanly, so a fence is at most one of\n * them. Auto-detection is deliberately conservative (requires connector\n * branches — the unambiguous AI file-tree signal); the parser still handles\n * pure-indentation renditions for explicitly `{[tree]}`-annotated fences.\n */\n\nimport type { MarkdownCodeBlock } from '../../markdown/types.js';\nimport { parseAsciiDiagramWithStats } from '../asciiDiagram/parse.js';\nimport { detectAsciiTimeline } from '../asciiTimeline/detect.js';\nimport { parseTreeWithStats } from './parse.js';\nimport type { TreeDetection } from './types.js';\n\n/** Fence languages eligible for tree detection (plus no language at all). */\nexport const TREE_FENCE_LANGS: ReadonlySet<string> = new Set([\n 'text',\n 'txt',\n 'plaintext',\n 'plain',\n 'ascii',\n 'tree',\n]);\n\nconst MAX_LINES = 400;\nconst MIN_LINES = 2;\nconst MIN_CONNECTOR_LINES = 2;\nconst MIN_NODES = 2;\n\n/**\n * Box-drawing corners a file tree NEVER contains: top-left/right and\n * bottom-right in light, heavy, double, and rounded weights. Bottom-LEFT\n * corners (└ ┗ ╰ ╚ ╘) are excluded — the tree codec uses them as elbows.\n */\nconst BOX_CORNER_RE = /[┌┐┘┏┓┛╔╗╝╭╮╯]/u;\n\nexport function isEligibleTreeFenceLang(lang: string | null | undefined): boolean {\n if (lang === null || lang === undefined) return true;\n const normalized = lang.trim().toLowerCase();\n return normalized === '' || TREE_FENCE_LANGS.has(normalized);\n}\n\n/**\n * True when the fence LANGUAGE is the explicit `tree` tag — an author-set\n * \"this is a tree\" marker that survives markdown ↔ Tiptap round-trips (the\n * language class round-trips; fence meta does not). Detection of a tagged\n * fence is lenient (no connector requirement) so a flattened/degenerate\n * tree stays a tree.\n */\nexport function isExplicitTreeLang(lang: string | null | undefined): boolean {\n return typeof lang === 'string' && lang.trim().toLowerCase() === 'tree';\n}\n\nexport interface DetectTreeOptions {\n /** The fence is explicitly `tree`-tagged: skip the connector requirement. */\n explicit?: boolean;\n}\n\nexport function detectTree(text: string, opts: DetectTreeOptions = {}): TreeDetection {\n const explicit = opts.explicit === true;\n const lines = text.replace(/\\r\\n?/g, '\\n').split('\\n');\n const nonBlank = lines.filter((l) => l.trim().length > 0);\n // A `tree`-tagged fence can be a single-node tree (e.g. the outline edited\n // down to one item); an untagged fence needs ≥2 lines to auto-detect.\n const minLines = explicit ? 1 : MIN_LINES;\n if (nonBlank.length < minLines) {\n return { isTree: false, reasons: [`too-few-lines(${nonBlank.length})`] };\n }\n if (lines.length > MAX_LINES) {\n return { isTree: false, reasons: [`too-many-lines(${lines.length})`] };\n }\n\n // Markdown/GFM table shape → not a tree (even when explicitly tagged; it\n // wouldn't parse into a sensible hierarchy anyway).\n const pipeRows = nonBlank.filter((l) => /^\\s*\\|.*\\|\\s*$/.test(l)).length;\n const hasGfmSeparator = nonBlank.some((l) => /^\\s*\\|?[\\s:|-]+\\|?\\s*$/.test(l) && l.includes('-'));\n if (pipeRows > nonBlank.length / 2 && hasGfmSeparator) {\n return { isTree: false, reasons: ['markdown-table'] };\n }\n\n // Box-drawing CORNERS are an unambiguous box-diagram signal. A file tree /\n // outline is built only from tees (├), elbows (└ ┗ ╰), rails (│), and dashes\n // (─) — it never contains a TOP corner (┌ ┐) or a BOTTOM-RIGHT corner (┘).\n // A fence with those is a diagram, even a MALFORMED one whose borders are\n // misaligned so the tracer finds <2 closed boxes (e.g. hand-drawn art\n // knocked out of alignment by a later rename that widened the labels).\n // Without this, such art falls through to a mangled treeview. (Bottom-LEFT\n // corners └ ┗ ╰ ╚ ╘ are deliberately excluded — they double as tree elbows.)\n if (BOX_CORNER_RE.test(text)) {\n return { isTree: false, reasons: ['has-box-corners'] };\n }\n\n // Timeline callout elbows can resemble tree branches. Give a qualifying\n // marker+axis timeline ownership before the loose tree parser sees it.\n if (!explicit && detectAsciiTimeline(text).isTimeline) {\n return { isTree: false, reasons: ['is-timeline'] };\n }\n\n // Mutual exclusion with the diagram codec: a fence with ≥2 closed boxes is\n // a diagram, not a tree.\n const boxes = parseAsciiDiagramWithStats(text).diagram.nodes.length;\n if (boxes >= 2) {\n return { isTree: false, reasons: [`has-boxes(${boxes})`] };\n }\n\n const { tree, stats } = parseTreeWithStats(text);\n const nodeCount = countNodes(tree.roots);\n const minNodes = explicit ? 1 : MIN_NODES;\n if (nodeCount < minNodes) {\n return { isTree: false, reasons: [`too-few-nodes(${nodeCount})`] };\n }\n if (!explicit) {\n // Auto-detection of an UNTAGGED fence requires the connector signal\n // (pure-indentation art could be prose or a list). A `tree`-tagged fence\n // trusts the author and skips this.\n if (stats.connectorLines < MIN_CONNECTOR_LINES) {\n return { isTree: false, reasons: [`too-few-connectors(${stats.connectorLines})`] };\n }\n if (stats.looseLines > stats.contentLines * 0.25) {\n return { isTree: false, reasons: [`loose-ratio(${stats.looseLines}/${stats.contentLines})`] };\n }\n }\n\n return {\n isTree: true,\n tree,\n reasons: [`nodes(${nodeCount})`, explicit ? 'explicit' : `connectors(${stats.connectorLines})`],\n };\n}\n\n/** Convenience gate for pipeline callers: lang allowlist + content detection. */\nexport function isTreeFence(node: MarkdownCodeBlock): boolean {\n if (node.type !== 'code') return false;\n if (!isEligibleTreeFenceLang(node.lang)) return false;\n return detectTree(node.value, { explicit: isExplicitTreeLang(node.lang) }).isTree;\n}\n\nfunction countNodes(nodes: readonly import('./types.js').TreeNode[]): number {\n let n = 0;\n for (const node of nodes) n += 1 + countNodes(node.children);\n return n;\n}\n","/**\n * Matches a prominent number suitable for a Stat Highlight block. Qualifies\n * on currency prefixes, common unit suffixes, and standalone large numbers.\n * Plain small numbers (`42`) intentionally do not qualify.\n */\nconst NUMBER_HIGHLIGHT_RE =\n /(?:[$€£¥]\\s?\\d+(?:[.,]\\d+)*(?:\\s?(?:[MBK]|million|billion|thousand))?|\\d+(?:[.,]\\d+)*\\s?(?:%|‰|x|×|[MBK]|million|billion|thousand|percent|years?|days?|hours?)|\\d{3,}(?:[.,]\\d+)*)/i;\n\n/** A prominent number found inside a short stat-like string. */\nexport interface NumberHighlightMatch {\n value: string;\n index: number;\n end: number;\n}\n\n/** Find the prominent number phrase inside a string, if one exists. */\nexport function matchNumberHighlight(text: string): NumberHighlightMatch | null {\n const match = NUMBER_HIGHLIGHT_RE.exec(text);\n if (!match || match.index === undefined) return null;\n return {\n value: match[0],\n index: match.index,\n end: match.index + match[0].length,\n };\n}\n","/**\n * Block template recommendations.\n *\n * Given a slice of markdown block nodes (the body underneath a heading),\n * profile the content for image / video / quote / list / table / date /\n * stat signals, then map that profile to the set of templates that make\n * sense for the block. Used by the editor's template picker to surface a\n * \"Recommended for this block\" section above the full template list.\n */\n\nimport { extractPlainText, findNodesByType, walkMarkdownTree } from '../markdown/utils.js';\nimport type {\n HtmlElement,\n HtmlNode,\n MarkdownBlockNode,\n MarkdownCodeBlock,\n MarkdownHtmlBlock,\n MarkdownNode,\n} from '../markdown/types.js';\nimport {\n detectAsciiDiagram,\n isEligibleAsciiFenceLang,\n isExplicitDiagramLang,\n} from '../doc/asciiDiagram/detect.js';\nimport {\n detectAsciiTimeline,\n isEligibleAsciiTimelineFenceLang,\n isExplicitTimelineLang,\n} from '../doc/asciiTimeline/detect.js';\nimport { detectTree, isEligibleTreeFenceLang, isExplicitTreeLang } from '../doc/treeview/detect.js';\nimport { matchNumberHighlight } from './numberHighlight.js';\n\nexport interface BlockContentProfile {\n hasImage: boolean;\n imageCount: number;\n hasVideo: boolean;\n hasBlockquote: boolean;\n hasList: boolean;\n hasTable: boolean;\n hasDate: boolean;\n hasNumberHighlight: boolean;\n wordCount: number;\n /**\n * True when the body is dominated by exactly one code fence whose content\n * is an ASCII box-and-line diagram (see `doc/asciiDiagram/detect.ts`).\n * Optional so externally-constructed profiles keep compiling.\n */\n hasAsciiDiagram?: boolean;\n /** True when a dominant code fence is an authored marker+axis timeline. */\n hasTimeline?: boolean;\n /**\n * True when the body is dominated by exactly one code fence whose content\n * is an ASCII file-tree / outline (see `doc/treeview/detect.ts`). Mutually\n * exclusive with `hasAsciiDiagram`.\n */\n hasTree?: boolean;\n}\n\nexport interface RecommendationResult {\n recommended: string[];\n rest: string[];\n}\n\nconst EMPTY_PROFILE: BlockContentProfile = Object.freeze({\n hasImage: false,\n imageCount: 0,\n hasVideo: false,\n hasBlockquote: false,\n hasList: false,\n hasTable: false,\n hasDate: false,\n hasNumberHighlight: false,\n wordCount: 0,\n});\n\nconst DATE_PATTERNS: RegExp[] = [\n /\\b(January|February|March|April|May|June|July|August|September|October|November|December)\\s+(\\d{1,2},?\\s+)?\\d{4}\\b/i,\n /\\b\\d{1,2}\\s+(January|February|March|April|May|June|July|August|September|October|November|December)\\s+\\d{4}\\b/i,\n /\\b(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Sept|Oct|Nov|Dec)\\.?\\s+\\d{1,2},?\\s+\\d{4}\\b/i,\n /\\b\\d{4}-\\d{2}-\\d{2}\\b/,\n /\\b\\d{1,2}\\/\\d{1,2}\\/\\d{2,4}\\b/,\n /\\bQ[1-4]\\s+\\d{4}\\b/,\n /\\b\\d{4}s\\b/,\n /\\b\\d{1,2}(st|nd|rd|th)\\s+century\\b/i,\n];\n\nconst VIDEO_HOST_RE = /(youtube\\.com|youtu\\.be|vimeo\\.com|wistia\\.|loom\\.com)/i;\n\nfunction htmlElementsByTag(root: MarkdownNode, tagNames: Set<string>): HtmlElement[] {\n const blocks = findNodesByType<MarkdownHtmlBlock>(root, 'htmlBlock');\n // Inline HTML (htmlInline) also carries htmlChildren; include both.\n const inline = findNodesByType<MarkdownNode>(root, 'htmlInline') as Array<\n MarkdownNode & { htmlChildren?: HtmlNode[] }\n >;\n const out: HtmlElement[] = [];\n const visit = (n: HtmlNode): void => {\n if (n.type === 'htmlElement') {\n if (tagNames.has(n.tagName.toLowerCase())) out.push(n);\n for (const c of n.children) visit(c);\n }\n };\n for (const b of blocks) for (const c of b.htmlChildren) visit(c);\n for (const i of inline) {\n if (Array.isArray(i.htmlChildren)) for (const c of i.htmlChildren) visit(c);\n }\n return out;\n}\n\n/**\n * Walk a slice of block nodes and summarize what kinds of content it\n * contains. Cheap to run — no markdown parsing, just AST traversal.\n */\nexport function profileBlockContents(nodes: MarkdownBlockNode[]): BlockContentProfile {\n if (!nodes || nodes.length === 0) return { ...EMPTY_PROFILE };\n\n let imageCount = 0;\n let hasBlockquote = false;\n let hasList = false;\n let hasTable = false;\n\n const plainParts: string[] = [];\n\n for (const node of nodes) {\n imageCount += findNodesByType(node, 'image').length;\n imageCount += findNodesByType(node, 'imageReference').length;\n if (findNodesByType(node, 'blockquote').length > 0) hasBlockquote = true;\n if (findNodesByType(node, 'list').length > 0) hasList = true;\n if (findNodesByType(node, 'table').length > 0) hasTable = true;\n plainParts.push(extractPlainText(node));\n }\n\n // HTML embeds: <img>, <video>, <iframe src=…video host>\n const root: MarkdownNode = { type: 'document', children: nodes };\n const imgTags = htmlElementsByTag(root, new Set(['img']));\n imageCount += imgTags.length;\n\n const videoTags = htmlElementsByTag(root, new Set(['video', 'iframe', 'source']));\n let hasVideo = false;\n for (const el of videoTags) {\n if (el.tagName.toLowerCase() === 'video') {\n hasVideo = true;\n break;\n }\n const src = el.attributes.src || el.attributes.href || '';\n if (VIDEO_HOST_RE.test(src)) {\n hasVideo = true;\n break;\n }\n }\n\n // Link-only video embeds (markdown link to a known video host).\n if (!hasVideo) {\n const links = findNodesByType<MarkdownNode & { url?: string }>(root, 'link');\n for (const link of links) {\n if (link.url && VIDEO_HOST_RE.test(link.url)) {\n hasVideo = true;\n break;\n }\n }\n }\n\n const plainText = plainParts.join(' ').trim();\n const wordCount = plainText ? plainText.split(/\\s+/).length : 0;\n\n let hasDate = false;\n for (const re of DATE_PATTERNS) {\n if (re.test(plainText)) {\n hasDate = true;\n break;\n }\n }\n\n // Number highlight: a paragraph that's mostly a single prominent figure.\n let hasNumberHighlight = false;\n walkMarkdownTree(root, (n) => {\n if (hasNumberHighlight) return true;\n if (n.type !== 'paragraph') return;\n const text = extractPlainText(n).trim();\n if (!text) return true;\n const m = matchNumberHighlight(text);\n if (!m) return true;\n // Paragraph qualifies when its word count is small AND a prominent\n // number occupies a meaningful chunk of it. Keeps \"the company grew\n // 50% last year\" from triggering, but accepts \"$2.3M raised\".\n const words = text.split(/\\s+/).length;\n if (words <= 8) hasNumberHighlight = true;\n return true;\n });\n\n // ASCII diagram: exactly one code fence with an eligible (inert) language\n // whose content detects as box-and-line art, in a body it dominates — no\n // competing table/image/video signal and at most a little surrounding\n // prose. The diagram template replaces the whole slide, so hiding a real\n // table or a second fence is the costly failure this guards against.\n let hasAsciiDiagram = false;\n const codeNodes: MarkdownCodeBlock[] = [];\n for (const node of nodes) codeNodes.push(...findNodesByType<MarkdownCodeBlock>(node, 'code'));\n if (\n codeNodes.length === 1 &&\n isEligibleAsciiFenceLang(codeNodes[0].lang) &&\n !hasTable &&\n imageCount === 0 &&\n !hasVideo\n ) {\n const nonCodeChars = Math.max(0, plainText.length - codeNodes[0].value.length);\n const explicit = isExplicitDiagramLang(codeNodes[0].lang);\n if (nonCodeChars <= 400 && detectAsciiDiagram(codeNodes[0].value, { explicit }).isDiagram) {\n hasAsciiDiagram = true;\n }\n }\n\n // ASCII timeline: after the more specific closed-box diagram gate and\n // before tree connector detection.\n let hasTimeline = false;\n if (\n !hasAsciiDiagram &&\n codeNodes.length === 1 &&\n isEligibleAsciiTimelineFenceLang(codeNodes[0].lang) &&\n !hasTable &&\n imageCount === 0 &&\n !hasVideo\n ) {\n const nonCodeChars = Math.max(0, plainText.length - codeNodes[0].value.length);\n const explicit = isExplicitTimelineLang(codeNodes[0].lang);\n if (nonCodeChars <= 400 && detectAsciiTimeline(codeNodes[0].value, { explicit }).isTimeline) {\n hasTimeline = true;\n }\n }\n\n // Tree detection comes last: timeline callout elbows can otherwise look\n // like connector branches to the deliberately lenient tree parser.\n let hasTree = false;\n if (\n !hasAsciiDiagram &&\n !hasTimeline &&\n codeNodes.length === 1 &&\n isEligibleTreeFenceLang(codeNodes[0].lang) &&\n !hasTable &&\n imageCount === 0 &&\n !hasVideo\n ) {\n const nonCodeChars = Math.max(0, plainText.length - codeNodes[0].value.length);\n const explicit = isExplicitTreeLang(codeNodes[0].lang);\n if (nonCodeChars <= 400 && detectTree(codeNodes[0].value, { explicit }).isTree) {\n hasTree = true;\n }\n }\n\n return {\n hasImage: imageCount > 0,\n imageCount,\n hasVideo,\n hasBlockquote,\n hasList,\n hasTable,\n hasDate,\n hasNumberHighlight,\n wordCount,\n hasAsciiDiagram,\n hasTimeline,\n hasTree,\n };\n}\n\n// ── Recommendation rules ───────────────────────────────────────────\n\nconst UNIVERSAL_DEFAULTS = ['title', 'sectionHeader', 'factCard', 'twoColumn'];\n\n/**\n * Given a content profile, return the canonical template-name list that\n * should appear in the \"Recommended\" bucket. Caller is responsible for\n * preserving deduplication / ordering when intersecting with the full\n * template list (see {@link recommendTemplatesForBlock}).\n */\nfunction recommendedNamesForProfile(profile: BlockContentProfile): string[] {\n const names = new Set<string>();\n let anyContentSignal = false;\n\n if (profile.hasAsciiDiagram) {\n anyContentSignal = true;\n names.add('diagram');\n }\n\n if (profile.hasTimeline) {\n anyContentSignal = true;\n names.add('timeline');\n }\n\n if (profile.hasTree) {\n anyContentSignal = true;\n names.add('tree');\n }\n\n if (profile.hasImage) {\n anyContentSignal = true;\n names.add('imageWithCaption');\n names.add('leftFeature');\n names.add('rightFeature');\n if (profile.imageCount >= 2) names.add('photoGrid');\n }\n\n if (profile.hasVideo) {\n anyContentSignal = true;\n names.add('videoWithCaption');\n if (profile.hasBlockquote) names.add('videoPullQuote');\n }\n\n if (profile.hasBlockquote) {\n anyContentSignal = true;\n names.add('quote');\n names.add('pullQuote');\n names.add('fullBleedQuote');\n }\n\n if (profile.hasList) {\n anyContentSignal = true;\n names.add('list');\n }\n\n if (profile.hasTable) {\n anyContentSignal = true;\n names.add('dataTable');\n names.add('comparisonBar');\n }\n\n if (profile.hasDate) {\n anyContentSignal = true;\n names.add('dateEvent');\n }\n\n if (profile.hasNumberHighlight) {\n anyContentSignal = true;\n names.add('statHighlight');\n }\n\n if (anyContentSignal) {\n // Universal pair only — keep recommended focused.\n names.add('title');\n names.add('sectionHeader');\n } else {\n for (const n of UNIVERSAL_DEFAULTS) names.add(n);\n }\n\n return Array.from(names);\n}\n\n/**\n * Deterministic single-template choice for an unannotated heading block,\n * from strong content signals only. Returns `undefined` when no signal is\n * decisive — the caller keeps its structural default (`sectionHeader`).\n *\n * Precedence favors the most specific/structured content: a table beats\n * an image beats a blockquote beats a stat-looking line. `blockIndex`\n * alternates left/right feature composition for single-image blocks so a\n * run of image sections doesn't stack the same layout.\n *\n * Used by `markdownToDoc`'s auto template picking (see its `autoTemplates`\n * option); the multi-candidate `recommendTemplatesForBlock` below serves\n * the editor's template-picker UI instead.\n */\nexport function pickAutoTemplate(profile: BlockContentProfile, blockIndex = 0): string | undefined {\n if (profile.hasAsciiDiagram) return 'diagram';\n if (profile.hasTimeline) return 'timeline';\n if (profile.hasTree) return 'tree';\n if (profile.hasTable) return 'dataTable';\n if (profile.imageCount >= 2) return 'photoGrid';\n if (profile.hasImage) return blockIndex % 2 === 0 ? 'leftFeature' : 'rightFeature';\n if (profile.hasBlockquote) return 'quote';\n if (profile.hasNumberHighlight) return 'statHighlight';\n if (profile.hasList) return 'list';\n return undefined;\n}\n\n/**\n * Split a flat list of template names into a \"Recommended\" bucket\n * (matches the active block's content profile) and a \"rest\" bucket\n * (everything else). Both buckets preserve the input ordering of\n * `allNames`, so the visual layout stays predictable as templates are\n * added.\n */\nexport function recommendTemplatesForBlock(\n profile: BlockContentProfile,\n allNames: readonly string[],\n): RecommendationResult {\n const desired = new Set(recommendedNamesForProfile(profile));\n const recommended: string[] = [];\n const rest: string[] = [];\n for (const name of allNames) {\n if (desired.has(name)) recommended.push(name);\n else rest.push(name);\n }\n return { recommended, rest };\n}\n"],"mappings":"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","names":["slug","detectStyle","MAX_LINES","MAX_COLS","detectStyle","slugify","ch","slug","MAX_LINES","MIN_LINES"]}