@react-x11/components 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (783) hide show
  1. package/README.md +979 -21
  2. package/dist/ansi/cast.d.ts +48 -0
  3. package/dist/ansi/cast.d.ts.map +1 -0
  4. package/dist/ansi/cast.js +135 -0
  5. package/dist/ansi/cast.js.map +1 -0
  6. package/dist/ansi/index.d.ts +10 -0
  7. package/dist/ansi/index.d.ts.map +1 -0
  8. package/dist/ansi/index.js +27 -0
  9. package/dist/ansi/index.js.map +1 -0
  10. package/dist/ansi/palette.d.ts +79 -0
  11. package/dist/ansi/palette.d.ts.map +1 -0
  12. package/dist/ansi/palette.js +155 -0
  13. package/dist/ansi/palette.js.map +1 -0
  14. package/dist/ansi/parse.d.ts +114 -0
  15. package/dist/ansi/parse.d.ts.map +1 -0
  16. package/dist/ansi/parse.js +687 -0
  17. package/dist/ansi/parse.js.map +1 -0
  18. package/dist/ansi/sgr.d.ts +87 -0
  19. package/dist/ansi/sgr.d.ts.map +1 -0
  20. package/dist/ansi/sgr.js +302 -0
  21. package/dist/ansi/sgr.js.map +1 -0
  22. package/dist/ansi/utf8.d.ts +15 -0
  23. package/dist/ansi/utf8.d.ts.map +1 -0
  24. package/dist/ansi/utf8.js +82 -0
  25. package/dist/ansi/utf8.js.map +1 -0
  26. package/dist/calendar/Calendar.d.ts +136 -0
  27. package/dist/calendar/Calendar.d.ts.map +1 -0
  28. package/dist/calendar/Calendar.js +460 -0
  29. package/dist/calendar/Calendar.js.map +1 -0
  30. package/dist/calendar/DatePicker.d.ts +52 -0
  31. package/dist/calendar/DatePicker.d.ts.map +1 -0
  32. package/dist/calendar/DatePicker.js +257 -0
  33. package/dist/calendar/DatePicker.js.map +1 -0
  34. package/dist/calendar/dates.d.ts +90 -0
  35. package/dist/calendar/dates.d.ts.map +1 -0
  36. package/dist/calendar/dates.js +236 -0
  37. package/dist/calendar/dates.js.map +1 -0
  38. package/dist/calendar/index.d.ts +8 -0
  39. package/dist/calendar/index.d.ts.map +1 -0
  40. package/dist/calendar/index.js +15 -0
  41. package/dist/calendar/index.js.map +1 -0
  42. package/dist/charts/components.d.ts +141 -0
  43. package/dist/charts/components.d.ts.map +1 -0
  44. package/dist/charts/components.js +580 -0
  45. package/dist/charts/components.js.map +1 -0
  46. package/dist/charts/data.d.ts +198 -0
  47. package/dist/charts/data.d.ts.map +1 -0
  48. package/dist/charts/data.js +616 -0
  49. package/dist/charts/data.js.map +1 -0
  50. package/dist/charts/hx.d.ts +21 -0
  51. package/dist/charts/hx.d.ts.map +1 -0
  52. package/dist/charts/hx.js +15 -0
  53. package/dist/charts/hx.js.map +1 -0
  54. package/dist/charts/index.d.ts +27 -0
  55. package/dist/charts/index.d.ts.map +1 -0
  56. package/dist/charts/index.js +38 -0
  57. package/dist/charts/index.js.map +1 -0
  58. package/dist/charts/node.d.ts +96 -0
  59. package/dist/charts/node.d.ts.map +1 -0
  60. package/dist/charts/node.js +720 -0
  61. package/dist/charts/node.js.map +1 -0
  62. package/dist/charts/render.d.ts +153 -0
  63. package/dist/charts/render.d.ts.map +1 -0
  64. package/dist/charts/render.js +762 -0
  65. package/dist/charts/render.js.map +1 -0
  66. package/dist/charts/scale.d.ts +42 -0
  67. package/dist/charts/scale.d.ts.map +1 -0
  68. package/dist/charts/scale.js +173 -0
  69. package/dist/charts/scale.js.map +1 -0
  70. package/dist/charts/spec.d.ts +91 -0
  71. package/dist/charts/spec.d.ts.map +1 -0
  72. package/dist/charts/spec.js +33 -0
  73. package/dist/charts/spec.js.map +1 -0
  74. package/dist/charts/timers.d.ts +6 -0
  75. package/dist/charts/timers.d.ts.map +1 -0
  76. package/dist/charts/timers.js +14 -0
  77. package/dist/charts/timers.js.map +1 -0
  78. package/dist/code/hx.d.ts +24 -0
  79. package/dist/code/hx.d.ts.map +1 -0
  80. package/dist/code/hx.js +25 -0
  81. package/dist/code/hx.js.map +1 -0
  82. package/dist/code/index.d.ts +45 -0
  83. package/dist/code/index.d.ts.map +1 -0
  84. package/dist/code/index.js +93 -0
  85. package/dist/code/index.js.map +1 -0
  86. package/dist/code-editor/completion.d.ts +26 -0
  87. package/dist/code-editor/completion.d.ts.map +1 -0
  88. package/dist/code-editor/completion.js +129 -0
  89. package/dist/code-editor/completion.js.map +1 -0
  90. package/dist/code-editor/doc.d.ts +35 -0
  91. package/dist/code-editor/doc.d.ts.map +1 -0
  92. package/dist/code-editor/doc.js +162 -0
  93. package/dist/code-editor/doc.js.map +1 -0
  94. package/dist/code-editor/hx.d.ts +13 -0
  95. package/dist/code-editor/hx.d.ts.map +1 -0
  96. package/dist/code-editor/hx.js +10 -0
  97. package/dist/code-editor/hx.js.map +1 -0
  98. package/dist/code-editor/index.d.ts +88 -0
  99. package/dist/code-editor/index.d.ts.map +1 -0
  100. package/dist/code-editor/index.js +401 -0
  101. package/dist/code-editor/index.js.map +1 -0
  102. package/dist/code-editor/node.d.ts +343 -0
  103. package/dist/code-editor/node.d.ts.map +1 -0
  104. package/dist/code-editor/node.js +1521 -0
  105. package/dist/code-editor/node.js.map +1 -0
  106. package/dist/code-language/hljs.d.ts +47 -0
  107. package/dist/code-language/hljs.d.ts.map +1 -0
  108. package/dist/code-language/hljs.js +211 -0
  109. package/dist/code-language/hljs.js.map +1 -0
  110. package/dist/code-language/index.d.ts +22 -0
  111. package/dist/code-language/index.d.ts.map +1 -0
  112. package/dist/code-language/index.js +20 -0
  113. package/dist/code-language/index.js.map +1 -0
  114. package/dist/code-language/languages/glsl.d.ts +4 -0
  115. package/dist/code-language/languages/glsl.d.ts.map +1 -0
  116. package/dist/code-language/languages/glsl.js +99 -0
  117. package/dist/code-language/languages/glsl.js.map +1 -0
  118. package/dist/code-language/languages/javascript.d.ts +10 -0
  119. package/dist/code-language/languages/javascript.d.ts.map +1 -0
  120. package/dist/code-language/languages/javascript.js +360 -0
  121. package/dist/code-language/languages/javascript.js.map +1 -0
  122. package/dist/code-language/languages/json.d.ts +4 -0
  123. package/dist/code-language/languages/json.d.ts.map +1 -0
  124. package/dist/code-language/languages/json.js +68 -0
  125. package/dist/code-language/languages/json.js.map +1 -0
  126. package/dist/code-language/languages/shell.d.ts +4 -0
  127. package/dist/code-language/languages/shell.d.ts.map +1 -0
  128. package/dist/code-language/languages/shell.js +189 -0
  129. package/dist/code-language/languages/shell.js.map +1 -0
  130. package/dist/code-language/languages/sql.d.ts +11 -0
  131. package/dist/code-language/languages/sql.d.ts.map +1 -0
  132. package/dist/code-language/languages/sql.js +133 -0
  133. package/dist/code-language/languages/sql.js.map +1 -0
  134. package/dist/code-language/lezer.d.ts +24 -0
  135. package/dist/code-language/lezer.d.ts.map +1 -0
  136. package/dist/code-language/lezer.js +148 -0
  137. package/dist/code-language/lezer.js.map +1 -0
  138. package/dist/code-language/registry.d.ts +19 -0
  139. package/dist/code-language/registry.d.ts.map +1 -0
  140. package/dist/code-language/registry.js +56 -0
  141. package/dist/code-language/registry.js.map +1 -0
  142. package/dist/code-language/runs.d.ts +35 -0
  143. package/dist/code-language/runs.d.ts.map +1 -0
  144. package/dist/code-language/runs.js +88 -0
  145. package/dist/code-language/runs.js.map +1 -0
  146. package/dist/code-language/stream.d.ts +70 -0
  147. package/dist/code-language/stream.d.ts.map +1 -0
  148. package/dist/code-language/stream.js +243 -0
  149. package/dist/code-language/stream.js.map +1 -0
  150. package/dist/code-language/textmate.d.ts +27 -0
  151. package/dist/code-language/textmate.d.ts.map +1 -0
  152. package/dist/code-language/textmate.js +86 -0
  153. package/dist/code-language/textmate.js.map +1 -0
  154. package/dist/code-language/theme.d.ts +26 -0
  155. package/dist/code-language/theme.d.ts.map +1 -0
  156. package/dist/code-language/theme.js +108 -0
  157. package/dist/code-language/theme.js.map +1 -0
  158. package/dist/code-language/timers.d.ts +7 -0
  159. package/dist/code-language/timers.d.ts.map +1 -0
  160. package/dist/code-language/timers.js +22 -0
  161. package/dist/code-language/timers.js.map +1 -0
  162. package/dist/code-language/types.d.ts +173 -0
  163. package/dist/code-language/types.d.ts.map +1 -0
  164. package/dist/code-language/types.js +41 -0
  165. package/dist/code-language/types.js.map +1 -0
  166. package/dist/codeblock/index.d.ts +69 -0
  167. package/dist/codeblock/index.d.ts.map +1 -0
  168. package/dist/codeblock/index.js +85 -0
  169. package/dist/codeblock/index.js.map +1 -0
  170. package/dist/color-picker/ColorField.d.ts +39 -0
  171. package/dist/color-picker/ColorField.d.ts.map +1 -0
  172. package/dist/color-picker/ColorField.js +239 -0
  173. package/dist/color-picker/ColorField.js.map +1 -0
  174. package/dist/color-picker/ColorPicker.d.ts +109 -0
  175. package/dist/color-picker/ColorPicker.d.ts.map +1 -0
  176. package/dist/color-picker/ColorPicker.js +757 -0
  177. package/dist/color-picker/ColorPicker.js.map +1 -0
  178. package/dist/color-picker/color.d.ts +105 -0
  179. package/dist/color-picker/color.d.ts.map +1 -0
  180. package/dist/color-picker/color.js +313 -0
  181. package/dist/color-picker/color.js.map +1 -0
  182. package/dist/color-picker/index.d.ts +8 -0
  183. package/dist/color-picker/index.d.ts.map +1 -0
  184. package/dist/color-picker/index.js +19 -0
  185. package/dist/color-picker/index.js.map +1 -0
  186. package/dist/desktop-calendar/eds.d.ts +102 -0
  187. package/dist/desktop-calendar/eds.d.ts.map +1 -0
  188. package/dist/desktop-calendar/eds.js +356 -0
  189. package/dist/desktop-calendar/eds.js.map +1 -0
  190. package/dist/desktop-calendar/ical.d.ts +63 -0
  191. package/dist/desktop-calendar/ical.d.ts.map +1 -0
  192. package/dist/desktop-calendar/ical.js +57 -0
  193. package/dist/desktop-calendar/ical.js.map +1 -0
  194. package/dist/desktop-calendar/index.d.ts +72 -0
  195. package/dist/desktop-calendar/index.d.ts.map +1 -0
  196. package/dist/desktop-calendar/index.js +213 -0
  197. package/dist/desktop-calendar/index.js.map +1 -0
  198. package/dist/embed/client.d.ts +121 -0
  199. package/dist/embed/client.d.ts.map +1 -0
  200. package/dist/embed/client.js +203 -0
  201. package/dist/embed/client.js.map +1 -0
  202. package/dist/embed/host.d.ts +96 -0
  203. package/dist/embed/host.d.ts.map +1 -0
  204. package/dist/embed/host.js +266 -0
  205. package/dist/embed/host.js.map +1 -0
  206. package/dist/embed/index.d.ts +5 -0
  207. package/dist/embed/index.d.ts.map +1 -0
  208. package/dist/embed/index.js +13 -0
  209. package/dist/embed/index.js.map +1 -0
  210. package/dist/embed/timers.d.ts +6 -0
  211. package/dist/embed/timers.d.ts.map +1 -0
  212. package/dist/embed/timers.js +16 -0
  213. package/dist/embed/timers.js.map +1 -0
  214. package/dist/flow/draw.d.ts +45 -0
  215. package/dist/flow/draw.d.ts.map +1 -0
  216. package/dist/flow/draw.js +295 -0
  217. package/dist/flow/draw.js.map +1 -0
  218. package/dist/flow/index.d.ts +64 -0
  219. package/dist/flow/index.d.ts.map +1 -0
  220. package/dist/flow/index.js +306 -0
  221. package/dist/flow/index.js.map +1 -0
  222. package/dist/flow/model.d.ts +158 -0
  223. package/dist/flow/model.d.ts.map +1 -0
  224. package/dist/flow/model.js +566 -0
  225. package/dist/flow/model.js.map +1 -0
  226. package/dist/flow/node.d.ts +429 -0
  227. package/dist/flow/node.d.ts.map +1 -0
  228. package/dist/flow/node.js +3025 -0
  229. package/dist/flow/node.js.map +1 -0
  230. package/dist/flow/paths.d.ts +43 -0
  231. package/dist/flow/paths.d.ts.map +1 -0
  232. package/dist/flow/paths.js +327 -0
  233. package/dist/flow/paths.js.map +1 -0
  234. package/dist/flow/types.d.ts +561 -0
  235. package/dist/flow/types.d.ts.map +1 -0
  236. package/dist/flow/types.js +2 -0
  237. package/dist/flow/types.js.map +1 -0
  238. package/dist/formula/hx.d.ts +24 -0
  239. package/dist/formula/hx.d.ts.map +1 -0
  240. package/dist/formula/hx.js +25 -0
  241. package/dist/formula/hx.js.map +1 -0
  242. package/dist/formula/index.d.ts +74 -0
  243. package/dist/formula/index.d.ts.map +1 -0
  244. package/dist/formula/index.js +155 -0
  245. package/dist/formula/index.js.map +1 -0
  246. package/dist/formula/katex.d.ts +78 -0
  247. package/dist/formula/katex.d.ts.map +1 -0
  248. package/dist/formula/katex.js +130 -0
  249. package/dist/formula/katex.js.map +1 -0
  250. package/dist/formula/layout.d.ts +103 -0
  251. package/dist/formula/layout.d.ts.map +1 -0
  252. package/dist/formula/layout.js +716 -0
  253. package/dist/formula/layout.js.map +1 -0
  254. package/dist/formula/node.d.ts +50 -0
  255. package/dist/formula/node.d.ts.map +1 -0
  256. package/dist/formula/node.js +351 -0
  257. package/dist/formula/node.js.map +1 -0
  258. package/dist/html/controls.d.ts +48 -0
  259. package/dist/html/controls.d.ts.map +1 -0
  260. package/dist/html/controls.js +195 -0
  261. package/dist/html/controls.js.map +1 -0
  262. package/dist/html/css/cascade.d.ts +51 -0
  263. package/dist/html/css/cascade.d.ts.map +1 -0
  264. package/dist/html/css/cascade.js +552 -0
  265. package/dist/html/css/cascade.js.map +1 -0
  266. package/dist/html/css/parse.d.ts +74 -0
  267. package/dist/html/css/parse.d.ts.map +1 -0
  268. package/dist/html/css/parse.js +464 -0
  269. package/dist/html/css/parse.js.map +1 -0
  270. package/dist/html/css/style.d.ts +142 -0
  271. package/dist/html/css/style.d.ts.map +1 -0
  272. package/dist/html/css/style.js +1145 -0
  273. package/dist/html/css/style.js.map +1 -0
  274. package/dist/html/css/ua.d.ts +5 -0
  275. package/dist/html/css/ua.d.ts.map +1 -0
  276. package/dist/html/css/ua.js +171 -0
  277. package/dist/html/css/ua.js.map +1 -0
  278. package/dist/html/css/values.d.ts +78 -0
  279. package/dist/html/css/values.d.ts.map +1 -0
  280. package/dist/html/css/values.js +330 -0
  281. package/dist/html/css/values.js.map +1 -0
  282. package/dist/html/dom.d.ts +112 -0
  283. package/dist/html/dom.d.ts.map +1 -0
  284. package/dist/html/dom.js +374 -0
  285. package/dist/html/dom.js.map +1 -0
  286. package/dist/html/hx.d.ts +24 -0
  287. package/dist/html/hx.d.ts.map +1 -0
  288. package/dist/html/hx.js +29 -0
  289. package/dist/html/hx.js.map +1 -0
  290. package/dist/html/index.d.ts +137 -0
  291. package/dist/html/index.d.ts.map +1 -0
  292. package/dist/html/index.js +339 -0
  293. package/dist/html/index.js.map +1 -0
  294. package/dist/html/layout/block.d.ts +58 -0
  295. package/dist/html/layout/block.d.ts.map +1 -0
  296. package/dist/html/layout/block.js +724 -0
  297. package/dist/html/layout/block.js.map +1 -0
  298. package/dist/html/layout/boxes.d.ts +261 -0
  299. package/dist/html/layout/boxes.d.ts.map +1 -0
  300. package/dist/html/layout/boxes.js +725 -0
  301. package/dist/html/layout/boxes.js.map +1 -0
  302. package/dist/html/layout/flex.d.ts +16 -0
  303. package/dist/html/layout/flex.d.ts.map +1 -0
  304. package/dist/html/layout/flex.js +242 -0
  305. package/dist/html/layout/flex.js.map +1 -0
  306. package/dist/html/layout/floats.d.ts +50 -0
  307. package/dist/html/layout/floats.d.ts.map +1 -0
  308. package/dist/html/layout/floats.js +110 -0
  309. package/dist/html/layout/floats.js.map +1 -0
  310. package/dist/html/layout/inline.d.ts +44 -0
  311. package/dist/html/layout/inline.d.ts.map +1 -0
  312. package/dist/html/layout/inline.js +700 -0
  313. package/dist/html/layout/inline.js.map +1 -0
  314. package/dist/html/layout/table.d.ts +5 -0
  315. package/dist/html/layout/table.d.ts.map +1 -0
  316. package/dist/html/layout/table.js +340 -0
  317. package/dist/html/layout/table.js.map +1 -0
  318. package/dist/html/node.d.ts +149 -0
  319. package/dist/html/node.d.ts.map +1 -0
  320. package/dist/html/node.js +861 -0
  321. package/dist/html/node.js.map +1 -0
  322. package/dist/html/paint.d.ts +48 -0
  323. package/dist/html/paint.d.ts.map +1 -0
  324. package/dist/html/paint.js +495 -0
  325. package/dist/html/paint.js.map +1 -0
  326. package/dist/html/resources.d.ts +48 -0
  327. package/dist/html/resources.d.ts.map +1 -0
  328. package/dist/html/resources.js +156 -0
  329. package/dist/html/resources.js.map +1 -0
  330. package/dist/index.d.ts +48 -0
  331. package/dist/index.d.ts.map +1 -0
  332. package/dist/index.js +92 -0
  333. package/dist/index.js.map +1 -0
  334. package/dist/internal/heights.d.ts +81 -0
  335. package/dist/internal/heights.d.ts.map +1 -0
  336. package/dist/internal/heights.js +193 -0
  337. package/dist/internal/heights.js.map +1 -0
  338. package/dist/internal/hx.d.ts +24 -0
  339. package/dist/internal/hx.d.ts.map +1 -0
  340. package/dist/internal/hx.js +27 -0
  341. package/dist/internal/hx.js.map +1 -0
  342. package/dist/internal/text.d.ts +6 -0
  343. package/dist/internal/text.d.ts.map +1 -0
  344. package/dist/internal/text.js +44 -0
  345. package/dist/internal/text.js.map +1 -0
  346. package/dist/internal/timers.d.ts +8 -0
  347. package/dist/internal/timers.d.ts.map +1 -0
  348. package/dist/internal/timers.js +22 -0
  349. package/dist/internal/timers.js.map +1 -0
  350. package/dist/internal/widget.d.ts +40 -0
  351. package/dist/internal/widget.d.ts.map +1 -0
  352. package/dist/internal/widget.js +44 -0
  353. package/dist/internal/widget.js.map +1 -0
  354. package/dist/markdown/ast.d.ts +126 -0
  355. package/dist/markdown/ast.d.ts.map +1 -0
  356. package/dist/markdown/ast.js +8 -0
  357. package/dist/markdown/ast.js.map +1 -0
  358. package/dist/markdown/hx.d.ts +24 -0
  359. package/dist/markdown/hx.d.ts.map +1 -0
  360. package/dist/markdown/hx.js +25 -0
  361. package/dist/markdown/hx.js.map +1 -0
  362. package/dist/markdown/index.d.ts +90 -0
  363. package/dist/markdown/index.d.ts.map +1 -0
  364. package/dist/markdown/index.js +413 -0
  365. package/dist/markdown/index.js.map +1 -0
  366. package/dist/markdown/parse.d.ts +8 -0
  367. package/dist/markdown/parse.d.ts.map +1 -0
  368. package/dist/markdown/parse.js +911 -0
  369. package/dist/markdown/parse.js.map +1 -0
  370. package/dist/markdown/spans.d.ts +20 -0
  371. package/dist/markdown/spans.d.ts.map +1 -0
  372. package/dist/markdown/spans.js +96 -0
  373. package/dist/markdown/spans.js.map +1 -0
  374. package/dist/media-player/backends.d.ts +64 -0
  375. package/dist/media-player/backends.d.ts.map +1 -0
  376. package/dist/media-player/backends.js +110 -0
  377. package/dist/media-player/backends.js.map +1 -0
  378. package/dist/media-player/control.d.ts +40 -0
  379. package/dist/media-player/control.d.ts.map +1 -0
  380. package/dist/media-player/control.js +44 -0
  381. package/dist/media-player/control.js.map +1 -0
  382. package/dist/media-player/hx.d.ts +24 -0
  383. package/dist/media-player/hx.d.ts.map +1 -0
  384. package/dist/media-player/hx.js +25 -0
  385. package/dist/media-player/hx.js.map +1 -0
  386. package/dist/media-player/index.d.ts +107 -0
  387. package/dist/media-player/index.d.ts.map +1 -0
  388. package/dist/media-player/index.js +219 -0
  389. package/dist/media-player/index.js.map +1 -0
  390. package/dist/media-player/mpv.d.ts +4 -0
  391. package/dist/media-player/mpv.d.ts.map +1 -0
  392. package/dist/media-player/mpv.js +120 -0
  393. package/dist/media-player/mpv.js.map +1 -0
  394. package/dist/media-player/vlc.d.ts +8 -0
  395. package/dist/media-player/vlc.d.ts.map +1 -0
  396. package/dist/media-player/vlc.js +83 -0
  397. package/dist/media-player/vlc.js.map +1 -0
  398. package/dist/richtext/index.d.ts +19 -0
  399. package/dist/richtext/index.d.ts.map +1 -0
  400. package/dist/richtext/index.js +4 -0
  401. package/dist/richtext/index.js.map +1 -0
  402. package/dist/richtext/links.d.ts +12 -0
  403. package/dist/richtext/links.d.ts.map +1 -0
  404. package/dist/richtext/links.js +64 -0
  405. package/dist/richtext/links.js.map +1 -0
  406. package/dist/richtext/menu.d.ts +11 -0
  407. package/dist/richtext/menu.d.ts.map +1 -0
  408. package/dist/richtext/menu.js +43 -0
  409. package/dist/richtext/menu.js.map +1 -0
  410. package/dist/richtext/node.d.ts +151 -0
  411. package/dist/richtext/node.d.ts.map +1 -0
  412. package/dist/richtext/node.js +255 -0
  413. package/dist/richtext/node.js.map +1 -0
  414. package/dist/richtext/runs.d.ts +92 -0
  415. package/dist/richtext/runs.d.ts.map +1 -0
  416. package/dist/richtext/runs.js +158 -0
  417. package/dist/richtext/runs.js.map +1 -0
  418. package/dist/table/hx.d.ts +24 -0
  419. package/dist/table/hx.d.ts.map +1 -0
  420. package/dist/table/hx.js +25 -0
  421. package/dist/table/hx.js.map +1 -0
  422. package/dist/table/index.d.ts +169 -0
  423. package/dist/table/index.d.ts.map +1 -0
  424. package/dist/table/index.js +844 -0
  425. package/dist/table/index.js.map +1 -0
  426. package/dist/table/rows.d.ts +136 -0
  427. package/dist/table/rows.d.ts.map +1 -0
  428. package/dist/table/rows.js +146 -0
  429. package/dist/table/rows.js.map +1 -0
  430. package/dist/terminal/backends.d.ts +105 -0
  431. package/dist/terminal/backends.d.ts.map +1 -0
  432. package/dist/terminal/backends.js +185 -0
  433. package/dist/terminal/backends.js.map +1 -0
  434. package/dist/terminal/hx.d.ts +24 -0
  435. package/dist/terminal/hx.d.ts.map +1 -0
  436. package/dist/terminal/hx.js +25 -0
  437. package/dist/terminal/hx.js.map +1 -0
  438. package/dist/terminal/index.d.ts +160 -0
  439. package/dist/terminal/index.d.ts.map +1 -0
  440. package/dist/terminal/index.js +344 -0
  441. package/dist/terminal/index.js.map +1 -0
  442. package/dist/terminal/title.d.ts +24 -0
  443. package/dist/terminal/title.d.ts.map +1 -0
  444. package/dist/terminal/title.js +129 -0
  445. package/dist/terminal/title.js.map +1 -0
  446. package/dist/terminal/vt/colors.d.ts +63 -0
  447. package/dist/terminal/vt/colors.d.ts.map +1 -0
  448. package/dist/terminal/vt/colors.js +203 -0
  449. package/dist/terminal/vt/colors.js.map +1 -0
  450. package/dist/terminal/vt/diff.d.ts +117 -0
  451. package/dist/terminal/vt/diff.d.ts.map +1 -0
  452. package/dist/terminal/vt/diff.js +358 -0
  453. package/dist/terminal/vt/diff.js.map +1 -0
  454. package/dist/terminal/vt/fonts.d.ts +92 -0
  455. package/dist/terminal/vt/fonts.d.ts.map +1 -0
  456. package/dist/terminal/vt/fonts.js +178 -0
  457. package/dist/terminal/vt/fonts.js.map +1 -0
  458. package/dist/terminal/vt/index.d.ts +78 -0
  459. package/dist/terminal/vt/index.d.ts.map +1 -0
  460. package/dist/terminal/vt/index.js +312 -0
  461. package/dist/terminal/vt/index.js.map +1 -0
  462. package/dist/terminal/vt/keys.d.ts +74 -0
  463. package/dist/terminal/vt/keys.d.ts.map +1 -0
  464. package/dist/terminal/vt/keys.js +309 -0
  465. package/dist/terminal/vt/keys.js.map +1 -0
  466. package/dist/terminal/vt/mouse.d.ts +44 -0
  467. package/dist/terminal/vt/mouse.d.ts.map +1 -0
  468. package/dist/terminal/vt/mouse.js +106 -0
  469. package/dist/terminal/vt/mouse.js.map +1 -0
  470. package/dist/terminal/vt/node.d.ts +246 -0
  471. package/dist/terminal/vt/node.d.ts.map +1 -0
  472. package/dist/terminal/vt/node.js +1068 -0
  473. package/dist/terminal/vt/node.js.map +1 -0
  474. package/dist/terminal/vt/pty.d.ts +81 -0
  475. package/dist/terminal/vt/pty.d.ts.map +1 -0
  476. package/dist/terminal/vt/pty.js +201 -0
  477. package/dist/terminal/vt/pty.js.map +1 -0
  478. package/dist/terminal/vt/renderer.d.ts +179 -0
  479. package/dist/terminal/vt/renderer.d.ts.map +1 -0
  480. package/dist/terminal/vt/renderer.js +357 -0
  481. package/dist/terminal/vt/renderer.js.map +1 -0
  482. package/dist/terminal/vt/timers.d.ts +6 -0
  483. package/dist/terminal/vt/timers.d.ts.map +1 -0
  484. package/dist/terminal/vt/timers.js +16 -0
  485. package/dist/terminal/vt/timers.js.map +1 -0
  486. package/dist/terminal/vt/xterm.d.ts +142 -0
  487. package/dist/terminal/vt/xterm.d.ts.map +1 -0
  488. package/dist/terminal/vt/xterm.js +32 -0
  489. package/dist/terminal/vt/xterm.js.map +1 -0
  490. package/dist/terminal-output/hx.d.ts +24 -0
  491. package/dist/terminal-output/hx.d.ts.map +1 -0
  492. package/dist/terminal-output/hx.js +25 -0
  493. package/dist/terminal-output/hx.js.map +1 -0
  494. package/dist/terminal-output/index.d.ts +92 -0
  495. package/dist/terminal-output/index.d.ts.map +1 -0
  496. package/dist/terminal-output/index.js +179 -0
  497. package/dist/terminal-output/index.js.map +1 -0
  498. package/dist/terminal-output/runs.d.ts +27 -0
  499. package/dist/terminal-output/runs.d.ts.map +1 -0
  500. package/dist/terminal-output/runs.js +66 -0
  501. package/dist/terminal-output/runs.js.map +1 -0
  502. package/dist/three/canvas.d.ts +46 -0
  503. package/dist/three/canvas.d.ts.map +1 -0
  504. package/dist/three/canvas.js +305 -0
  505. package/dist/three/canvas.js.map +1 -0
  506. package/dist/three/events.d.ts +64 -0
  507. package/dist/three/events.d.ts.map +1 -0
  508. package/dist/three/events.js +146 -0
  509. package/dist/three/events.js.map +1 -0
  510. package/dist/three/geometries.d.ts +89 -0
  511. package/dist/three/geometries.d.ts.map +1 -0
  512. package/dist/three/geometries.js +345 -0
  513. package/dist/three/geometries.js.map +1 -0
  514. package/dist/three/globals.d.ts +7 -0
  515. package/dist/three/globals.d.ts.map +1 -0
  516. package/dist/three/globals.js +20 -0
  517. package/dist/three/globals.js.map +1 -0
  518. package/dist/three/hx.d.ts +9 -0
  519. package/dist/three/hx.d.ts.map +1 -0
  520. package/dist/three/hx.js +10 -0
  521. package/dist/three/hx.js.map +1 -0
  522. package/dist/three/index.d.ts +22 -0
  523. package/dist/three/index.d.ts.map +1 -0
  524. package/dist/three/index.js +24 -0
  525. package/dist/three/index.js.map +1 -0
  526. package/dist/three/jsx-dev-runtime.d.ts +19 -0
  527. package/dist/three/jsx-dev-runtime.d.ts.map +1 -0
  528. package/dist/three/jsx-dev-runtime.js +2 -0
  529. package/dist/three/jsx-dev-runtime.js.map +1 -0
  530. package/dist/three/jsx-runtime.d.ts +19 -0
  531. package/dist/three/jsx-runtime.d.ts.map +1 -0
  532. package/dist/three/jsx-runtime.js +2 -0
  533. package/dist/three/jsx-runtime.js.map +1 -0
  534. package/dist/three/jsx.d.ts +198 -0
  535. package/dist/three/jsx.d.ts.map +1 -0
  536. package/dist/three/jsx.js +2 -0
  537. package/dist/three/jsx.js.map +1 -0
  538. package/dist/three/materials.d.ts +125 -0
  539. package/dist/three/materials.d.ts.map +1 -0
  540. package/dist/three/materials.js +229 -0
  541. package/dist/three/materials.js.map +1 -0
  542. package/dist/three/math.d.ts +146 -0
  543. package/dist/three/math.d.ts.map +1 -0
  544. package/dist/three/math.js +464 -0
  545. package/dist/three/math.js.map +1 -0
  546. package/dist/three/objects.d.ts +185 -0
  547. package/dist/three/objects.d.ts.map +1 -0
  548. package/dist/three/objects.js +309 -0
  549. package/dist/three/objects.js.map +1 -0
  550. package/dist/three/passes.d.ts +54 -0
  551. package/dist/three/passes.d.ts.map +1 -0
  552. package/dist/three/passes.js +78 -0
  553. package/dist/three/passes.js.map +1 -0
  554. package/dist/three/postprocess.d.ts +85 -0
  555. package/dist/three/postprocess.d.ts.map +1 -0
  556. package/dist/three/postprocess.js +503 -0
  557. package/dist/three/postprocess.js.map +1 -0
  558. package/dist/three/raycast.d.ts +24 -0
  559. package/dist/three/raycast.d.ts.map +1 -0
  560. package/dist/three/raycast.js +138 -0
  561. package/dist/three/raycast.js.map +1 -0
  562. package/dist/three/reconciler.d.ts +48 -0
  563. package/dist/three/reconciler.d.ts.map +1 -0
  564. package/dist/three/reconciler.js +416 -0
  565. package/dist/three/reconciler.js.map +1 -0
  566. package/dist/three/renderer-direct.d.ts +102 -0
  567. package/dist/three/renderer-direct.d.ts.map +1 -0
  568. package/dist/three/renderer-direct.js +782 -0
  569. package/dist/three/renderer-direct.js.map +1 -0
  570. package/dist/three/renderer-indirect.d.ts +68 -0
  571. package/dist/three/renderer-indirect.d.ts.map +1 -0
  572. package/dist/three/renderer-indirect.js +438 -0
  573. package/dist/three/renderer-indirect.js.map +1 -0
  574. package/dist/three/store.d.ts +81 -0
  575. package/dist/three/store.d.ts.map +1 -0
  576. package/dist/three/store.js +110 -0
  577. package/dist/three/store.js.map +1 -0
  578. package/dist/timeline/hx.d.ts +18 -0
  579. package/dist/timeline/hx.d.ts.map +1 -0
  580. package/dist/timeline/hx.js +10 -0
  581. package/dist/timeline/hx.js.map +1 -0
  582. package/dist/timeline/index.d.ts +152 -0
  583. package/dist/timeline/index.d.ts.map +1 -0
  584. package/dist/timeline/index.js +383 -0
  585. package/dist/timeline/index.js.map +1 -0
  586. package/dist/tray-host/hx.d.ts +24 -0
  587. package/dist/tray-host/hx.d.ts.map +1 -0
  588. package/dist/tray-host/hx.js +25 -0
  589. package/dist/tray-host/hx.js.map +1 -0
  590. package/dist/tray-host/index.d.ts +110 -0
  591. package/dist/tray-host/index.d.ts.map +1 -0
  592. package/dist/tray-host/index.js +191 -0
  593. package/dist/tray-host/index.js.map +1 -0
  594. package/dist/tray-host/manager.d.ts +137 -0
  595. package/dist/tray-host/manager.d.ts.map +1 -0
  596. package/dist/tray-host/manager.js +462 -0
  597. package/dist/tray-host/manager.js.map +1 -0
  598. package/dist/tray-host/notify.d.ts +22 -0
  599. package/dist/tray-host/notify.d.ts.map +1 -0
  600. package/dist/tray-host/notify.js +74 -0
  601. package/dist/tray-host/notify.js.map +1 -0
  602. package/dist/tray-host/protocol.d.ts +106 -0
  603. package/dist/tray-host/protocol.d.ts.map +1 -0
  604. package/dist/tray-host/protocol.js +191 -0
  605. package/dist/tray-host/protocol.js.map +1 -0
  606. package/dist/tree/hx.d.ts +24 -0
  607. package/dist/tree/hx.d.ts.map +1 -0
  608. package/dist/tree/hx.js +25 -0
  609. package/dist/tree/hx.js.map +1 -0
  610. package/dist/tree/index.d.ts +221 -0
  611. package/dist/tree/index.d.ts.map +1 -0
  612. package/dist/tree/index.js +716 -0
  613. package/dist/tree/index.js.map +1 -0
  614. package/dist/tree/internal.d.ts +18 -0
  615. package/dist/tree/internal.d.ts.map +1 -0
  616. package/dist/tree/internal.js +66 -0
  617. package/dist/tree/internal.js.map +1 -0
  618. package/dist/tree/rows.d.ts +177 -0
  619. package/dist/tree/rows.d.ts.map +1 -0
  620. package/dist/tree/rows.js +179 -0
  621. package/dist/tree/rows.js.map +1 -0
  622. package/package.json +166 -12
  623. package/src/ansi/cast.ts +159 -0
  624. package/src/ansi/index.ts +53 -0
  625. package/src/ansi/palette.ts +226 -0
  626. package/src/ansi/parse.ts +780 -0
  627. package/src/ansi/sgr.ts +380 -0
  628. package/src/ansi/utf8.ts +84 -0
  629. package/src/calendar/Calendar.ts +744 -0
  630. package/src/calendar/DatePicker.ts +368 -0
  631. package/src/calendar/dates.ts +307 -0
  632. package/src/calendar/index.ts +51 -0
  633. package/src/charts/components.ts +864 -0
  634. package/src/charts/data.ts +776 -0
  635. package/src/charts/hx.ts +39 -0
  636. package/src/charts/index.ts +99 -0
  637. package/src/charts/node.ts +932 -0
  638. package/src/charts/render.ts +982 -0
  639. package/src/charts/scale.ts +214 -0
  640. package/src/charts/spec.ts +122 -0
  641. package/src/charts/timers.ts +24 -0
  642. package/src/code/hx.ts +51 -0
  643. package/src/code/index.ts +174 -0
  644. package/src/code-editor/completion.ts +161 -0
  645. package/src/code-editor/doc.ts +198 -0
  646. package/src/code-editor/hx.ts +26 -0
  647. package/src/code-editor/index.ts +615 -0
  648. package/src/code-editor/node.ts +1926 -0
  649. package/src/code-language/hljs.ts +302 -0
  650. package/src/code-language/index.ts +51 -0
  651. package/src/code-language/languages/glsl.ts +120 -0
  652. package/src/code-language/languages/javascript.ts +419 -0
  653. package/src/code-language/languages/json.ts +72 -0
  654. package/src/code-language/languages/shell.ts +221 -0
  655. package/src/code-language/languages/sql.ts +165 -0
  656. package/src/code-language/lezer.ts +190 -0
  657. package/src/code-language/registry.ts +66 -0
  658. package/src/code-language/runs.ts +128 -0
  659. package/src/code-language/stream.ts +306 -0
  660. package/src/code-language/textmate.ts +134 -0
  661. package/src/code-language/theme.ts +124 -0
  662. package/src/code-language/timers.ts +36 -0
  663. package/src/code-language/types.ts +252 -0
  664. package/src/codeblock/index.ts +146 -0
  665. package/src/color-picker/ColorField.ts +333 -0
  666. package/src/color-picker/ColorPicker.ts +1069 -0
  667. package/src/color-picker/color.ts +399 -0
  668. package/src/color-picker/index.ts +50 -0
  669. package/src/desktop-calendar/eds.ts +484 -0
  670. package/src/desktop-calendar/ical.ts +119 -0
  671. package/src/desktop-calendar/index.ts +287 -0
  672. package/src/embed/client.ts +311 -0
  673. package/src/embed/host.ts +432 -0
  674. package/src/embed/index.ts +33 -0
  675. package/src/embed/timers.ts +32 -0
  676. package/src/flow/draw.ts +418 -0
  677. package/src/flow/index.ts +473 -0
  678. package/src/flow/model.ts +687 -0
  679. package/src/flow/node.ts +3694 -0
  680. package/src/flow/paths.ts +403 -0
  681. package/src/flow/types.ts +634 -0
  682. package/src/formula/hx.ts +51 -0
  683. package/src/formula/index.ts +243 -0
  684. package/src/formula/katex.ts +209 -0
  685. package/src/formula/layout.ts +876 -0
  686. package/src/formula/node.ts +467 -0
  687. package/src/html/controls.ts +244 -0
  688. package/src/html/css/cascade.ts +606 -0
  689. package/src/html/css/parse.ts +500 -0
  690. package/src/html/css/style.ts +1371 -0
  691. package/src/html/css/ua.ts +174 -0
  692. package/src/html/css/values.ts +358 -0
  693. package/src/html/dom.ts +410 -0
  694. package/src/html/hx.ts +55 -0
  695. package/src/html/index.ts +545 -0
  696. package/src/html/layout/block.ts +876 -0
  697. package/src/html/layout/boxes.ts +981 -0
  698. package/src/html/layout/flex.ts +297 -0
  699. package/src/html/layout/floats.ts +125 -0
  700. package/src/html/layout/inline.ts +870 -0
  701. package/src/html/layout/table.ts +380 -0
  702. package/src/html/node.ts +967 -0
  703. package/src/html/paint.ts +605 -0
  704. package/src/html/resources.ts +214 -0
  705. package/src/index.ts +638 -0
  706. package/src/internal/heights.ts +211 -0
  707. package/src/internal/hx.ts +53 -0
  708. package/src/internal/text.ts +44 -0
  709. package/src/internal/timers.ts +44 -0
  710. package/src/internal/widget.ts +92 -0
  711. package/src/markdown/ast.ts +163 -0
  712. package/src/markdown/hx.ts +51 -0
  713. package/src/markdown/index.ts +686 -0
  714. package/src/markdown/parse.ts +1037 -0
  715. package/src/markdown/spans.ts +143 -0
  716. package/src/media-player/backends.ts +155 -0
  717. package/src/media-player/control.ts +70 -0
  718. package/src/media-player/hx.ts +51 -0
  719. package/src/media-player/index.ts +378 -0
  720. package/src/media-player/mpv.ts +146 -0
  721. package/src/media-player/vlc.ts +97 -0
  722. package/src/richtext/index.ts +42 -0
  723. package/src/richtext/links.ts +78 -0
  724. package/src/richtext/menu.ts +49 -0
  725. package/src/richtext/node.ts +406 -0
  726. package/src/richtext/runs.ts +253 -0
  727. package/src/table/hx.ts +51 -0
  728. package/src/table/index.ts +1219 -0
  729. package/src/table/rows.ts +275 -0
  730. package/src/terminal/backends.ts +242 -0
  731. package/src/terminal/hx.ts +51 -0
  732. package/src/terminal/index.ts +574 -0
  733. package/src/terminal/title.ts +172 -0
  734. package/src/terminal/vt/colors.ts +247 -0
  735. package/src/terminal/vt/diff.ts +467 -0
  736. package/src/terminal/vt/fonts.ts +233 -0
  737. package/src/terminal/vt/index.ts +443 -0
  738. package/src/terminal/vt/keys.ts +369 -0
  739. package/src/terminal/vt/mouse.ts +144 -0
  740. package/src/terminal/vt/node.ts +1242 -0
  741. package/src/terminal/vt/pty.ts +334 -0
  742. package/src/terminal/vt/renderer.ts +555 -0
  743. package/src/terminal/vt/timers.ts +31 -0
  744. package/src/terminal/vt/xterm.ts +193 -0
  745. package/src/terminal-output/hx.ts +51 -0
  746. package/src/terminal-output/index.ts +340 -0
  747. package/src/terminal-output/runs.ts +79 -0
  748. package/src/three/canvas.ts +451 -0
  749. package/src/three/events.ts +197 -0
  750. package/src/three/geometries.ts +429 -0
  751. package/src/three/globals.ts +34 -0
  752. package/src/three/hx.ts +22 -0
  753. package/src/three/index.ts +98 -0
  754. package/src/three/jsx-dev-runtime.ts +27 -0
  755. package/src/three/jsx-runtime.ts +38 -0
  756. package/src/three/jsx.ts +275 -0
  757. package/src/three/materials.ts +270 -0
  758. package/src/three/math.ts +585 -0
  759. package/src/three/objects.ts +397 -0
  760. package/src/three/passes.ts +90 -0
  761. package/src/three/postprocess.ts +677 -0
  762. package/src/three/raycast.ts +189 -0
  763. package/src/three/react-reconciler.d.ts +50 -0
  764. package/src/three/reconciler.ts +624 -0
  765. package/src/three/renderer-direct.ts +1055 -0
  766. package/src/three/renderer-indirect.ts +570 -0
  767. package/src/three/store.ts +207 -0
  768. package/src/timeline/hx.ts +31 -0
  769. package/src/timeline/index.ts +603 -0
  770. package/src/tray-host/hx.ts +51 -0
  771. package/src/tray-host/index.ts +331 -0
  772. package/src/tray-host/manager.ts +639 -0
  773. package/src/tray-host/notify.ts +102 -0
  774. package/src/tray-host/protocol.ts +235 -0
  775. package/src/tree/hx.ts +51 -0
  776. package/src/tree/index.ts +1087 -0
  777. package/src/tree/internal.ts +87 -0
  778. package/src/tree/rows.ts +334 -0
  779. package/src/index.d.ts +0 -2
  780. package/src/index.js +0 -9
  781. package/src/sparkline/index.d.ts +0 -29
  782. package/src/sparkline/index.js +0 -50
  783. package/src/sparkline/node.js +0 -72
@@ -0,0 +1,1037 @@
1
+ // Markdown → AST, written for this component rather than adapted from a
2
+ // DOM-shaped pipeline. GFM-flavoured CommonMark: headings (ATX and setext),
3
+ // paragraphs, fenced and indented code, blockquotes with lazy continuation,
4
+ // nested ordered/bullet/task lists with the tight/loose distinction, tables,
5
+ // thematic breaks; inline emphasis with the real flanking and rule-of-three
6
+ // algorithm, code spans, links, images, autolinks, hard breaks, entities.
7
+ //
8
+ // The deliberate deviations, all in the direction LLM output wants:
9
+ //
10
+ // - **Streaming tolerance is in the parser, not a repair pre-pass.** The
11
+ // behavioural spec is Streamdown's `remend` package (the handlers were
12
+ // read, not imported): unclosed `**`/`*`/`~~`/`` ` `` reaching the end of
13
+ // a partial document close implicitly, `[text](partial-url` renders its
14
+ // text link-styled with `href: null`, half-arrived images vanish, a bare
15
+ // trailing `**`, `#` or `---` is held back until it can be read. Doing it
16
+ // during the parse means one pass over the text instead of
17
+ // repair-then-reparse, and none of remend's "was that backtick inside a
18
+ // fence?" re-scans.
19
+ // - **Single `~` is never strikethrough** (GFM allows it): `~~` only, so
20
+ // "20~25" needs no escaping heuristic.
21
+ // - **Reference links (`[text][ref]`) stay literal.** They need a
22
+ // definitions pass over the whole document, and streamed model output
23
+ // essentially never uses them.
24
+ // - **Raw HTML is literal text.** There is no HTML pass anywhere in this
25
+ // component, by design; `<Component />` syntax is reserved for a future
26
+ // MDX extension (see `ComponentInline` in ast.ts).
27
+ import type {
28
+ BlockNode,
29
+ Document,
30
+ InlineNode,
31
+ ListBlock,
32
+ ListItem,
33
+ ParseOptions,
34
+ TableAlign,
35
+ } from './ast.js';
36
+
37
+ // --- line-level regexes, compiled once -------------------------------------
38
+
39
+ const RE_BLANK = /^[ \t]*$/;
40
+ const RE_ATX = /^ {0,3}(#{1,6})(?:[ \t]+(.*?))?(?:[ \t]+#+)?[ \t]*$/;
41
+ const RE_ATX_STUB = /^ {0,3}#{1,6}$/;
42
+ const RE_FENCE_OPEN = /^( {0,3})(`{3,}|~{3,})[ \t]*(.*)$/;
43
+ const RE_HR = /^ {0,3}([*_-])[ \t]*(?:\1[ \t]*){2,}$/;
44
+ const RE_SETEXT = /^ {0,3}(=+|-+)[ \t]*$/;
45
+ const RE_QUOTE = /^ {0,3}>[ ]?(.*)$/;
46
+ const RE_LIST = /^( {0,3})([-+*]|\d{1,9}[.)])(?:([ \t]+)(.*))?$/;
47
+ const RE_TASK = /^\[([ xX])\][ \t]+/;
48
+ const RE_INDENT_CODE = /^(?: {4}|\t)/;
49
+ // a complete GFM delimiter row: | :---: | --- |
50
+ const RE_TABLE_DELIM =
51
+ /^ {0,3}\|?[ \t]*:?-+:?[ \t]*(?:\|[ \t]*:?-+:?[ \t]*)*\|?[ \t]*$/;
52
+ // a plausible prefix of one, for the streaming case ("| :--" mid-arrival)
53
+ const RE_TABLE_DELIM_PREFIX = /^ {0,3}\|[ \t:|-]*$/;
54
+
55
+ /** Would this line open something other than a paragraph? The test lazy
56
+ * continuation and list/quote termination share. */
57
+ function isBlockStart(line: string): boolean {
58
+ return (
59
+ RE_ATX.test(line) ||
60
+ RE_FENCE_OPEN.test(line) ||
61
+ RE_HR.test(line) ||
62
+ RE_QUOTE.test(line) ||
63
+ RE_LIST.test(line)
64
+ );
65
+ }
66
+
67
+ /** Leading tabs advance to 4-column stops; content tabs are left alone. */
68
+ function expandLeadingTabs(line: string): string {
69
+ let i = 0;
70
+ let col = 0;
71
+ while (i < line.length) {
72
+ const ch = line.charCodeAt(i);
73
+ if (ch === 32) col += 1;
74
+ else if (ch === 9) col += 4 - (col % 4);
75
+ else break;
76
+ i += 1;
77
+ }
78
+ if (col === i) return line; // no tabs in the indent
79
+ return ' '.repeat(col) + line.slice(i);
80
+ }
81
+
82
+ function indentOf(line: string): number {
83
+ let i = 0;
84
+ while (i < line.length && line.charCodeAt(i) === 32) i += 1;
85
+ return i;
86
+ }
87
+
88
+ // --- entry -----------------------------------------------------------------
89
+
90
+ export function parse(source: string, options: ParseOptions = {}): Document {
91
+ const partial = options.partial !== false;
92
+ const normalized = source.replace(/\r\n?/g, '\n');
93
+ const lines = normalized.split('\n').map(expandLeadingTabs);
94
+ const blocks: BlockNode[] = [];
95
+ const ranges: Array<[number, number]> = [];
96
+ parseBlocks(lines, partial, blocks, ranges);
97
+ return {
98
+ blocks,
99
+ raws: ranges.map(([a, b]) => lines.slice(a, b).join('\n')),
100
+ };
101
+ }
102
+
103
+ // --- block layer -----------------------------------------------------------
104
+
105
+ /**
106
+ * Parse a run of lines into blocks. `tailOpen` says the end of `lines` is
107
+ * the live end of a streaming document — the license for every "complete it
108
+ * anyway" rule. `ranges`, when given, receives each block's [start, endExcl)
109
+ * line range (only the top-level call wants them, for the streaming cache).
110
+ */
111
+ function parseBlocks(
112
+ lines: string[],
113
+ tailOpen: boolean,
114
+ out: BlockNode[],
115
+ ranges?: Array<[number, number]>,
116
+ ): void {
117
+ let i = 0;
118
+ const n = lines.length;
119
+
120
+ let paraStart = -1;
121
+ const para: string[] = [];
122
+
123
+ const commit = (block: BlockNode, start: number, end: number): void => {
124
+ out.push(block);
125
+ ranges?.push([start, end]);
126
+ };
127
+
128
+ const flushPara = (end: number): void => {
129
+ if (para.length === 0) return;
130
+ const text = para.join('\n');
131
+ const start = paraStart;
132
+ para.length = 0;
133
+ paraStart = -1;
134
+ // the paragraph owns the live tail iff its last line is the document's
135
+ const children = parseInline(text, tailOpen && end === n);
136
+ if (children.length > 0)
137
+ commit({ type: 'paragraph', children }, start, end);
138
+ };
139
+
140
+ while (i < n) {
141
+ const line = lines[i];
142
+ const isLast = i === n - 1;
143
+ const held = tailOpen && isLast; // "might still grow" applies
144
+
145
+ if (RE_BLANK.test(line)) {
146
+ flushPara(i);
147
+ i += 1;
148
+ continue;
149
+ }
150
+
151
+ // Setext underline closes an open paragraph — unless it is the live
152
+ // tail, where "Title\n---" might still become a rule, a list item or
153
+ // plain text ("--- more"), so the line is held back for one round.
154
+ if (para.length > 0) {
155
+ const setext = RE_SETEXT.exec(line);
156
+ if (setext) {
157
+ if (held) {
158
+ i += 1;
159
+ continue;
160
+ }
161
+ const text = para.join('\n');
162
+ const start = paraStart;
163
+ para.length = 0;
164
+ paraStart = -1;
165
+ commit(
166
+ {
167
+ type: 'heading',
168
+ depth: setext[1][0] === '=' ? 1 : 2,
169
+ children: parseInline(text, false),
170
+ },
171
+ start,
172
+ i + 1,
173
+ );
174
+ i += 1;
175
+ continue;
176
+ }
177
+ }
178
+
179
+ // Ambiguous live tails, hidden until they commit to being something:
180
+ // a bare marker run (`---`, `***` — rule? setext? bold opener?) or a
181
+ // content-less ATX stub (`##`).
182
+ if (
183
+ held &&
184
+ para.length === 0 &&
185
+ (RE_SETEXT.test(line) || RE_HR.test(line) || RE_ATX_STUB.test(line))
186
+ ) {
187
+ i += 1;
188
+ continue;
189
+ }
190
+
191
+ // Thematic break — before list, so `- - -` is a rule and not a list.
192
+ if (RE_HR.test(line)) {
193
+ flushPara(i);
194
+ commit({ type: 'rule' }, i, i + 1);
195
+ i += 1;
196
+ continue;
197
+ }
198
+
199
+ const atx = RE_ATX.exec(line);
200
+ if (atx) {
201
+ flushPara(i);
202
+ commit(
203
+ {
204
+ type: 'heading',
205
+ depth: atx[1].length,
206
+ children: parseInline(atx[2] ?? '', held),
207
+ },
208
+ i,
209
+ i + 1,
210
+ );
211
+ i += 1;
212
+ continue;
213
+ }
214
+
215
+ const fence = RE_FENCE_OPEN.exec(line);
216
+ // an info string on a backtick fence cannot itself contain a backtick
217
+ if (fence && !(fence[2][0] === '`' && fence[3].includes('`'))) {
218
+ flushPara(i);
219
+ const start = i;
220
+ const fenceIndent = fence[1].length;
221
+ const marker = fence[2];
222
+ const lang = (fence[3].trim().split(/[ \t]/, 1)[0] ?? '').toLowerCase();
223
+ const body: string[] = [];
224
+ let closed = false;
225
+ i += 1;
226
+ while (i < n) {
227
+ const l = lines[i];
228
+ const close = RE_FENCE_OPEN.exec(l);
229
+ if (
230
+ close &&
231
+ close[2][0] === marker[0] &&
232
+ close[2].length >= marker.length &&
233
+ close[3] === ''
234
+ ) {
235
+ closed = true;
236
+ i += 1;
237
+ break;
238
+ }
239
+ // content dedents by at most the opening fence's indent
240
+ body.push(
241
+ indentOf(l) >= fenceIndent
242
+ ? l.slice(fenceIndent)
243
+ : l.replace(/^ +/, ''),
244
+ );
245
+ i += 1;
246
+ }
247
+ commit({ type: 'code', lang, text: body.join('\n'), closed }, start, i);
248
+ continue;
249
+ }
250
+
251
+ const quote = RE_QUOTE.exec(line);
252
+ if (quote) {
253
+ flushPara(i);
254
+ const start = i;
255
+ const inner: string[] = [];
256
+ inner.push(quote[1]);
257
+ i += 1;
258
+ // further `>` lines, plus lazy continuation of a trailing paragraph
259
+ while (i < n) {
260
+ const l = lines[i];
261
+ const q = RE_QUOTE.exec(l);
262
+ if (q) {
263
+ inner.push(q[1]);
264
+ i += 1;
265
+ continue;
266
+ }
267
+ if (
268
+ !RE_BLANK.test(l) &&
269
+ !isBlockStart(l) &&
270
+ inner.length > 0 &&
271
+ !RE_BLANK.test(inner[inner.length - 1])
272
+ ) {
273
+ inner.push(l); // lazy: "> a\nb" keeps b in the quote
274
+ i += 1;
275
+ continue;
276
+ }
277
+ break;
278
+ }
279
+ const children: BlockNode[] = [];
280
+ parseBlocks(inner, tailOpen && i === n, children);
281
+ if (children.length > 0) commit({ type: 'quote', children }, start, i);
282
+ continue;
283
+ }
284
+
285
+ const list = RE_LIST.exec(line);
286
+ // an empty item cannot interrupt a paragraph ("foo\n-" is not a list…),
287
+ // and while streaming the very last line gets the same benefit of doubt
288
+ if (list && !(para.length > 0 && !list[4]) && !(held && !list[4])) {
289
+ flushPara(i);
290
+ const start = i;
291
+ const block = parseList(lines, i, tailOpen);
292
+ i = block.end;
293
+ commit(block.list, start, i);
294
+ continue;
295
+ }
296
+
297
+ // GFM table: a header row whose next line is the delimiter row. While
298
+ // streaming, a delimiter row still arriving ("| :--") is accepted too.
299
+ if (para.length === 0 && line.includes('|')) {
300
+ const next = i + 1 < n ? lines[i + 1] : null;
301
+ const headerCells = splitRow(line);
302
+ // a complete delimiter row with agreeing column count is the real
303
+ // thing; while streaming, a still-arriving one ("| :-" as the last
304
+ // line) is accepted with the header's column count and no alignment
305
+ const fullDelim =
306
+ next !== null &&
307
+ next.includes('-') &&
308
+ RE_TABLE_DELIM.test(next) &&
309
+ splitRow(next).length === headerCells.length;
310
+ const partialDelim =
311
+ !fullDelim &&
312
+ tailOpen &&
313
+ i + 1 === n - 1 &&
314
+ next !== null &&
315
+ RE_TABLE_DELIM_PREFIX.test(next);
316
+ const arrivingDelim = tailOpen && i === n - 1;
317
+ if (headerCells.length > 0 && (fullDelim || partialDelim)) {
318
+ const start = i;
319
+ const align: TableAlign[] = fullDelim
320
+ ? splitRow(next).map(alignOf)
321
+ : headerCells.map(() => null);
322
+ i += 2;
323
+ const rows: InlineNode[][][] = [];
324
+ while (i < n) {
325
+ const l = lines[i];
326
+ if (RE_BLANK.test(l) || !l.includes('|') || isBlockStart(l)) break;
327
+ rows.push(
328
+ normalizeRow(splitRow(l), align.length, tailOpen && i === n - 1),
329
+ );
330
+ i += 1;
331
+ }
332
+ commit(
333
+ {
334
+ type: 'table',
335
+ align,
336
+ header: normalizeRow(headerCells, align.length, false),
337
+ rows,
338
+ },
339
+ start,
340
+ i,
341
+ );
342
+ continue;
343
+ } else if (
344
+ arrivingDelim &&
345
+ headerCells.length > 1 &&
346
+ line.trimStart().startsWith('|')
347
+ ) {
348
+ // the header row itself is the live tail — hold it rather than
349
+ // flashing "| a | b |" as literal text for one frame
350
+ i += 1;
351
+ continue;
352
+ }
353
+ }
354
+
355
+ // indented code cannot interrupt a paragraph
356
+ if (para.length === 0 && RE_INDENT_CODE.test(line)) {
357
+ const start = i;
358
+ const body: string[] = [];
359
+ while (i < n) {
360
+ const l = lines[i];
361
+ if (RE_INDENT_CODE.test(l)) {
362
+ body.push(l.startsWith('\t') ? l.slice(1) : l.slice(4));
363
+ i += 1;
364
+ } else if (RE_BLANK.test(l)) {
365
+ body.push('');
366
+ i += 1;
367
+ } else break;
368
+ }
369
+ while (body.length > 0 && body[body.length - 1] === '') body.pop();
370
+ commit(
371
+ { type: 'code', lang: '', text: body.join('\n'), closed: true },
372
+ start,
373
+ i,
374
+ );
375
+ continue;
376
+ }
377
+
378
+ if (para.length === 0) paraStart = i;
379
+ // only the lead is trimmed: trailing spaces are the hard-break syntax
380
+ para.push(line.trimStart());
381
+ i += 1;
382
+ }
383
+
384
+ flushPara(n);
385
+ }
386
+
387
+ // --- lists -----------------------------------------------------------------
388
+
389
+ interface ParsedList {
390
+ list: ListBlock;
391
+ end: number;
392
+ }
393
+
394
+ function parseList(
395
+ lines: string[],
396
+ from: number,
397
+ tailOpen: boolean,
398
+ ): ParsedList {
399
+ const n = lines.length;
400
+ const first = RE_LIST.exec(lines[from]);
401
+ // caller matched — this is the narrowing, not a runtime possibility
402
+ if (!first) throw new Error('parseList called off a list marker');
403
+ const marker = first[2];
404
+ const ordered = marker.length > 1;
405
+ const markerType = ordered ? marker[marker.length - 1] : marker; // ')' '.' '-' '+' '*'
406
+ const start = ordered ? parseInt(marker, 10) : 1;
407
+
408
+ const items: ListItem[] = [];
409
+ let loose = false;
410
+ let i = from;
411
+ let sawBlank = false;
412
+
413
+ while (i < n) {
414
+ const m = RE_LIST.exec(lines[i]);
415
+ const sameKind =
416
+ m &&
417
+ (ordered
418
+ ? /\d/.test(m[2][0]) && m[2][m[2].length - 1] === markerType
419
+ : m[2] === markerType);
420
+ if (!sameKind) break;
421
+ if (sawBlank && items.length > 0) loose = true;
422
+ sawBlank = false;
423
+
424
+ const indent = m[1].length;
425
+ const afterMarker = m[3] ?? '';
426
+ const rest = m[4] ?? '';
427
+ // content column: marker + one space, or the actual spacing when ≤ 4
428
+ const pad =
429
+ afterMarker.length === 0 || afterMarker.length > 4
430
+ ? 1
431
+ : afterMarker.length;
432
+ const contentIndent = indent + m[2].length + pad;
433
+
434
+ const inner: string[] = [rest];
435
+ i += 1;
436
+ let pendingBlanks = 0;
437
+ while (i < n) {
438
+ const l = lines[i];
439
+ if (RE_BLANK.test(l)) {
440
+ pendingBlanks += 1;
441
+ if (pendingBlanks > 1) break;
442
+ i += 1;
443
+ continue;
444
+ }
445
+ if (indentOf(l) >= contentIndent) {
446
+ if (pendingBlanks > 0) {
447
+ inner.push('');
448
+ loose = true;
449
+ pendingBlanks = 0;
450
+ }
451
+ inner.push(l.slice(contentIndent));
452
+ i += 1;
453
+ continue;
454
+ }
455
+ if (pendingBlanks === 0 && !isBlockStart(l) && !RE_BLANK.test(l)) {
456
+ inner.push(l); // lazy paragraph continuation
457
+ i += 1;
458
+ continue;
459
+ }
460
+ break;
461
+ }
462
+ if (pendingBlanks > 0) sawBlank = true;
463
+
464
+ // GFM task marker sits at the head of the item's first line
465
+ let checked: boolean | null = null;
466
+ const task = RE_TASK.exec(inner[0]);
467
+ if (task) {
468
+ checked = task[1] !== ' ';
469
+ inner[0] = inner[0].slice(task[0].length);
470
+ }
471
+
472
+ const children: BlockNode[] = [];
473
+ parseBlocks(inner, tailOpen && i >= n, children);
474
+ items.push({ checked, children });
475
+ }
476
+
477
+ return {
478
+ list: { type: 'list', ordered, start, tight: !loose, items },
479
+ end: i,
480
+ };
481
+ }
482
+
483
+ // --- tables ----------------------------------------------------------------
484
+
485
+ /** Split a row on unescaped pipes; `\|` stays literal in the cell. */
486
+ function splitRow(line: string): string[] {
487
+ const trimmed = line.trim();
488
+ const cells: string[] = [];
489
+ let cur = '';
490
+ for (let i = 0; i < trimmed.length; i += 1) {
491
+ const ch = trimmed[i];
492
+ if (ch === '\\' && trimmed[i + 1] === '|') {
493
+ cur += '|';
494
+ i += 1;
495
+ } else if (ch === '|') {
496
+ cells.push(cur.trim());
497
+ cur = '';
498
+ } else cur += ch;
499
+ }
500
+ cells.push(cur.trim());
501
+ if (cells.length > 0 && cells[0] === '' && trimmed.startsWith('|'))
502
+ cells.shift();
503
+ if (
504
+ cells.length > 0 &&
505
+ cells[cells.length - 1] === '' &&
506
+ trimmed.endsWith('|')
507
+ )
508
+ cells.pop();
509
+ return cells;
510
+ }
511
+
512
+ function alignOf(cell: string): TableAlign {
513
+ const left = cell.startsWith(':');
514
+ const right = cell.endsWith(':');
515
+ if (left && right) return 'center';
516
+ if (right) return 'right';
517
+ if (left) return 'left';
518
+ return null;
519
+ }
520
+
521
+ function normalizeRow(
522
+ cells: string[],
523
+ width: number,
524
+ rowIsLiveTail: boolean,
525
+ ): InlineNode[][] {
526
+ const row: InlineNode[][] = [];
527
+ for (let c = 0; c < width; c += 1) {
528
+ const text = cells[c] ?? '';
529
+ row.push(
530
+ parseInline(
531
+ text,
532
+ rowIsLiveTail && c === Math.min(cells.length, width) - 1,
533
+ ),
534
+ );
535
+ }
536
+ return row;
537
+ }
538
+
539
+ // --- inline layer ----------------------------------------------------------
540
+
541
+ // A mutable working item: finished inline nodes interleaved with unresolved
542
+ // delimiter runs, resolved in place by the emphasis pass.
543
+ type Item =
544
+ | { kind: 'node'; node: InlineNode }
545
+ | {
546
+ kind: 'delim';
547
+ char: '*' | '_' | '~';
548
+ length: number;
549
+ canOpen: boolean;
550
+ canClose: boolean;
551
+ }
552
+ | { kind: 'bracket'; image: boolean };
553
+
554
+ const RE_UNI_WS = /\s/u;
555
+ const RE_UNI_PUNCT = /[\p{P}\p{S}]/u;
556
+ const RE_AUTOLINK = /^<([a-zA-Z][a-zA-Z0-9+.-]{1,31}:[^<>\s]*)>/;
557
+ const RE_AUTOEMAIL = /^<([^<>\s@]+@[^<>\s@]+\.[^<>\s@]+)>/;
558
+ const RE_ENTITY =
559
+ /&(?:#(\d{1,7})|#[xX]([0-9a-fA-F]{1,6})|([a-zA-Z][a-zA-Z0-9]{1,31}));/g;
560
+
561
+ const NAMED_ENTITIES: Record<string, string> = {
562
+ amp: '&',
563
+ lt: '<',
564
+ gt: '>',
565
+ quot: '"',
566
+ apos: "'",
567
+ nbsp: ' ',
568
+ copy: '©',
569
+ reg: '®',
570
+ trade: '™',
571
+ hellip: '…',
572
+ mdash: '—',
573
+ ndash: '–',
574
+ laquo: '«',
575
+ raquo: '»',
576
+ times: '×',
577
+ middot: '·',
578
+ };
579
+
580
+ function decodeEntities(text: string): string {
581
+ if (!text.includes('&')) return text;
582
+ return text.replace(RE_ENTITY, (whole, dec, hex, named) => {
583
+ if (dec) {
584
+ const cp = parseInt(dec, 10);
585
+ return cp > 0 && cp <= 0x10ffff ? String.fromCodePoint(cp) : '�';
586
+ }
587
+ if (hex) {
588
+ const cp = parseInt(hex, 16);
589
+ return cp > 0 && cp <= 0x10ffff ? String.fromCodePoint(cp) : '�';
590
+ }
591
+ return NAMED_ENTITIES[named] ?? whole;
592
+ });
593
+ }
594
+
595
+ function classify(ch: string | undefined): 'ws' | 'punct' | 'other' {
596
+ if (ch === undefined) return 'ws'; // string boundaries count as whitespace
597
+ if (RE_UNI_WS.test(ch)) return 'ws';
598
+ if (RE_UNI_PUNCT.test(ch)) return 'punct';
599
+ return 'other';
600
+ }
601
+
602
+ /**
603
+ * Parse inline markdown. `atDocEnd` marks text whose end is the live end of
604
+ * a streaming document — only then do the implicit-close rules apply.
605
+ */
606
+ export function parseInline(text: string, atDocEnd: boolean): InlineNode[] {
607
+ const items: Item[] = [];
608
+ let buf = '';
609
+
610
+ const flushText = (): void => {
611
+ if (buf.length === 0) return;
612
+ items.push({
613
+ kind: 'node',
614
+ node: { type: 'text', text: decodeEntities(buf) },
615
+ });
616
+ buf = '';
617
+ };
618
+
619
+ const len = text.length;
620
+ let i = 0;
621
+ while (i < len) {
622
+ const ch = text[i];
623
+
624
+ if (ch === '\\') {
625
+ const next = text[i + 1];
626
+ if (next === '\n') {
627
+ // hard break by trailing backslash
628
+ flushText();
629
+ items.push({ kind: 'node', node: { type: 'break' } });
630
+ i += 2;
631
+ continue;
632
+ }
633
+ if (next !== undefined && RE_UNI_PUNCT.test(next)) {
634
+ buf += next;
635
+ i += 2;
636
+ continue;
637
+ }
638
+ buf += ch;
639
+ i += 1;
640
+ continue;
641
+ }
642
+
643
+ if (ch === '\n') {
644
+ const hard = buf.endsWith(' ');
645
+ buf = buf.replace(/[ \t]+$/, '');
646
+ flushText();
647
+ items.push({
648
+ kind: 'node',
649
+ node: hard ? { type: 'break' } : { type: 'text', text: ' ' },
650
+ });
651
+ i += 1;
652
+ while (text[i] === ' ' || text[i] === '\t') i += 1;
653
+ continue;
654
+ }
655
+
656
+ if (ch === '`') {
657
+ let run = 1;
658
+ while (text[i + run] === '`') run += 1;
659
+ // the closing run must be exactly as long, and not part of a longer one
660
+ let j = i + run;
661
+ let close = -1;
662
+ while (j < len) {
663
+ if (text[j] === '`') {
664
+ let r = 1;
665
+ while (text[j + r] === '`') r += 1;
666
+ if (r === run) {
667
+ close = j;
668
+ break;
669
+ }
670
+ j += r;
671
+ } else j += 1;
672
+ }
673
+ if (close !== -1) {
674
+ flushText();
675
+ items.push({
676
+ kind: 'node',
677
+ node: {
678
+ type: 'code',
679
+ text: codeSpanText(text.slice(i + run, close)),
680
+ },
681
+ });
682
+ i = close + run;
683
+ continue;
684
+ }
685
+ if (atDocEnd) {
686
+ // `remend`'s inlineCode rule: an open span at the live end closes
687
+ // itself — unless nothing follows the backticks yet, then hide them
688
+ const rest = text.slice(i + run);
689
+ flushText();
690
+ if (rest.length > 0)
691
+ items.push({
692
+ kind: 'node',
693
+ node: { type: 'code', text: codeSpanText(rest) },
694
+ });
695
+ i = len;
696
+ continue;
697
+ }
698
+ buf += text.slice(i, i + run);
699
+ i += run;
700
+ continue;
701
+ }
702
+
703
+ if (ch === '<') {
704
+ const rest = text.slice(i);
705
+ const auto = RE_AUTOLINK.exec(rest) ?? RE_AUTOEMAIL.exec(rest);
706
+ if (auto) {
707
+ flushText();
708
+ const target = auto[1];
709
+ const href = RE_AUTOLINK.test(auto[0]) ? target : `mailto:${target}`;
710
+ items.push({
711
+ kind: 'node',
712
+ node: {
713
+ type: 'link',
714
+ href,
715
+ image: false,
716
+ children: [{ type: 'text', text: target }],
717
+ },
718
+ });
719
+ i += auto[0].length;
720
+ continue;
721
+ }
722
+ buf += ch;
723
+ i += 1;
724
+ continue;
725
+ }
726
+
727
+ if (ch === '[' || (ch === '!' && text[i + 1] === '[')) {
728
+ const image = ch === '!';
729
+ flushText();
730
+ items.push({ kind: 'bracket', image });
731
+ i += image ? 2 : 1;
732
+ continue;
733
+ }
734
+
735
+ if (ch === ']') {
736
+ const openIdx = lastBracket(items);
737
+ if (openIdx === -1) {
738
+ buf += ch;
739
+ i += 1;
740
+ continue;
741
+ }
742
+ const suffix = parseLinkSuffix(text, i + 1);
743
+ if (suffix) {
744
+ flushText();
745
+ closeLink(items, openIdx, suffix.href);
746
+ i = suffix.end;
747
+ continue;
748
+ }
749
+ if (atDocEnd && text[i + 1] === '(' && !text.includes(')', i + 1)) {
750
+ // `[text](partial-url` at the live end: keep the text, link-styled,
751
+ // with nowhere to go yet. A half-arrived image vanishes instead.
752
+ flushText();
753
+ const bracket = items[openIdx] as { kind: 'bracket'; image: boolean };
754
+ if (bracket.image) items.splice(openIdx);
755
+ else closeLink(items, openIdx, null);
756
+ i = len;
757
+ continue;
758
+ }
759
+ // no destination: not a link (reference links stay literal)
760
+ flushText();
761
+ items.splice(openIdx, 1, {
762
+ kind: 'node',
763
+ node: {
764
+ type: 'text',
765
+ text: (items[openIdx] as { image: boolean }).image ? '![' : '[',
766
+ },
767
+ });
768
+ buf += ch;
769
+ i += 1;
770
+ continue;
771
+ }
772
+
773
+ if (ch === '*' || ch === '_' || ch === '~') {
774
+ let run = 1;
775
+ while (text[i + run] === ch) run += 1;
776
+ const before = classify(text[i - 1]);
777
+ const after = classify(text[i + run]);
778
+ const leftFlank =
779
+ after !== 'ws' && (after !== 'punct' || before !== 'other');
780
+ const rightFlank =
781
+ before !== 'ws' && (before !== 'punct' || after !== 'other');
782
+ let canOpen = leftFlank;
783
+ let canClose = rightFlank;
784
+ if (ch === '_') {
785
+ // intraword `_` never opens or closes: snake_case stays literal
786
+ canOpen = leftFlank && (!rightFlank || before === 'punct');
787
+ canClose = rightFlank && (!leftFlank || after === 'punct');
788
+ }
789
+ if (ch === '~' && run !== 2) {
790
+ buf += text.slice(i, i + run);
791
+ i += run;
792
+ continue;
793
+ }
794
+ // a fresh opener with nothing after it yet, at the live end of the
795
+ // document — `text **` — is hidden rather than shown as raw markers
796
+ if (atDocEnd && i + run === len && before !== 'other') {
797
+ i = len;
798
+ continue;
799
+ }
800
+ if (!canOpen && !canClose) {
801
+ buf += text.slice(i, i + run);
802
+ i += run;
803
+ continue;
804
+ }
805
+ flushText();
806
+ items.push({ kind: 'delim', char: ch, length: run, canOpen, canClose });
807
+ i += run;
808
+ continue;
809
+ }
810
+
811
+ buf += ch;
812
+ i += 1;
813
+ }
814
+ flushText();
815
+
816
+ processEmphasis(items, atDocEnd);
817
+
818
+ // leftover brackets: a live-tail `[still typing…` renders link-styled,
819
+ // a dead one is the literal character it always was
820
+ for (let k = items.length - 1; k >= 0; k -= 1) {
821
+ const it = items[k];
822
+ if (it.kind !== 'bracket') continue;
823
+ if (atDocEnd) {
824
+ if (it.image) items.splice(k);
825
+ else closeLink(items, k, null);
826
+ } else {
827
+ items.splice(k, 1, {
828
+ kind: 'node',
829
+ node: { type: 'text', text: it.image ? '![' : '[' },
830
+ });
831
+ }
832
+ }
833
+
834
+ return finish(items);
835
+ }
836
+
837
+ /** CommonMark's code-span rule: newlines become spaces, and one space is
838
+ * shaved off each end when both ends have one and content remains. */
839
+ function codeSpanText(raw: string): string {
840
+ const flat = raw.replace(/\n/g, ' ');
841
+ if (
842
+ flat.length >= 2 &&
843
+ flat.startsWith(' ') &&
844
+ flat.endsWith(' ') &&
845
+ flat.trim() !== ''
846
+ )
847
+ return flat.slice(1, -1);
848
+ return flat;
849
+ }
850
+
851
+ function lastBracket(items: Item[]): number {
852
+ for (let k = items.length - 1; k >= 0; k -= 1)
853
+ if (items[k].kind === 'bracket') return k;
854
+ return -1;
855
+ }
856
+
857
+ interface LinkSuffix {
858
+ href: string;
859
+ end: number;
860
+ }
861
+
862
+ /** `](dest "title")` — destination in `<>` or bare with balanced parens.
863
+ * The title is tolerated and dropped: nothing here renders one. */
864
+ function parseLinkSuffix(text: string, from: number): LinkSuffix | null {
865
+ if (text[from] !== '(') return null;
866
+ let i = from + 1;
867
+ const len = text.length;
868
+ while (i < len && (text[i] === ' ' || text[i] === '\n')) i += 1;
869
+ let href = '';
870
+ if (text[i] === '<') {
871
+ const close = text.indexOf('>', i + 1);
872
+ if (close === -1) return null;
873
+ href = text.slice(i + 1, close);
874
+ if (href.includes('\n')) return null;
875
+ i = close + 1;
876
+ } else {
877
+ let depth = 0;
878
+ while (i < len) {
879
+ const ch = text[i];
880
+ if (ch === '\\' && i + 1 < len) {
881
+ href += text[i + 1];
882
+ i += 2;
883
+ continue;
884
+ }
885
+ if (ch === '(') depth += 1;
886
+ if (ch === ')') {
887
+ if (depth === 0) break;
888
+ depth -= 1;
889
+ }
890
+ if (ch === ' ' || ch === '\n' || ch === '\t') break;
891
+ href += ch;
892
+ i += 1;
893
+ }
894
+ }
895
+ while (i < len && (text[i] === ' ' || text[i] === '\n' || text[i] === '\t'))
896
+ i += 1;
897
+ // an optional title in any of the three quote styles
898
+ const q = text[i];
899
+ if (q === '"' || q === "'" || q === '(') {
900
+ const closer = q === '(' ? ')' : q;
901
+ let j = i + 1;
902
+ while (j < len && text[j] !== closer) j += 1;
903
+ if (j >= len) return null;
904
+ i = j + 1;
905
+ while (i < len && (text[i] === ' ' || text[i] === '\n' || text[i] === '\t'))
906
+ i += 1;
907
+ }
908
+ if (text[i] !== ')') return null;
909
+ return { href: decodeEntities(href), end: i + 1 };
910
+ }
911
+
912
+ /** Fold everything after the bracket opener at `openIdx` into a link node. */
913
+ function closeLink(items: Item[], openIdx: number, href: string | null): void {
914
+ const bracket = items[openIdx] as { kind: 'bracket'; image: boolean };
915
+ const inner = items.splice(openIdx);
916
+ inner.shift();
917
+ // emphasis inside the link text resolves within the link's own scope
918
+ processEmphasis(inner, href === null);
919
+ items.push({
920
+ kind: 'node',
921
+ node: { type: 'link', href, image: bracket.image, children: finish(inner) },
922
+ });
923
+ }
924
+
925
+ /**
926
+ * The CommonMark delimiter algorithm over `items`, in place: walk closers
927
+ * left to right, match each to the nearest compatible opener, wrap. The
928
+ * "rule of three" guards `**foo*` against eating the wrong marker. With
929
+ * `implicitClose` (the live tail), openers left standing afterwards close
930
+ * at the end of the text — that is `remend`'s bold/italic/strikethrough
931
+ * behaviour — unless nothing follows them, in which case they vanish.
932
+ */
933
+ function processEmphasis(items: Item[], implicitClose: boolean): void {
934
+ let closer = 0;
935
+ while (closer < items.length) {
936
+ const c = items[closer];
937
+ if (c.kind !== 'delim' || !c.canClose) {
938
+ closer += 1;
939
+ continue;
940
+ }
941
+ let opener = -1;
942
+ for (let k = closer - 1; k >= 0; k -= 1) {
943
+ const o = items[k];
944
+ if (o.kind === 'bracket') break; // emphasis cannot cross a link boundary
945
+ if (o.kind !== 'delim' || o.char !== c.char || !o.canOpen) continue;
946
+ // rule of three
947
+ if (
948
+ (o.canClose || c.canOpen) &&
949
+ (o.length + c.length) % 3 === 0 &&
950
+ (o.length % 3 !== 0 || c.length % 3 !== 0)
951
+ )
952
+ continue;
953
+ opener = k;
954
+ break;
955
+ }
956
+ if (opener === -1) {
957
+ if (!c.canOpen) {
958
+ items.splice(closer, 1, delimToText(c));
959
+ }
960
+ closer += 1;
961
+ continue;
962
+ }
963
+
964
+ const o = items[opener] as Extract<Item, { kind: 'delim' }>;
965
+ const use = c.char === '~' ? 2 : Math.min(2, o.length, c.length);
966
+ const type = c.char === '~' ? 'del' : use === 2 ? 'strong' : 'em';
967
+ const inner = items.splice(opener + 1, closer - opener - 1);
968
+ const node: InlineNode = { type, children: finish(inner) };
969
+ o.length -= use;
970
+ c.length -= use;
971
+ items.splice(opener + 1, 0, { kind: 'node', node });
972
+ closer = opener + 2;
973
+ if (o.length === 0) {
974
+ items.splice(opener, 1);
975
+ closer -= 1;
976
+ }
977
+ if (c.length === 0) items.splice(closer, 1);
978
+ }
979
+
980
+ if (implicitClose) {
981
+ // leftmost surviving opener wraps the rest; repeats handle `**a *b`
982
+ for (let k = 0; k < items.length; k += 1) {
983
+ const o = items[k];
984
+ if (o.kind !== 'delim' || !o.canOpen) continue;
985
+ const rest = items.splice(k + 1);
986
+ const restNodes = finish(rest);
987
+ if (restNodes.length === 0) {
988
+ items.splice(k, 1);
989
+ k -= 1;
990
+ continue;
991
+ }
992
+ let node: InlineNode;
993
+ if (o.char === '~') node = { type: 'del', children: restNodes };
994
+ else if (o.length >= 3)
995
+ node = {
996
+ type: 'strong',
997
+ children: [{ type: 'em', children: restNodes }],
998
+ };
999
+ else if (o.length === 2) node = { type: 'strong', children: restNodes };
1000
+ else node = { type: 'em', children: restNodes };
1001
+ items.splice(k, 1, { kind: 'node', node });
1002
+ }
1003
+ }
1004
+
1005
+ // whatever survives was never emphasis — restore the literal characters
1006
+ for (let k = 0; k < items.length; k += 1) {
1007
+ const it = items[k];
1008
+ if (it.kind === 'delim') items.splice(k, 1, delimToText(it));
1009
+ }
1010
+ }
1011
+
1012
+ function delimToText(d: Extract<Item, { kind: 'delim' }>): Item {
1013
+ return {
1014
+ kind: 'node',
1015
+ node: { type: 'text', text: d.char.repeat(d.length) },
1016
+ };
1017
+ }
1018
+
1019
+ /** Collapse a fully-resolved item list to nodes, merging adjacent texts. */
1020
+ function finish(items: Item[]): InlineNode[] {
1021
+ const out: InlineNode[] = [];
1022
+ for (const it of items) {
1023
+ const node =
1024
+ it.kind === 'node'
1025
+ ? it.node
1026
+ : it.kind === 'delim'
1027
+ ? ({ type: 'text', text: it.char.repeat(it.length) } as InlineNode)
1028
+ : ({ type: 'text', text: it.image ? '![' : '[' } as InlineNode);
1029
+ const prev = out[out.length - 1];
1030
+ if (node.type === 'text' && prev?.type === 'text') {
1031
+ prev.text += node.text;
1032
+ } else if (!(node.type === 'text' && node.text === '')) {
1033
+ out.push(node);
1034
+ }
1035
+ }
1036
+ return out;
1037
+ }