@deepseek-harness-tui/dsh-tui 0.11.1 → 0.11.2

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 (427) hide show
  1. package/README.md +50 -20
  2. package/assets/whale-girl/whale-girl-dark.png +0 -0
  3. package/assets/whale-girl/whale-girl-happy.png +0 -0
  4. package/assets/whale-girl/whale-girl.png +0 -0
  5. package/bin/dsh-tui.js +63 -3
  6. package/cordis.patch.yml +39 -17
  7. package/cordis.yml +3 -2
  8. package/lib/settings.json +1272 -0
  9. package/lib/types/adapter/channel/ui-policy.d.ts +9 -2
  10. package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
  11. package/lib/types/adapter/channel/ui-policy.js +13 -0
  12. package/lib/types/adapter/kernel/replay.d.ts.map +1 -1
  13. package/lib/types/adapter/kernel/replay.js +2 -0
  14. package/lib/types/adapter/ports/channel-display.d.ts +12 -0
  15. package/lib/types/adapter/ports/channel-display.d.ts.map +1 -1
  16. package/lib/types/adapter/ports/channel-session.d.ts +38 -0
  17. package/lib/types/adapter/ports/channel-session.d.ts.map +1 -1
  18. package/lib/types/adapter/ports/channel-settings.d.ts +12 -0
  19. package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -1
  20. package/lib/types/adapter/ports/channel-ui.d.ts +46 -4
  21. package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
  22. package/lib/types/adapter/ports/channel-view.d.ts +43 -0
  23. package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
  24. package/lib/types/commands.d.ts.map +1 -1
  25. package/lib/types/commands.js +2 -0
  26. package/lib/types/components/BalanceReportRow.d.ts +10 -2
  27. package/lib/types/components/BalanceReportRow.d.ts.map +1 -1
  28. package/lib/types/components/BalanceReportRow.js +18 -4
  29. package/lib/types/components/CompactionStatusRow.d.ts +24 -0
  30. package/lib/types/components/CompactionStatusRow.d.ts.map +1 -0
  31. package/lib/types/components/CompactionStatusRow.js +72 -0
  32. package/lib/types/components/GoalTodoPanel.js +2 -2
  33. package/lib/types/components/HelpMenu.d.ts +2 -2
  34. package/lib/types/components/HelpMenu.d.ts.map +1 -1
  35. package/lib/types/components/HelpMenu.js +5 -4
  36. package/lib/types/components/InlineMathParagraph.d.ts +22 -0
  37. package/lib/types/components/InlineMathParagraph.d.ts.map +1 -0
  38. package/lib/types/components/InlineMathParagraph.js +178 -0
  39. package/lib/types/components/LogoV2.d.ts +41 -3
  40. package/lib/types/components/LogoV2.d.ts.map +1 -1
  41. package/lib/types/components/LogoV2.js +148 -24
  42. package/lib/types/components/Markdown.d.ts +10 -3
  43. package/lib/types/components/Markdown.d.ts.map +1 -1
  44. package/lib/types/components/Markdown.js +47 -14
  45. package/lib/types/components/MathBlock.d.ts +13 -0
  46. package/lib/types/components/MathBlock.d.ts.map +1 -0
  47. package/lib/types/components/MathBlock.js +136 -0
  48. package/lib/types/components/MessageList.d.ts +10 -1
  49. package/lib/types/components/MessageList.d.ts.map +1 -1
  50. package/lib/types/components/MessageList.js +13 -4
  51. package/lib/types/components/MigratePicker.d.ts +30 -0
  52. package/lib/types/components/MigratePicker.d.ts.map +1 -0
  53. package/lib/types/components/MigratePicker.js +38 -0
  54. package/lib/types/components/PromptInput.d.ts +17 -0
  55. package/lib/types/components/PromptInput.d.ts.map +1 -1
  56. package/lib/types/components/PromptInput.js +48 -7
  57. package/lib/types/components/SplitDiffView.d.ts.map +1 -1
  58. package/lib/types/components/SplitDiffView.js +2 -1
  59. package/lib/types/components/StarPrompt.d.ts +53 -0
  60. package/lib/types/components/StarPrompt.d.ts.map +1 -0
  61. package/lib/types/components/StarPrompt.js +281 -0
  62. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
  63. package/lib/types/components/StreamingMarkdown.js +20 -3
  64. package/lib/types/components/TimelineRail.d.ts.map +1 -1
  65. package/lib/types/components/TimelineRail.js +9 -1
  66. package/lib/types/components/Whale.d.ts +17 -8
  67. package/lib/types/components/Whale.d.ts.map +1 -1
  68. package/lib/types/components/Whale.js +25 -15
  69. package/lib/types/components/WhaleGirl.d.ts +29 -0
  70. package/lib/types/components/WhaleGirl.d.ts.map +1 -0
  71. package/lib/types/components/WhaleGirl.js +32 -0
  72. package/lib/types/components/WorkingSpinner.d.ts +4 -1
  73. package/lib/types/components/WorkingSpinner.d.ts.map +1 -1
  74. package/lib/types/components/WorkingSpinner.js +2 -2
  75. package/lib/types/components/bigfont.d.ts +47 -18
  76. package/lib/types/components/bigfont.d.ts.map +1 -1
  77. package/lib/types/components/bigfont.js +55 -40
  78. package/lib/types/components/design-system/ThemeProvider.d.ts +6 -0
  79. package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -1
  80. package/lib/types/components/design-system/ThemeProvider.js +40 -1
  81. package/lib/types/components/maidPortrait.d.ts +44 -0
  82. package/lib/types/components/maidPortrait.d.ts.map +1 -0
  83. package/lib/types/components/maidPortrait.js +178 -0
  84. package/lib/types/components/mathPreview.d.ts +25 -0
  85. package/lib/types/components/mathPreview.d.ts.map +1 -0
  86. package/lib/types/components/mathPreview.js +48 -0
  87. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  88. package/lib/types/components/messages/AssistantThinkingMessage.js +2 -1
  89. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  90. package/lib/types/components/messages/AssistantToolUseMessage.js +3 -2
  91. package/lib/types/components/messages/TranscriptImages.d.ts.map +1 -1
  92. package/lib/types/components/messages/TranscriptImages.js +11 -1
  93. package/lib/types/components/questions/AskUserQuestionPanel.d.ts +14 -2
  94. package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
  95. package/lib/types/components/questions/AskUserQuestionPanel.js +80 -38
  96. package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
  97. package/lib/types/components/questions/PlanReviewPanel.js +3 -3
  98. package/lib/types/components/sessions/ForeignSessionRow.d.ts +34 -0
  99. package/lib/types/components/sessions/ForeignSessionRow.d.ts.map +1 -0
  100. package/lib/types/components/sessions/ForeignSessionRow.js +43 -0
  101. package/lib/types/components/sessions/SourceTabs.d.ts +52 -0
  102. package/lib/types/components/sessions/SourceTabs.d.ts.map +1 -0
  103. package/lib/types/components/sessions/SourceTabs.js +70 -0
  104. package/lib/types/components/splashEggs.d.ts +56 -0
  105. package/lib/types/components/splashEggs.d.ts.map +1 -0
  106. package/lib/types/components/splashEggs.js +67 -0
  107. package/lib/types/components/splashFonts.d.ts +119 -0
  108. package/lib/types/components/splashFonts.d.ts.map +1 -0
  109. package/lib/types/components/splashFonts.js +267 -0
  110. package/lib/types/components/splashLayout.d.ts +41 -0
  111. package/lib/types/components/splashLayout.d.ts.map +1 -0
  112. package/lib/types/components/splashLayout.js +40 -0
  113. package/lib/types/components/whaleGirlSprite.d.ts +17 -0
  114. package/lib/types/components/whaleGirlSprite.d.ts.map +1 -0
  115. package/lib/types/components/whaleGirlSprite.js +47 -0
  116. package/lib/types/deepseekPricing.d.ts +74 -0
  117. package/lib/types/deepseekPricing.d.ts.map +1 -1
  118. package/lib/types/deepseekPricing.js +110 -11
  119. package/lib/types/dsh-adapter/channel/action-readiness.d.ts +1 -1
  120. package/lib/types/dsh-adapter/channel/action-readiness.d.ts.map +1 -1
  121. package/lib/types/dsh-adapter/channel/action-readiness.js +6 -1
  122. package/lib/types/dsh-adapter/channel/background-action.d.ts +1 -0
  123. package/lib/types/dsh-adapter/channel/background-action.d.ts.map +1 -1
  124. package/lib/types/dsh-adapter/channel/background-action.js +1 -0
  125. package/lib/types/dsh-adapter/channel/binding-events.d.ts +8 -9
  126. package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
  127. package/lib/types/dsh-adapter/channel/binding-events.js +69 -21
  128. package/lib/types/dsh-adapter/channel/compaction.d.ts +2 -1
  129. package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -1
  130. package/lib/types/dsh-adapter/channel/compaction.js +35 -2
  131. package/lib/types/dsh-adapter/channel/local-actions.d.ts.map +1 -1
  132. package/lib/types/dsh-adapter/channel/local-actions.js +6 -1
  133. package/lib/types/dsh-adapter/channel/model-switch.d.ts.map +1 -1
  134. package/lib/types/dsh-adapter/channel/model-switch.js +5 -1
  135. package/lib/types/dsh-adapter/channel/paths.d.ts.map +1 -1
  136. package/lib/types/dsh-adapter/channel/paths.js +7 -1
  137. package/lib/types/dsh-adapter/channel/preferences.d.ts +1 -1
  138. package/lib/types/dsh-adapter/channel/preferences.d.ts.map +1 -1
  139. package/lib/types/dsh-adapter/channel/preferences.js +16 -0
  140. package/lib/types/dsh-adapter/channel/projection.d.ts +1 -2
  141. package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -1
  142. package/lib/types/dsh-adapter/channel/projection.js +127 -17
  143. package/lib/types/dsh-adapter/channel/question-record.d.ts +76 -0
  144. package/lib/types/dsh-adapter/channel/question-record.d.ts.map +1 -0
  145. package/lib/types/dsh-adapter/channel/question-record.js +107 -0
  146. package/lib/types/dsh-adapter/channel/session-lineage.d.ts +42 -0
  147. package/lib/types/dsh-adapter/channel/session-lineage.d.ts.map +1 -0
  148. package/lib/types/dsh-adapter/channel/session-lineage.js +51 -0
  149. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts +2 -0
  150. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts.map +1 -1
  151. package/lib/types/dsh-adapter/channel/session-live-adoption.js +9 -3
  152. package/lib/types/dsh-adapter/channel/session-metadata.d.ts +2 -1
  153. package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -1
  154. package/lib/types/dsh-adapter/channel/session-metadata.js +39 -7
  155. package/lib/types/dsh-adapter/channel/session-reset.d.ts +1 -1
  156. package/lib/types/dsh-adapter/channel/session-reset.d.ts.map +1 -1
  157. package/lib/types/dsh-adapter/channel/session-reset.js +7 -0
  158. package/lib/types/dsh-adapter/channel/session-resume.d.ts +1 -0
  159. package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -1
  160. package/lib/types/dsh-adapter/channel/session-resume.js +4 -2
  161. package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -1
  162. package/lib/types/dsh-adapter/channel/settings-host.js +8 -0
  163. package/lib/types/dsh-adapter/channel/state.d.ts +14 -1
  164. package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
  165. package/lib/types/dsh-adapter/channel/state.js +6 -1
  166. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts +30 -35
  167. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
  168. package/lib/types/dsh-adapter/channel/subagent-projection.js +138 -4
  169. package/lib/types/dsh-adapter/channel/types.d.ts +1 -1
  170. package/lib/types/dsh-adapter/channel/types.d.ts.map +1 -1
  171. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  172. package/lib/types/dsh-adapter/channel.js +19 -4
  173. package/lib/types/dsh-adapter/compat/messages.d.ts +6 -0
  174. package/lib/types/dsh-adapter/compat/messages.d.ts.map +1 -1
  175. package/lib/types/dsh-adapter/compat/messages.js +9 -0
  176. package/lib/types/dsh-adapter/contract.d.ts +5 -5
  177. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  178. package/lib/types/dsh-adapter/contract.js +8 -6
  179. package/lib/types/dsh-adapter/index.d.ts +36 -1
  180. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  181. package/lib/types/dsh-adapter/index.js +22 -6
  182. package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts +3 -0
  183. package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts.map +1 -0
  184. package/lib/types/dsh-adapter/migrate/adapters/claude-code.js +131 -0
  185. package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.d.ts +17 -0
  186. package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.d.ts.map +1 -0
  187. package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.js +329 -0
  188. package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts +3 -0
  189. package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts.map +1 -0
  190. package/lib/types/dsh-adapter/migrate/adapters/codex.js +102 -0
  191. package/lib/types/dsh-adapter/migrate/adapters/codex.parse.d.ts +16 -0
  192. package/lib/types/dsh-adapter/migrate/adapters/codex.parse.d.ts.map +1 -0
  193. package/lib/types/dsh-adapter/migrate/adapters/codex.parse.js +289 -0
  194. package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts +3 -0
  195. package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts.map +1 -0
  196. package/lib/types/dsh-adapter/migrate/adapters/grok-build.js +117 -0
  197. package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.d.ts +13 -0
  198. package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.d.ts.map +1 -0
  199. package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.js +178 -0
  200. package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts +3 -0
  201. package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts.map +1 -0
  202. package/lib/types/dsh-adapter/migrate/adapters/omp.js +133 -0
  203. package/lib/types/dsh-adapter/migrate/adapters/scan-fs.d.ts +60 -0
  204. package/lib/types/dsh-adapter/migrate/adapters/scan-fs.d.ts.map +1 -0
  205. package/lib/types/dsh-adapter/migrate/adapters/scan-fs.js +178 -0
  206. package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts +8 -0
  207. package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts.map +1 -0
  208. package/lib/types/dsh-adapter/migrate/adapters/scan.js +40 -0
  209. package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts +3 -0
  210. package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts.map +1 -0
  211. package/lib/types/dsh-adapter/migrate/adapters/zcode.js +93 -0
  212. package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.d.ts +9 -0
  213. package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.d.ts.map +1 -0
  214. package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.js +89 -0
  215. package/lib/types/dsh-adapter/migrate/bin-path.d.ts +6 -0
  216. package/lib/types/dsh-adapter/migrate/bin-path.d.ts.map +1 -0
  217. package/lib/types/dsh-adapter/migrate/bin-path.js +30 -0
  218. package/lib/types/dsh-adapter/migrate/browse.d.ts +42 -0
  219. package/lib/types/dsh-adapter/migrate/browse.d.ts.map +1 -0
  220. package/lib/types/dsh-adapter/migrate/browse.js +90 -0
  221. package/lib/types/dsh-adapter/migrate/cli.d.ts +9 -0
  222. package/lib/types/dsh-adapter/migrate/cli.d.ts.map +1 -0
  223. package/lib/types/dsh-adapter/migrate/cli.js +106 -0
  224. package/lib/types/dsh-adapter/migrate/import-one.d.ts +89 -0
  225. package/lib/types/dsh-adapter/migrate/import-one.d.ts.map +1 -0
  226. package/lib/types/dsh-adapter/migrate/import-one.js +133 -0
  227. package/lib/types/dsh-adapter/migrate/index.d.ts +35 -0
  228. package/lib/types/dsh-adapter/migrate/index.d.ts.map +1 -0
  229. package/lib/types/dsh-adapter/migrate/index.js +107 -0
  230. package/lib/types/dsh-adapter/migrate/parse/injection.d.ts +40 -0
  231. package/lib/types/dsh-adapter/migrate/parse/injection.d.ts.map +1 -0
  232. package/lib/types/dsh-adapter/migrate/parse/injection.js +127 -0
  233. package/lib/types/dsh-adapter/migrate/parse/jsonl.d.ts +28 -0
  234. package/lib/types/dsh-adapter/migrate/parse/jsonl.d.ts.map +1 -0
  235. package/lib/types/dsh-adapter/migrate/parse/jsonl.js +40 -0
  236. package/lib/types/dsh-adapter/migrate/parse/role-turns.d.ts +28 -0
  237. package/lib/types/dsh-adapter/migrate/parse/role-turns.d.ts.map +1 -0
  238. package/lib/types/dsh-adapter/migrate/parse/role-turns.js +50 -0
  239. package/lib/types/dsh-adapter/migrate/parse/title.d.ts +18 -0
  240. package/lib/types/dsh-adapter/migrate/parse/title.d.ts.map +1 -0
  241. package/lib/types/dsh-adapter/migrate/parse/title.js +29 -0
  242. package/lib/types/dsh-adapter/migrate/parse/tools.d.ts +62 -0
  243. package/lib/types/dsh-adapter/migrate/parse/tools.d.ts.map +1 -0
  244. package/lib/types/dsh-adapter/migrate/parse/tools.js +110 -0
  245. package/lib/types/dsh-adapter/migrate/picker.d.ts +64 -0
  246. package/lib/types/dsh-adapter/migrate/picker.d.ts.map +1 -0
  247. package/lib/types/dsh-adapter/migrate/picker.js +86 -0
  248. package/lib/types/dsh-adapter/migrate/recent-agents.d.ts +40 -0
  249. package/lib/types/dsh-adapter/migrate/recent-agents.d.ts.map +1 -0
  250. package/lib/types/dsh-adapter/migrate/recent-agents.js +100 -0
  251. package/lib/types/dsh-adapter/migrate/sessionize.d.ts +39 -0
  252. package/lib/types/dsh-adapter/migrate/sessionize.d.ts.map +1 -0
  253. package/lib/types/dsh-adapter/migrate/sessionize.js +271 -0
  254. package/lib/types/dsh-adapter/migrate/types.d.ts +176 -0
  255. package/lib/types/dsh-adapter/migrate/types.d.ts.map +1 -0
  256. package/lib/types/dsh-adapter/migrate/types.js +11 -0
  257. package/lib/types/dsh-adapter/migrate/uuid.d.ts +7 -0
  258. package/lib/types/dsh-adapter/migrate/uuid.d.ts.map +1 -0
  259. package/lib/types/dsh-adapter/migrate/uuid.js +25 -0
  260. package/lib/types/dsh-adapter/plugin.d.ts +4 -2
  261. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  262. package/lib/types/dsh-adapter/plugin.js +143 -364
  263. package/lib/types/dsh-adapter/providerWizard.d.ts +17 -0
  264. package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -1
  265. package/lib/types/dsh-adapter/providerWizard.js +254 -66
  266. package/lib/types/dsh-adapter/questions.d.ts +22 -15
  267. package/lib/types/dsh-adapter/questions.d.ts.map +1 -1
  268. package/lib/types/dsh-adapter/questions.js +47 -45
  269. package/lib/types/dsh-adapter/sessions/digest.d.ts +11 -6
  270. package/lib/types/dsh-adapter/sessions/digest.d.ts.map +1 -1
  271. package/lib/types/dsh-adapter/sessions/digest.js +20 -13
  272. package/lib/types/dsh-adapter/sessions/frames.d.ts +3 -1
  273. package/lib/types/dsh-adapter/sessions/frames.d.ts.map +1 -1
  274. package/lib/types/dsh-adapter/sessions/frames.js +5 -4
  275. package/lib/types/dsh-adapter/sessions/list.d.ts +6 -1
  276. package/lib/types/dsh-adapter/sessions/list.d.ts.map +1 -1
  277. package/lib/types/dsh-adapter/sessions/list.js +188 -164
  278. package/lib/types/dsh-adapter/sessions/recovery.d.ts +16 -0
  279. package/lib/types/dsh-adapter/sessions/recovery.d.ts.map +1 -0
  280. package/lib/types/dsh-adapter/sessions/recovery.js +108 -0
  281. package/lib/types/dsh-adapter/sessions/snapshot.d.ts +7 -0
  282. package/lib/types/dsh-adapter/sessions/snapshot.d.ts.map +1 -0
  283. package/lib/types/dsh-adapter/sessions/snapshot.js +90 -0
  284. package/lib/types/dsh-adapter/sessions/store.d.ts +10 -4
  285. package/lib/types/dsh-adapter/sessions/store.d.ts.map +1 -1
  286. package/lib/types/dsh-adapter/sessions/store.js +62 -25
  287. package/lib/types/dsh-adapter/sideQuestion.d.ts +41 -2
  288. package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -1
  289. package/lib/types/dsh-adapter/sideQuestion.js +98 -2
  290. package/lib/types/dsh-adapter/subagents.d.ts +28 -3
  291. package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
  292. package/lib/types/dsh-adapter/subagents.js +77 -2
  293. package/lib/types/herdr.d.ts +2 -0
  294. package/lib/types/herdr.d.ts.map +1 -1
  295. package/lib/types/herdr.js +9 -3
  296. package/lib/types/i18n.d.ts +424 -42
  297. package/lib/types/i18n.d.ts.map +1 -1
  298. package/lib/types/i18n.js +145 -20
  299. package/lib/types/ink/components/App.d.ts +2 -2
  300. package/lib/types/ink/components/App.d.ts.map +1 -1
  301. package/lib/types/ink/components/App.js +5 -1
  302. package/lib/types/ink/components/Image.d.ts +14 -1
  303. package/lib/types/ink/components/Image.d.ts.map +1 -1
  304. package/lib/types/ink/components/Image.js +2 -2
  305. package/lib/types/ink/events/input-event.js +3 -3
  306. package/lib/types/ink/hooks/use-terminal-images.d.ts +12 -0
  307. package/lib/types/ink/hooks/use-terminal-images.d.ts.map +1 -1
  308. package/lib/types/ink/hooks/use-terminal-images.js +13 -0
  309. package/lib/types/ink/ink.d.ts +6 -0
  310. package/lib/types/ink/ink.d.ts.map +1 -1
  311. package/lib/types/ink/ink.js +16 -1
  312. package/lib/types/ink/kitty-graphics.d.ts +44 -3
  313. package/lib/types/ink/kitty-graphics.d.ts.map +1 -1
  314. package/lib/types/ink/kitty-graphics.js +184 -23
  315. package/lib/types/ink/output.d.ts +24 -2
  316. package/lib/types/ink/output.d.ts.map +1 -1
  317. package/lib/types/ink/output.js +83 -5
  318. package/lib/types/ink/parse-keypress.d.ts +26 -1
  319. package/lib/types/ink/parse-keypress.d.ts.map +1 -1
  320. package/lib/types/ink/parse-keypress.js +156 -13
  321. package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
  322. package/lib/types/ink/render-node-to-output.js +8 -1
  323. package/lib/types/ink/screen.d.ts +24 -0
  324. package/lib/types/ink/screen.d.ts.map +1 -1
  325. package/lib/types/ink/screen.js +89 -0
  326. package/lib/types/ink/selection.d.ts +40 -18
  327. package/lib/types/ink/selection.d.ts.map +1 -1
  328. package/lib/types/ink/selection.js +142 -30
  329. package/lib/types/ink/sixel-codec.d.ts +12 -1
  330. package/lib/types/ink/sixel-codec.d.ts.map +1 -1
  331. package/lib/types/ink/sixel-codec.js +29 -5
  332. package/lib/types/ink/sixel-graphics.d.ts.map +1 -1
  333. package/lib/types/ink/sixel-graphics.js +5 -3
  334. package/lib/types/ink/styles.d.ts +9 -0
  335. package/lib/types/ink/styles.d.ts.map +1 -1
  336. package/lib/types/ink/terminal-image.d.ts +8 -0
  337. package/lib/types/ink/terminal-image.d.ts.map +1 -1
  338. package/lib/types/ink/terminal-querier.d.ts +7 -1
  339. package/lib/types/ink/terminal-querier.d.ts.map +1 -1
  340. package/lib/types/ink/terminal-querier.js +12 -2
  341. package/lib/types/ink/timeline-rail.d.ts +5 -0
  342. package/lib/types/ink/timeline-rail.d.ts.map +1 -1
  343. package/lib/types/math/inline-layout.d.ts +29 -0
  344. package/lib/types/math/inline-layout.d.ts.map +1 -0
  345. package/lib/types/math/inline-layout.js +106 -0
  346. package/lib/types/math/layout.d.ts +58 -0
  347. package/lib/types/math/layout.d.ts.map +1 -0
  348. package/lib/types/math/layout.js +59 -0
  349. package/lib/types/math/renderer.d.ts +64 -0
  350. package/lib/types/math/renderer.d.ts.map +1 -0
  351. package/lib/types/math/renderer.js +256 -0
  352. package/lib/types/screens/Chat.d.ts +14 -1
  353. package/lib/types/screens/Chat.d.ts.map +1 -1
  354. package/lib/types/screens/Chat.js +606 -53
  355. package/lib/types/screens/SessionSupervisor.d.ts +2 -1
  356. package/lib/types/screens/SessionSupervisor.d.ts.map +1 -1
  357. package/lib/types/screens/SessionSupervisor.js +156 -19
  358. package/lib/types/screens/Settings.d.ts.map +1 -1
  359. package/lib/types/screens/Settings.js +49 -11
  360. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  361. package/lib/types/screens/StatusLine.js +45 -15
  362. package/lib/types/screens/chatOverlay.d.ts +5 -0
  363. package/lib/types/screens/chatOverlay.d.ts.map +1 -1
  364. package/lib/types/screens/chatOverlay.js +1 -0
  365. package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.d.ts +47 -0
  366. package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.d.ts.map +1 -0
  367. package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.js +65 -0
  368. package/lib/types/screens/sessionSupervisor/model.d.ts +12 -0
  369. package/lib/types/screens/sessionSupervisor/model.d.ts.map +1 -1
  370. package/lib/types/screens/sessionSupervisor/model.js +26 -0
  371. package/lib/types/screens/sessionSupervisor/useForeignSessions.d.ts +107 -0
  372. package/lib/types/screens/sessionSupervisor/useForeignSessions.d.ts.map +1 -0
  373. package/lib/types/screens/sessionSupervisor/useForeignSessions.js +312 -0
  374. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts +4 -1
  375. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts.map +1 -1
  376. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.js +97 -14
  377. package/lib/types/sessionHistory.d.ts +2 -2
  378. package/lib/types/sessionHistory.d.ts.map +1 -1
  379. package/lib/types/sessionHistory.js +31 -5
  380. package/lib/types/settings/definitions.d.ts +681 -0
  381. package/lib/types/settings/definitions.d.ts.map +1 -0
  382. package/lib/types/settings/definitions.js +511 -0
  383. package/lib/types/starAction.d.ts +44 -0
  384. package/lib/types/starAction.d.ts.map +1 -0
  385. package/lib/types/starAction.js +52 -0
  386. package/lib/types/terminal-utils/latex.d.ts +10 -0
  387. package/lib/types/terminal-utils/latex.d.ts.map +1 -0
  388. package/lib/types/terminal-utils/latex.js +1417 -0
  389. package/lib/types/terminal-utils/markdown.d.ts +3 -1
  390. package/lib/types/terminal-utils/markdown.d.ts.map +1 -1
  391. package/lib/types/terminal-utils/markdown.js +26 -1
  392. package/lib/types/terminal-utils/math.d.ts +66 -0
  393. package/lib/types/terminal-utils/math.d.ts.map +1 -0
  394. package/lib/types/terminal-utils/math.js +337 -0
  395. package/lib/types/tips.d.ts.map +1 -1
  396. package/lib/types/tips.js +6 -0
  397. package/lib/types/tuiDisplayPrefs.d.ts +67 -0
  398. package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
  399. package/lib/types/tuiDisplayPrefs.js +59 -0
  400. package/lib/types/ui.d.ts +1 -1
  401. package/lib/types/ui.d.ts.map +1 -1
  402. package/lib/types/ui.js +1 -1
  403. package/lib/types/usageStats.d.ts +98 -0
  404. package/lib/types/usageStats.d.ts.map +1 -0
  405. package/lib/types/usageStats.js +169 -0
  406. package/lib/types/utils/bmp.d.ts +17 -0
  407. package/lib/types/utils/bmp.d.ts.map +1 -0
  408. package/lib/types/utils/bmp.js +154 -0
  409. package/lib/types/utils/clipboard.d.ts +14 -2
  410. package/lib/types/utils/clipboard.d.ts.map +1 -1
  411. package/lib/types/utils/clipboard.js +143 -8
  412. package/lib/types/utils/fold-long-lines.d.ts.map +1 -1
  413. package/lib/types/utils/fold-long-lines.js +2 -1
  414. package/lib/types/utils/keymap.d.ts +4 -1
  415. package/lib/types/utils/keymap.d.ts.map +1 -1
  416. package/lib/types/utils/keymap.js +8 -0
  417. package/lib/types/utils/modifiers.d.ts +4 -3
  418. package/lib/types/utils/modifiers.d.ts.map +1 -1
  419. package/lib/types/utils/modifiers.js +4 -3
  420. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/LICENSE +202 -0
  421. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/NOTICE +20 -0
  422. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/index.d.ts +16 -0
  423. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/bundled-packages.json +4 -0
  424. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/index.mjs +20 -0
  425. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/index.mjs.LEGAL.txt +35 -0
  426. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/package.json +29 -0
  427. package/package.json +111 -97
@@ -0,0 +1,1417 @@
1
+ /**
2
+ * LaTeX math → terminal Unicode text (a TeX subset: symbols, scripts,
3
+ * fractions, roots, accents, operator limits, matrices, cases, aligned).
4
+ *
5
+ * VENDORED — do not restyle. Copied from Pi's TUI package so upstream fixes
6
+ * can be re-applied with a plain diff; the file keeps Pi's formatting (tabs,
7
+ * double quotes, semicolons) on purpose, like the Ink-derived renderer.
8
+ *
9
+ * Source: https://github.com/earendil-works/pi (formerly badlogic/pi-mono)
10
+ * packages/tui/src/latex.ts
11
+ * Commit: fa0e1f48ac (last change to the file) at snapshot 2b0a123de9, 2026-09-26
12
+ * Local: the `visibleWidth` import now points at this repo's display-width
13
+ * helper; nothing else is changed. Integration (delimiters, size cap,
14
+ * single-line policy, fallback) lives in ./math.ts, not here.
15
+ * Re-sync: diff this file against upstream packages/tui/src/latex.ts, keep
16
+ * the import line and this header, then run
17
+ * `pnpm verify:latex-math`.
18
+ *
19
+ * MIT License
20
+ *
21
+ * Copyright (c) 2025 Mario Zechner
22
+ *
23
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
24
+ * of this software and associated documentation files (the "Software"), to deal
25
+ * in the Software without restriction, including without limitation the rights
26
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27
+ * copies of the Software, and to permit persons to whom the Software is
28
+ * furnished to do so, subject to the following conditions:
29
+ *
30
+ * The above copyright notice and this permission notice shall be included in all
31
+ * copies or substantial portions of the Software.
32
+ *
33
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39
+ * SOFTWARE.
40
+ */
41
+ import { stringWidth as visibleWidth } from "../ink/stringWidth.js";
42
+ const SYMBOLS = {
43
+ alpha: "α",
44
+ beta: "β",
45
+ gamma: "γ",
46
+ delta: "δ",
47
+ epsilon: "ϵ",
48
+ varepsilon: "ε",
49
+ zeta: "ζ",
50
+ eta: "η",
51
+ theta: "θ",
52
+ vartheta: "ϑ",
53
+ iota: "ι",
54
+ kappa: "κ",
55
+ varkappa: "ϰ",
56
+ lambda: "λ",
57
+ mu: "μ",
58
+ nu: "ν",
59
+ xi: "ξ",
60
+ pi: "π",
61
+ varpi: "ϖ",
62
+ rho: "ρ",
63
+ varrho: "ϱ",
64
+ sigma: "σ",
65
+ varsigma: "ς",
66
+ tau: "τ",
67
+ upsilon: "υ",
68
+ phi: "ϕ",
69
+ varphi: "φ",
70
+ chi: "χ",
71
+ psi: "ψ",
72
+ omega: "ω",
73
+ Gamma: "Γ",
74
+ Delta: "Δ",
75
+ Theta: "Θ",
76
+ Lambda: "Λ",
77
+ Xi: "Ξ",
78
+ Pi: "Π",
79
+ Sigma: "Σ",
80
+ Upsilon: "Υ",
81
+ Phi: "Φ",
82
+ Psi: "Ψ",
83
+ Omega: "Ω",
84
+ pm: "±",
85
+ mp: "∓",
86
+ times: "×",
87
+ div: "÷",
88
+ cdot: "·",
89
+ ast: "∗",
90
+ star: "⋆",
91
+ circ: "∘",
92
+ bullet: "•",
93
+ oplus: "⊕",
94
+ ominus: "⊖",
95
+ otimes: "⊗",
96
+ oslash: "⊘",
97
+ odot: "⊙",
98
+ bigcirc: "○",
99
+ dagger: "†",
100
+ ddagger: "‡",
101
+ amalg: "⨿",
102
+ uplus: "⊎",
103
+ sqcap: "⊓",
104
+ sqcup: "⊔",
105
+ bowtie: "⋈",
106
+ Join: "⋈",
107
+ ltimes: "⋉",
108
+ rtimes: "⋊",
109
+ leftouterjoin: "⟕",
110
+ rightouterjoin: "⟖",
111
+ fullouterjoin: "⟗",
112
+ triangleleft: "◁",
113
+ triangleright: "▷",
114
+ wr: "≀",
115
+ cap: "∩",
116
+ cup: "∪",
117
+ bigcap: "⋂",
118
+ bigcup: "⋃",
119
+ bigwedge: "⋀",
120
+ bigvee: "⋁",
121
+ bigsqcup: "⨆",
122
+ biguplus: "⨄",
123
+ bigoplus: "⨁",
124
+ bigotimes: "⨂",
125
+ bigodot: "⨀",
126
+ setminus: "∖",
127
+ in: "∈",
128
+ notin: "∉",
129
+ ni: "∋",
130
+ subset: "⊂",
131
+ supset: "⊃",
132
+ subseteq: "⊆",
133
+ supseteq: "⊇",
134
+ sqsubset: "⊏",
135
+ sqsupset: "⊐",
136
+ sqsubseteq: "⊑",
137
+ sqsupseteq: "⊒",
138
+ prec: "≺",
139
+ preceq: "≼",
140
+ succ: "≻",
141
+ succeq: "≽",
142
+ ll: "≪",
143
+ gg: "≫",
144
+ le: "≤",
145
+ leq: "≤",
146
+ leqslant: "≤",
147
+ ge: "≥",
148
+ geq: "≥",
149
+ geqslant: "≥",
150
+ ne: "≠",
151
+ neq: "≠",
152
+ equiv: "≡",
153
+ approx: "≈",
154
+ sim: "∼",
155
+ simeq: "≃",
156
+ cong: "≅",
157
+ asymp: "≍",
158
+ doteq: "≐",
159
+ propto: "∝",
160
+ parallel: "∥",
161
+ perp: "⊥",
162
+ mid: "∣",
163
+ vdash: "⊢",
164
+ dashv: "⊣",
165
+ models: "⊨",
166
+ Vdash: "⊩",
167
+ Vvdash: "⊪",
168
+ nvdash: "⊬",
169
+ nvDash: "⊭",
170
+ forall: "∀",
171
+ exists: "∃",
172
+ nexists: "∄",
173
+ neg: "¬",
174
+ land: "∧",
175
+ wedge: "∧",
176
+ lor: "∨",
177
+ vee: "∨",
178
+ to: "→",
179
+ rightarrow: "→",
180
+ longrightarrow: "→",
181
+ leftarrow: "←",
182
+ longleftarrow: "←",
183
+ gets: "←",
184
+ leftrightarrow: "↔",
185
+ longleftrightarrow: "↔",
186
+ hookleftarrow: "↩",
187
+ hookrightarrow: "↪",
188
+ twoheadleftarrow: "↞",
189
+ twoheadrightarrow: "↠",
190
+ leftharpoonup: "↼",
191
+ leftharpoondown: "↽",
192
+ rightharpoonup: "⇀",
193
+ rightharpoondown: "⇁",
194
+ rightleftharpoons: "⇌",
195
+ leftrightharpoons: "⇋",
196
+ nearrow: "↗",
197
+ searrow: "↘",
198
+ swarrow: "↙",
199
+ nwarrow: "↖",
200
+ rightsquigarrow: "⇝",
201
+ leadsto: "⇝",
202
+ Rightarrow: "⇒",
203
+ Longrightarrow: "⇒",
204
+ Leftarrow: "⇐",
205
+ Longleftarrow: "⇐",
206
+ Leftrightarrow: "⇔",
207
+ Longleftrightarrow: "⇔",
208
+ implies: "⇒",
209
+ iff: "⇔",
210
+ mapsto: "↦",
211
+ longmapsto: "↦",
212
+ uparrow: "↑",
213
+ downarrow: "↓",
214
+ partial: "∂",
215
+ nabla: "∇",
216
+ int: "∫",
217
+ iint: "∬",
218
+ iiint: "∭",
219
+ oint: "∮",
220
+ sum: "∑",
221
+ prod: "∏",
222
+ coprod: "∐",
223
+ infty: "∞",
224
+ emptyset: "∅",
225
+ varnothing: "∅",
226
+ angle: "∠",
227
+ therefore: "∴",
228
+ because: "∵",
229
+ aleph: "ℵ",
230
+ beth: "ℶ",
231
+ gimel: "ℷ",
232
+ daleth: "ℸ",
233
+ top: "⊤",
234
+ bot: "⊥",
235
+ triangle: "△",
236
+ square: "□",
237
+ lozenge: "◊",
238
+ checkmark: "✓",
239
+ complement: "∁",
240
+ wp: "℘",
241
+ prime: "′",
242
+ ldots: "…",
243
+ dots: "…",
244
+ cdots: "⋯",
245
+ vdots: "⋮",
246
+ ddots: "⋱",
247
+ ell: "ℓ",
248
+ hbar: "ℏ",
249
+ Im: "ℑ",
250
+ Re: "ℜ",
251
+ langle: "⟨",
252
+ rangle: "⟩",
253
+ vert: "|",
254
+ lvert: "|",
255
+ rvert: "|",
256
+ Vert: "‖",
257
+ lVert: "‖",
258
+ rVert: "‖",
259
+ lbrace: "{",
260
+ rbrace: "}",
261
+ backslash: "\\",
262
+ lfloor: "⌊",
263
+ rfloor: "⌋",
264
+ lceil: "⌈",
265
+ rceil: "⌉",
266
+ colon: ":",
267
+ };
268
+ const NAMED_OPERATORS = new Set([
269
+ "arccos",
270
+ "arcsin",
271
+ "arctan",
272
+ "arg",
273
+ "cos",
274
+ "cosh",
275
+ "cot",
276
+ "coth",
277
+ "csc",
278
+ "deg",
279
+ "det",
280
+ "dim",
281
+ "exp",
282
+ "gcd",
283
+ "hom",
284
+ "inf",
285
+ "ker",
286
+ "lg",
287
+ "lim",
288
+ "liminf",
289
+ "limsup",
290
+ "ln",
291
+ "log",
292
+ "max",
293
+ "min",
294
+ "Pr",
295
+ "sec",
296
+ "sin",
297
+ "sinh",
298
+ "sup",
299
+ "tan",
300
+ "tanh",
301
+ ]);
302
+ const LIMIT_OPERATORS = new Set([
303
+ "argmax",
304
+ "argmin",
305
+ "inf",
306
+ "injlim",
307
+ "lim",
308
+ "liminf",
309
+ "limsup",
310
+ "max",
311
+ "min",
312
+ "projlim",
313
+ "sup",
314
+ ]);
315
+ const DISPLAY_LIMIT_SYMBOLS = new Set([
316
+ "bigcap",
317
+ "bigcup",
318
+ "bigodot",
319
+ "bigoplus",
320
+ "bigotimes",
321
+ "bigsqcup",
322
+ "biguplus",
323
+ "bigvee",
324
+ "bigwedge",
325
+ "coprod",
326
+ "int",
327
+ "iint",
328
+ "iiint",
329
+ "oint",
330
+ "prod",
331
+ "sum",
332
+ ]);
333
+ const RELATION_COMMANDS = new Set([
334
+ "Leftarrow",
335
+ "Leftrightarrow",
336
+ "Longleftarrow",
337
+ "Longleftrightarrow",
338
+ "Longrightarrow",
339
+ "Rightarrow",
340
+ "Join",
341
+ "Vdash",
342
+ "Vvdash",
343
+ "approx",
344
+ "asymp",
345
+ "bowtie",
346
+ "cong",
347
+ "dashv",
348
+ "fullouterjoin",
349
+ "doteq",
350
+ "downarrow",
351
+ "equiv",
352
+ "ge",
353
+ "geq",
354
+ "geqslant",
355
+ "gets",
356
+ "gg",
357
+ "hookleftarrow",
358
+ "hookrightarrow",
359
+ "iff",
360
+ "implies",
361
+ "in",
362
+ "leadsto",
363
+ "le",
364
+ "leftarrow",
365
+ "leftharpoondown",
366
+ "leftharpoonup",
367
+ "leftrightarrow",
368
+ "leftrightharpoons",
369
+ "leftouterjoin",
370
+ "leq",
371
+ "leqslant",
372
+ "ll",
373
+ "longleftarrow",
374
+ "longleftrightarrow",
375
+ "longmapsto",
376
+ "longrightarrow",
377
+ "ltimes",
378
+ "mapsto",
379
+ "mid",
380
+ "models",
381
+ "ne",
382
+ "nearrow",
383
+ "neq",
384
+ "ni",
385
+ "notin",
386
+ "nvdash",
387
+ "nvDash",
388
+ "nwarrow",
389
+ "parallel",
390
+ "perp",
391
+ "prec",
392
+ "preceq",
393
+ "propto",
394
+ "rightharpoondown",
395
+ "rightharpoonup",
396
+ "rightleftharpoons",
397
+ "rightouterjoin",
398
+ "rightarrow",
399
+ "rightsquigarrow",
400
+ "rtimes",
401
+ "searrow",
402
+ "sim",
403
+ "simeq",
404
+ "sqsubset",
405
+ "sqsubseteq",
406
+ "sqsupset",
407
+ "sqsupseteq",
408
+ "subset",
409
+ "subseteq",
410
+ "succ",
411
+ "succeq",
412
+ "supset",
413
+ "supseteq",
414
+ "swarrow",
415
+ "to",
416
+ "triangleleft",
417
+ "triangleright",
418
+ "twoheadleftarrow",
419
+ "twoheadrightarrow",
420
+ "uparrow",
421
+ "vdash",
422
+ ]);
423
+ const NEGATED_SYMBOLS = {
424
+ "<": "≮",
425
+ ">": "≯",
426
+ "=": "≠",
427
+ "∈": "∉",
428
+ "∋": "∌",
429
+ "∣": "∤",
430
+ "∥": "∦",
431
+ "∼": "≁",
432
+ "≃": "≄",
433
+ "≅": "≇",
434
+ "≈": "≉",
435
+ "≡": "≢",
436
+ "≤": "≰",
437
+ "≥": "≱",
438
+ "≺": "⊀",
439
+ "≻": "⊁",
440
+ "⊂": "⊄",
441
+ "⊃": "⊅",
442
+ "⊆": "⊈",
443
+ "⊇": "⊉",
444
+ "⊢": "⊬",
445
+ "⊨": "⊭",
446
+ "↔": "↮",
447
+ "←": "↚",
448
+ "→": "↛",
449
+ "⇒": "⇏",
450
+ "⇐": "⇍",
451
+ "⇔": "⇎",
452
+ "≼": "⋠",
453
+ "≽": "⋡",
454
+ };
455
+ const BLACKBOARD = {
456
+ C: "ℂ",
457
+ H: "ℍ",
458
+ N: "ℕ",
459
+ P: "ℙ",
460
+ Q: "ℚ",
461
+ R: "ℝ",
462
+ Z: "ℤ",
463
+ };
464
+ const SUPERSCRIPTS = {
465
+ "0": "⁰",
466
+ "1": "¹",
467
+ "2": "²",
468
+ "3": "³",
469
+ "4": "⁴",
470
+ "5": "⁵",
471
+ "6": "⁶",
472
+ "7": "⁷",
473
+ "8": "⁸",
474
+ "9": "⁹",
475
+ "+": "⁺",
476
+ "-": "⁻",
477
+ "=": "⁼",
478
+ "(": "⁽",
479
+ ")": "⁾",
480
+ a: "ᵃ",
481
+ b: "ᵇ",
482
+ c: "ᶜ",
483
+ d: "ᵈ",
484
+ e: "ᵉ",
485
+ f: "ᶠ",
486
+ g: "ᵍ",
487
+ h: "ʰ",
488
+ i: "ⁱ",
489
+ j: "ʲ",
490
+ k: "ᵏ",
491
+ l: "ˡ",
492
+ m: "ᵐ",
493
+ n: "ⁿ",
494
+ o: "ᵒ",
495
+ p: "ᵖ",
496
+ r: "ʳ",
497
+ s: "ˢ",
498
+ t: "ᵗ",
499
+ u: "ᵘ",
500
+ v: "ᵛ",
501
+ w: "ʷ",
502
+ x: "ˣ",
503
+ y: "ʸ",
504
+ z: "ᶻ",
505
+ };
506
+ const SUBSCRIPTS = {
507
+ "0": "₀",
508
+ "1": "₁",
509
+ "2": "₂",
510
+ "3": "₃",
511
+ "4": "₄",
512
+ "5": "₅",
513
+ "6": "₆",
514
+ "7": "₇",
515
+ "8": "₈",
516
+ "9": "₉",
517
+ "+": "₊",
518
+ "-": "₋",
519
+ "=": "₌",
520
+ "(": "₍",
521
+ ")": "₎",
522
+ a: "ₐ",
523
+ e: "ₑ",
524
+ h: "ₕ",
525
+ i: "ᵢ",
526
+ j: "ⱼ",
527
+ k: "ₖ",
528
+ l: "ₗ",
529
+ m: "ₘ",
530
+ n: "ₙ",
531
+ o: "ₒ",
532
+ p: "ₚ",
533
+ r: "ᵣ",
534
+ s: "ₛ",
535
+ t: "ₜ",
536
+ u: "ᵤ",
537
+ v: "ᵥ",
538
+ x: "ₓ",
539
+ };
540
+ const SPACING_COMMANDS = new Set([
541
+ ",",
542
+ ":",
543
+ ";",
544
+ " ",
545
+ ">",
546
+ "enspace",
547
+ "enskip",
548
+ "medspace",
549
+ "quad",
550
+ "qquad",
551
+ "thickspace",
552
+ "thinspace",
553
+ ]);
554
+ const NEGATIVE_SPACING_COMMANDS = new Set(["!", "negmedspace", "negthickspace", "negthinspace"]);
555
+ const NEGATIVE_SPACE = "\u0000";
556
+ const FONT_SWITCH_COMMANDS = new Set(["bf", "cal", "it", "rm", "sf", "sl", "tt"]);
557
+ const IGNORED_COMMANDS = new Set([
558
+ "displaystyle",
559
+ "limits",
560
+ "nolimits",
561
+ "scriptstyle",
562
+ "scriptscriptstyle",
563
+ "textstyle",
564
+ ]);
565
+ const SIZE_COMMANDS = new Set([
566
+ "big",
567
+ "Big",
568
+ "bigg",
569
+ "Bigg",
570
+ "bigl",
571
+ "Bigl",
572
+ "biggl",
573
+ "Biggl",
574
+ "bigr",
575
+ "Bigr",
576
+ "biggr",
577
+ "Biggr",
578
+ ]);
579
+ const PLAIN_WRAPPERS = new Set([
580
+ "emph",
581
+ "mathcal",
582
+ "mathbf",
583
+ "mathfrak",
584
+ "mathit",
585
+ "mathrm",
586
+ "mathnormal",
587
+ "mathscr",
588
+ "mathsf",
589
+ "mathtt",
590
+ "mathup",
591
+ "mbox",
592
+ "overbrace",
593
+ "pmb",
594
+ "smash",
595
+ "substack",
596
+ "text",
597
+ "textbf",
598
+ "textit",
599
+ "textmd",
600
+ "textnormal",
601
+ "textrm",
602
+ "textsc",
603
+ "textsf",
604
+ "textsl",
605
+ "texttt",
606
+ "textup",
607
+ "underbrace",
608
+ "bm",
609
+ "boldsymbol",
610
+ ]);
611
+ const ACCENTS = {
612
+ acute: "\u0301",
613
+ bar: "\u0305",
614
+ breve: "\u0306",
615
+ check: "\u030c",
616
+ ddot: "\u0308",
617
+ dot: "\u0307",
618
+ grave: "\u0300",
619
+ hat: "\u0302",
620
+ mathring: "\u030a",
621
+ overleftarrow: "\u20d6",
622
+ overleftrightarrow: "\u20e1",
623
+ overline: "\u0305",
624
+ overrightarrow: "\u20d7",
625
+ tilde: "\u0303",
626
+ underline: "\u0332",
627
+ vec: "\u20d7",
628
+ widehat: "\u0302",
629
+ widetilde: "\u0303",
630
+ };
631
+ function replaceCharacters(value, replacements) {
632
+ let result = "";
633
+ for (const character of value) {
634
+ const replacement = replacements[character];
635
+ if (replacement === undefined) {
636
+ return undefined;
637
+ }
638
+ result += replacement;
639
+ }
640
+ return result;
641
+ }
642
+ function normalizeScriptValue(value) {
643
+ return value.trim().replace(/\s*([=+-])\s*/g, "$1");
644
+ }
645
+ function formatUnicodeScript(value, kind) {
646
+ return replaceCharacters(normalizeScriptValue(value), kind === "sub" ? SUBSCRIPTS : SUPERSCRIPTS);
647
+ }
648
+ function formatScript(value, kind) {
649
+ value = normalizeScriptValue(value);
650
+ const unicode = formatUnicodeScript(value, kind);
651
+ if (unicode !== undefined) {
652
+ return unicode;
653
+ }
654
+ const prefix = kind === "sub" ? "_" : "^";
655
+ if (Array.from(value).length === 1 || (kind === "sub" && /^[A-Za-z]+$/.test(value))) {
656
+ return `${prefix}${value}`;
657
+ }
658
+ return `${prefix}(${value})`;
659
+ }
660
+ function formatFraction(numerator, denominator) {
661
+ numerator = numerator.trim();
662
+ denominator = denominator.trim();
663
+ const simpleNumerator = /^[\p{L}\p{N}.]+$/u.test(numerator);
664
+ const simpleDenominator = /^[\p{N}.]+$/u.test(denominator) || Array.from(denominator).length === 1;
665
+ return `${simpleNumerator ? numerator : `(${numerator})`}/${simpleDenominator ? denominator : `(${denominator})`}`;
666
+ }
667
+ function formatRoot(value, symbol = "√") {
668
+ value = value.trim();
669
+ return /^[\p{L}\p{N}.]+$/u.test(value) ? `${symbol}${value}` : `${symbol}(${value})`;
670
+ }
671
+ const NAMED_OPERATOR_START = "\u{f0004}";
672
+ const NAMED_OPERATOR_END = "\u{f0005}";
673
+ const NAMED_OPERATOR_LEFT_SPACING_PATTERN = /(?<=[\p{L}\p{N})\]}\u{f0001}])\u{f0004}/gu;
674
+ const NAMED_OPERATOR_RIGHT_SPACING_PATTERN = /\u{f0005}(?=[\p{L}\p{N}√\u{f0000}])/gu;
675
+ function normalizeOutput(value) {
676
+ return value
677
+ .replace(NAMED_OPERATOR_LEFT_SPACING_PATTERN, " ")
678
+ .replaceAll(NAMED_OPERATOR_START, "")
679
+ .replace(NAMED_OPERATOR_RIGHT_SPACING_PATTERN, " ")
680
+ .replaceAll(NAMED_OPERATOR_END, "")
681
+ .split("\n")
682
+ .map((line) => line.replace(/[ \t]+/g, " ").trim())
683
+ .filter((line, index, lines) => line.length > 0 || (index > 0 && index < lines.length - 1))
684
+ .join("\n")
685
+ .trim();
686
+ }
687
+ const LAYOUT_MARKER_START = "\u{f0000}";
688
+ const LAYOUT_MARKER_END = "\u{f0001}";
689
+ const LAYOUT_MARKER_PATTERN = /\u{f0000}(\d+)\u{f0001}/gu;
690
+ const TRAILING_LAYOUT_MARKER_PATTERN = /\u{f0000}(\d+)\u{f0001}$/u;
691
+ const PROTECTED_SPACE = "\u{f0002}";
692
+ function padLayoutLine(line, width, centered = false) {
693
+ const padding = Math.max(0, width - visibleWidth(line));
694
+ const left = centered ? Math.floor(padding / 2) : 0;
695
+ return `${" ".repeat(left)}${line}${" ".repeat(padding - left)}`;
696
+ }
697
+ function joinLayouts(layouts) {
698
+ if (layouts.length === 0) {
699
+ return { lines: [""], width: 0, baseline: 0 };
700
+ }
701
+ const baseline = Math.max(...layouts.map((layout) => layout.baseline));
702
+ const below = Math.max(...layouts.map((layout) => layout.lines.length - layout.baseline - 1));
703
+ const lines = [];
704
+ for (let row = 0; row <= baseline + below; row++) {
705
+ let line = "";
706
+ for (const layout of layouts) {
707
+ const sourceRow = row - baseline + layout.baseline;
708
+ line +=
709
+ sourceRow >= 0 && sourceRow < layout.lines.length
710
+ ? padLayoutLine(layout.lines[sourceRow] ?? "", layout.width)
711
+ : " ".repeat(layout.width);
712
+ }
713
+ lines.push(line.trimEnd());
714
+ }
715
+ return {
716
+ lines,
717
+ width: layouts.reduce((width, layout) => width + layout.width, 0),
718
+ baseline,
719
+ };
720
+ }
721
+ function renderLayout(source, nodes) {
722
+ const renderedLines = [];
723
+ let firstBaseline = 0;
724
+ for (const sourceLine of source.split("\n")) {
725
+ const layouts = [];
726
+ let position = 0;
727
+ let previousNode;
728
+ for (const match of sourceLine.matchAll(LAYOUT_MARKER_PATTERN)) {
729
+ const index = match.index;
730
+ const node = nodes[Number(match[1])];
731
+ if (!node) {
732
+ continue;
733
+ }
734
+ if (index > position) {
735
+ const sliced = sourceLine.slice(position, index);
736
+ const trimmed = (previousNode ? sliced.trimStart() : sliced).trimEnd();
737
+ const preserveLeadingSpace = previousNode?.type === "matrix" && /^\s/.test(sliced);
738
+ const preserveTrailingSpace = node.type === "matrix" && /\s$/.test(sliced);
739
+ const text = trimmed
740
+ ? `${preserveLeadingSpace ? " " : ""}${trimmed}${preserveTrailingSpace ? " " : ""}`
741
+ : preserveLeadingSpace || preserveTrailingSpace
742
+ ? " "
743
+ : "";
744
+ layouts.push({ lines: [text], width: visibleWidth(text), baseline: 0 });
745
+ }
746
+ if (node.type === "fraction") {
747
+ const numerator = renderLayout(node.numerator, nodes);
748
+ const denominator = renderLayout(node.denominator, nodes);
749
+ const contentWidth = Math.max(numerator.width, denominator.width, 1);
750
+ const width = contentWidth + 2;
751
+ layouts.push({
752
+ lines: [
753
+ ...numerator.lines.map((line) => padLayoutLine(line, width, true)),
754
+ ` ${"─".repeat(contentWidth)} `,
755
+ ...denominator.lines.map((line) => padLayoutLine(line, width, true)),
756
+ ],
757
+ width,
758
+ baseline: numerator.lines.length,
759
+ });
760
+ }
761
+ else if (node.type === "operator") {
762
+ const contentWidth = Math.max(visibleWidth(node.operator), node.lower === undefined ? 0 : visibleWidth(node.lower), node.upper === undefined ? 0 : visibleWidth(node.upper));
763
+ const lines = [];
764
+ if (node.upper !== undefined) {
765
+ lines.push(`${padLayoutLine(node.upper, contentWidth, true)} `);
766
+ }
767
+ lines.push(`${padLayoutLine(node.operator, contentWidth, true)} `);
768
+ if (node.lower !== undefined) {
769
+ lines.push(`${padLayoutLine(node.lower, contentWidth, true)} `);
770
+ }
771
+ layouts.push({
772
+ lines,
773
+ width: contentWidth + 1,
774
+ baseline: node.upper === undefined ? 0 : 1,
775
+ });
776
+ }
777
+ else if (node.type === "script") {
778
+ const upper = node.upper === undefined ? undefined : renderLayout(node.upper, nodes);
779
+ const lower = node.lower === undefined ? undefined : renderLayout(node.lower, nodes);
780
+ const width = Math.max(upper?.width ?? 0, lower?.width ?? 0);
781
+ layouts.push({
782
+ lines: [
783
+ ...(upper?.lines.map((line) => padLayoutLine(line, width)) ?? []),
784
+ " ".repeat(width),
785
+ ...(lower?.lines.map((line) => padLayoutLine(line, width)) ?? []),
786
+ ],
787
+ width,
788
+ baseline: upper?.lines.length ?? 0,
789
+ });
790
+ }
791
+ else {
792
+ const width = Math.max(0, ...node.lines.map((line) => visibleWidth(line)));
793
+ layouts.push({
794
+ lines: node.lines.map((line) => padLayoutLine(line, width)),
795
+ width,
796
+ baseline: node.baseline,
797
+ });
798
+ }
799
+ position = index + match[0].length;
800
+ previousNode = node;
801
+ }
802
+ if (position < sourceLine.length) {
803
+ const sliced = sourceLine.slice(position);
804
+ const trimmed = previousNode ? sliced.trimStart() : sliced;
805
+ const text = previousNode?.type === "matrix" && /^\s/.test(sliced) ? ` ${trimmed}` : trimmed;
806
+ layouts.push({ lines: [text], width: visibleWidth(text), baseline: 0 });
807
+ }
808
+ const lineLayout = joinLayouts(layouts);
809
+ if (renderedLines.length === 0) {
810
+ firstBaseline = lineLayout.baseline;
811
+ }
812
+ renderedLines.push(...lineLayout.lines);
813
+ }
814
+ return {
815
+ lines: renderedLines,
816
+ width: Math.max(0, ...renderedLines.map((line) => visibleWidth(line))),
817
+ baseline: firstBaseline,
818
+ };
819
+ }
820
+ class LatexParser {
821
+ source;
822
+ layoutNodes;
823
+ display;
824
+ position = 0;
825
+ supported = true;
826
+ stackFractions = true;
827
+ scriptDepth = 0;
828
+ constructor(source, layoutNodes, display) {
829
+ this.source = source;
830
+ this.layoutNodes = layoutNodes;
831
+ this.display = display;
832
+ }
833
+ render() {
834
+ const rendered = this.parseSequence();
835
+ if (!this.supported || this.position !== this.source.length) {
836
+ return undefined;
837
+ }
838
+ return normalizeOutput(rendered);
839
+ }
840
+ parseSequence(endCharacter) {
841
+ let result = "";
842
+ while (this.position < this.source.length) {
843
+ const character = this.source[this.position];
844
+ if (endCharacter && character === endCharacter) {
845
+ this.position++;
846
+ return result;
847
+ }
848
+ if (character === "}") {
849
+ this.supported = false;
850
+ return result;
851
+ }
852
+ if (character === "{") {
853
+ this.position++;
854
+ result += this.parseSequence("}");
855
+ continue;
856
+ }
857
+ if (character === "\\") {
858
+ const command = this.parseCommand();
859
+ if (command === NEGATIVE_SPACE) {
860
+ result = result.trimEnd();
861
+ if (result.endsWith(NAMED_OPERATOR_END)) {
862
+ result = result.slice(0, -NAMED_OPERATOR_END.length);
863
+ }
864
+ }
865
+ else {
866
+ result += command;
867
+ }
868
+ continue;
869
+ }
870
+ if (character === "^" || character === "_") {
871
+ this.position++;
872
+ result = result.trimEnd();
873
+ const script = this.parseScripts(character);
874
+ if (result.endsWith(NAMED_OPERATOR_END)) {
875
+ result = `${result.slice(0, -NAMED_OPERATOR_END.length)}${script}${NAMED_OPERATOR_END}`;
876
+ }
877
+ else {
878
+ result += script;
879
+ }
880
+ continue;
881
+ }
882
+ if (/\s/.test(character)) {
883
+ result += this.parseWhitespace();
884
+ continue;
885
+ }
886
+ if (character === "=" || character === "<" || character === ">") {
887
+ result = `${result.trimEnd()} ${character} `;
888
+ this.position++;
889
+ continue;
890
+ }
891
+ if (character === "&") {
892
+ this.position++;
893
+ continue;
894
+ }
895
+ if (character === "~") {
896
+ this.position++;
897
+ result += " ";
898
+ continue;
899
+ }
900
+ if (character === ".") {
901
+ const marker = TRAILING_LAYOUT_MARKER_PATTERN.exec(result);
902
+ const node = marker ? this.layoutNodes[Number(marker[1])] : undefined;
903
+ if (node?.type === "matrix") {
904
+ const lastLine = node.lines.length - 1;
905
+ node.lines[lastLine] = `${node.lines[lastLine] ?? ""}${character}`;
906
+ this.position++;
907
+ continue;
908
+ }
909
+ }
910
+ result += character;
911
+ this.position++;
912
+ }
913
+ if (endCharacter) {
914
+ this.supported = false;
915
+ }
916
+ return result;
917
+ }
918
+ parseScripts(initialMarker) {
919
+ const scripts = {};
920
+ const order = [];
921
+ const parse = (marker) => {
922
+ const kind = marker === "_" ? "sub" : "sup";
923
+ this.scriptDepth++;
924
+ try {
925
+ scripts[kind] = this.parseRequiredArgument(false);
926
+ }
927
+ finally {
928
+ this.scriptDepth--;
929
+ }
930
+ order.push(kind);
931
+ };
932
+ parse(initialMarker);
933
+ let nextPosition = this.position;
934
+ while (nextPosition < this.source.length && /\s/.test(this.source[nextPosition] ?? "")) {
935
+ nextPosition++;
936
+ }
937
+ const nextMarker = this.source[nextPosition];
938
+ if ((nextMarker === "^" || nextMarker === "_") && nextMarker !== initialMarker) {
939
+ this.position = nextPosition + 1;
940
+ parse(nextMarker);
941
+ }
942
+ const subUnicode = scripts.sub === undefined ? undefined : formatUnicodeScript(scripts.sub, "sub");
943
+ const supUnicode = scripts.sup === undefined ? undefined : formatUnicodeScript(scripts.sup, "sup");
944
+ const canUseLayout = ![scripts.sub, scripts.sup].some((value) => value !== undefined &&
945
+ (value.includes("/") ||
946
+ (!value.includes(LAYOUT_MARKER_START) && Array.from(value).length > 1 && !/[A-Z*∗]/.test(value))));
947
+ const needsLayout = this.display &&
948
+ canUseLayout &&
949
+ (this.scriptDepth > 0 ||
950
+ (scripts.sub !== undefined && subUnicode === undefined) ||
951
+ (scripts.sup !== undefined && supUnicode === undefined));
952
+ if (!needsLayout) {
953
+ return order
954
+ .map((kind) => kind === "sub"
955
+ ? (subUnicode ?? formatScript(scripts.sub ?? "", kind))
956
+ : (supUnicode ?? formatScript(scripts.sup ?? "", kind)))
957
+ .join("");
958
+ }
959
+ const index = this.layoutNodes.push({
960
+ type: "script",
961
+ lower: scripts.sub === undefined ? undefined : normalizeOutput(scripts.sub),
962
+ upper: scripts.sup === undefined ? undefined : normalizeOutput(scripts.sup),
963
+ }) - 1;
964
+ return `${LAYOUT_MARKER_START}${index}${LAYOUT_MARKER_END}`;
965
+ }
966
+ parseWhitespace() {
967
+ while (this.position < this.source.length && /\s/.test(this.source[this.position] ?? "")) {
968
+ this.position++;
969
+ }
970
+ return " ";
971
+ }
972
+ parseCommand() {
973
+ this.position++;
974
+ if (this.position >= this.source.length) {
975
+ this.supported = false;
976
+ return "";
977
+ }
978
+ let command = "";
979
+ const first = this.source[this.position] ?? "";
980
+ if (first === "\n" || first === "\r") {
981
+ this.position++;
982
+ if (first === "\r" && this.source[this.position] === "\n") {
983
+ this.position++;
984
+ }
985
+ return " ";
986
+ }
987
+ if (/[A-Za-z]/.test(first)) {
988
+ const start = this.position;
989
+ while (this.position < this.source.length && /[A-Za-z]/.test(this.source[this.position] ?? "")) {
990
+ this.position++;
991
+ }
992
+ command = this.source.slice(start, this.position);
993
+ }
994
+ else {
995
+ command = first;
996
+ this.position++;
997
+ }
998
+ if (command === "\\") {
999
+ return "\n";
1000
+ }
1001
+ if (SPACING_COMMANDS.has(command)) {
1002
+ return " ";
1003
+ }
1004
+ if (NEGATIVE_SPACING_COMMANDS.has(command)) {
1005
+ return NEGATIVE_SPACE;
1006
+ }
1007
+ if (FONT_SWITCH_COMMANDS.has(command)) {
1008
+ while (this.position < this.source.length && /\s/.test(this.source[this.position] ?? "")) {
1009
+ this.position++;
1010
+ }
1011
+ return "";
1012
+ }
1013
+ if (IGNORED_COMMANDS.has(command)) {
1014
+ return "";
1015
+ }
1016
+ if (command === "{" ||
1017
+ command === "}" ||
1018
+ command === "$" ||
1019
+ command === "%" ||
1020
+ command === "#" ||
1021
+ command === "_" ||
1022
+ command === "&") {
1023
+ return command;
1024
+ }
1025
+ if (command === "|") {
1026
+ return "‖";
1027
+ }
1028
+ if (command === "not") {
1029
+ const value = this.parseRequiredArgument(false).trim();
1030
+ const negated = NEGATED_SYMBOLS[value];
1031
+ if (negated !== undefined) {
1032
+ return ` ${negated} `;
1033
+ }
1034
+ const characters = Array.from(value);
1035
+ if (characters.length === 0) {
1036
+ this.supported = false;
1037
+ return "";
1038
+ }
1039
+ return ` ${characters[0]}\u0338${characters.slice(1).join("")} `;
1040
+ }
1041
+ if (LIMIT_OPERATORS.has(command)) {
1042
+ return this.parseOperator(command, "bracket", true, true);
1043
+ }
1044
+ const symbol = SYMBOLS[command];
1045
+ if (symbol !== undefined) {
1046
+ if (DISPLAY_LIMIT_SYMBOLS.has(command)) {
1047
+ return this.parseOperator(symbol, "script", true);
1048
+ }
1049
+ return command === "cdot" || command === "times" || RELATION_COMMANDS.has(command) ? ` ${symbol} ` : symbol;
1050
+ }
1051
+ if (NAMED_OPERATORS.has(command)) {
1052
+ return `${NAMED_OPERATOR_START}${command}${NAMED_OPERATOR_END}`;
1053
+ }
1054
+ if (SIZE_COMMANDS.has(command)) {
1055
+ return "";
1056
+ }
1057
+ if (command === "left" || command === "middle" || command === "right") {
1058
+ if (this.source[this.position] === ".") {
1059
+ this.position++;
1060
+ }
1061
+ return "";
1062
+ }
1063
+ if (command === "frac" || command === "dfrac" || command === "tfrac") {
1064
+ const shouldStack = this.display && this.stackFractions && command !== "tfrac";
1065
+ const numerator = this.parseRequiredArgument(!shouldStack);
1066
+ const denominator = this.parseRequiredArgument(!shouldStack);
1067
+ if (shouldStack) {
1068
+ const index = this.layoutNodes.push({
1069
+ type: "fraction",
1070
+ numerator: normalizeOutput(numerator),
1071
+ denominator: normalizeOutput(denominator),
1072
+ }) - 1;
1073
+ return `${LAYOUT_MARKER_START}${index}${LAYOUT_MARKER_END}`;
1074
+ }
1075
+ return formatFraction(numerator, denominator);
1076
+ }
1077
+ if (command === "sqrt") {
1078
+ const degree = this.parseOptionalArgument()?.trim();
1079
+ const value = this.parseRequiredArgument();
1080
+ if (degree === undefined || degree === "2") {
1081
+ return formatRoot(value);
1082
+ }
1083
+ if (degree === "3") {
1084
+ return formatRoot(value, "∛");
1085
+ }
1086
+ if (degree === "4") {
1087
+ return formatRoot(value, "∜");
1088
+ }
1089
+ return `${formatScript(degree, "sup")}${formatRoot(value)}`;
1090
+ }
1091
+ if (command === "boxed" || command === "fbox") {
1092
+ return `[${this.parseRequiredArgument().trim()}]`;
1093
+ }
1094
+ if (command === "binom" || command === "dbinom" || command === "tbinom") {
1095
+ return `(${this.parseRequiredArgument()} choose ${this.parseRequiredArgument()})`;
1096
+ }
1097
+ const accent = ACCENTS[command];
1098
+ if (accent !== undefined) {
1099
+ const value = this.parseRequiredArgument();
1100
+ return Array.from(value).length === 1 ? `${value}${accent}` : `${command}(${value})`;
1101
+ }
1102
+ if (command === "mathbb") {
1103
+ const value = this.parseRequiredArgument();
1104
+ return Array.from(value, (character) => BLACKBOARD[character] ?? character).join("");
1105
+ }
1106
+ if (command === "operatorname") {
1107
+ const starred = this.source[this.position] === "*";
1108
+ if (starred) {
1109
+ this.position++;
1110
+ }
1111
+ const operator = normalizeOutput(this.parseRequiredArgument()).trim();
1112
+ return this.parseOperator(operator, "bracket", starred, true);
1113
+ }
1114
+ if (command === "mod" || command === "bmod") {
1115
+ return " mod ";
1116
+ }
1117
+ if (command === "pmod" || command === "pod") {
1118
+ const value = this.parseRequiredArgument().trim();
1119
+ return command === "pmod" ? ` (mod ${value})` : ` (${value})`;
1120
+ }
1121
+ if (command === "overset" || command === "stackrel") {
1122
+ const upper = this.parseRequiredArgument();
1123
+ const value = this.parseRequiredArgument().trim();
1124
+ return `${value}${formatScript(upper, "sup")}`;
1125
+ }
1126
+ if (command === "underset") {
1127
+ const lower = this.parseRequiredArgument();
1128
+ const value = this.parseRequiredArgument().trim();
1129
+ return `${value}${formatScript(lower, "sub")}`;
1130
+ }
1131
+ if (PLAIN_WRAPPERS.has(command)) {
1132
+ const value = this.parseRequiredArgument();
1133
+ return command.startsWith("text") || command === "mbox" ? value : value.trim();
1134
+ }
1135
+ if (command === "begin") {
1136
+ return this.parseEnvironment();
1137
+ }
1138
+ if (command === "end") {
1139
+ this.supported = false;
1140
+ return "";
1141
+ }
1142
+ this.supported = false;
1143
+ return `\\${command}`;
1144
+ }
1145
+ parseOperator(operator, inlineLowerStyle, displayLimits, spaced = false) {
1146
+ let useDisplayLimits = displayLimits;
1147
+ let modifierPosition = this.position;
1148
+ while (modifierPosition < this.source.length && /[ \t]/.test(this.source[modifierPosition] ?? "")) {
1149
+ modifierPosition++;
1150
+ }
1151
+ const modifier = /^\\(limits|nolimits)(?![A-Za-z])/.exec(this.source.slice(modifierPosition));
1152
+ if (modifier) {
1153
+ useDisplayLimits = modifier[1] === "limits";
1154
+ this.position = modifierPosition + modifier[0].length;
1155
+ }
1156
+ let lower;
1157
+ let upper;
1158
+ while (true) {
1159
+ let scriptPosition = this.position;
1160
+ while (scriptPosition < this.source.length && /[ \t]/.test(this.source[scriptPosition] ?? "")) {
1161
+ scriptPosition++;
1162
+ }
1163
+ const kind = this.source[scriptPosition];
1164
+ if (kind !== "_" && kind !== "^") {
1165
+ break;
1166
+ }
1167
+ this.position = scriptPosition + 1;
1168
+ const value = normalizeOutput(this.parseRequiredArgument(false)).replaceAll(" ", "");
1169
+ if (kind === "_") {
1170
+ if (lower !== undefined) {
1171
+ this.supported = false;
1172
+ }
1173
+ lower = value;
1174
+ }
1175
+ else {
1176
+ if (upper !== undefined) {
1177
+ this.supported = false;
1178
+ }
1179
+ upper = value;
1180
+ }
1181
+ }
1182
+ if (this.display && useDisplayLimits && (lower !== undefined || upper !== undefined)) {
1183
+ const index = this.layoutNodes.push({ type: "operator", operator, lower, upper }) - 1;
1184
+ return `${LAYOUT_MARKER_START}${index}${LAYOUT_MARKER_END}`;
1185
+ }
1186
+ let rendered = operator;
1187
+ if (lower !== undefined) {
1188
+ rendered += inlineLowerStyle === "bracket" ? `[${lower}]` : formatScript(lower, "sub");
1189
+ }
1190
+ if (upper !== undefined) {
1191
+ rendered += formatScript(upper, "sup");
1192
+ }
1193
+ return spaced ? ` ${rendered} ` : rendered;
1194
+ }
1195
+ parseRequiredArgument(stackFractions = true) {
1196
+ const previousStackFractions = this.stackFractions;
1197
+ this.stackFractions = previousStackFractions && stackFractions;
1198
+ const value = this.parseRequiredArgumentValue();
1199
+ this.stackFractions = previousStackFractions;
1200
+ return value;
1201
+ }
1202
+ parseRequiredArgumentValue() {
1203
+ while (this.position < this.source.length && /\s/.test(this.source[this.position] ?? "")) {
1204
+ this.position++;
1205
+ }
1206
+ if (this.position >= this.source.length) {
1207
+ this.supported = false;
1208
+ return "";
1209
+ }
1210
+ if (this.source[this.position] === "{") {
1211
+ this.position++;
1212
+ return this.parseSequence("}");
1213
+ }
1214
+ if (this.source[this.position] === "\\") {
1215
+ return this.parseCommand();
1216
+ }
1217
+ const value = this.source[this.position] ?? "";
1218
+ this.position++;
1219
+ return value;
1220
+ }
1221
+ parseOptionalArgument() {
1222
+ while (this.position < this.source.length && /[ \t]/.test(this.source[this.position] ?? "")) {
1223
+ this.position++;
1224
+ }
1225
+ if (this.source[this.position] !== "[") {
1226
+ return undefined;
1227
+ }
1228
+ const end = this.source.indexOf("]", this.position + 1);
1229
+ if (end < 0) {
1230
+ this.supported = false;
1231
+ return undefined;
1232
+ }
1233
+ const value = this.source.slice(this.position + 1, end);
1234
+ this.position = end + 1;
1235
+ return this.renderNested(value);
1236
+ }
1237
+ readRawGroup() {
1238
+ while (this.position < this.source.length && /[ \t]/.test(this.source[this.position] ?? "")) {
1239
+ this.position++;
1240
+ }
1241
+ if (this.source[this.position] !== "{") {
1242
+ this.supported = false;
1243
+ return undefined;
1244
+ }
1245
+ const start = ++this.position;
1246
+ let depth = 1;
1247
+ while (this.position < this.source.length) {
1248
+ const character = this.source[this.position];
1249
+ if (character === "\\") {
1250
+ this.position += 2;
1251
+ continue;
1252
+ }
1253
+ if (character === "{")
1254
+ depth++;
1255
+ if (character === "}")
1256
+ depth--;
1257
+ if (depth === 0) {
1258
+ const value = this.source.slice(start, this.position);
1259
+ this.position++;
1260
+ return value;
1261
+ }
1262
+ this.position++;
1263
+ }
1264
+ this.supported = false;
1265
+ return undefined;
1266
+ }
1267
+ splitEnvironmentRows(body) {
1268
+ return body.split(/\\\\(?:\[[^\]\n]*\])?/);
1269
+ }
1270
+ parseEnvironment() {
1271
+ const environment = this.readRawGroup();
1272
+ if (!environment) {
1273
+ return "";
1274
+ }
1275
+ const endMarker = `\\end{${environment}}`;
1276
+ const end = this.source.indexOf(endMarker, this.position);
1277
+ if (end < 0) {
1278
+ this.supported = false;
1279
+ return "";
1280
+ }
1281
+ const body = this.source.slice(this.position, end);
1282
+ this.position = end + endMarker.length;
1283
+ if (environment === "equation" || environment === "equation*" || environment === "displaymath") {
1284
+ return this.renderNested(body).trim();
1285
+ }
1286
+ if (environment === "aligned" ||
1287
+ environment === "align" ||
1288
+ environment === "align*" ||
1289
+ environment === "alignedat" ||
1290
+ environment === "alignat" ||
1291
+ environment === "alignat*" ||
1292
+ environment === "gather" ||
1293
+ environment === "gathered" ||
1294
+ environment === "multline" ||
1295
+ environment === "multline*" ||
1296
+ environment === "split") {
1297
+ const alignedAt = ["alignedat", "alignat", "alignat*"].includes(environment);
1298
+ const alignedBody = alignedAt ? body.replace(/^\s*\{[^}]*\}/, "") : body;
1299
+ return this.splitEnvironmentRows(alignedBody)
1300
+ .map((row) => {
1301
+ const cells = row.split("&");
1302
+ const source = alignedAt
1303
+ ? Array.from({ length: Math.ceil(cells.length / 2) }, (_, index) => cells.slice(index * 2, index * 2 + 2).join("")).join(" ")
1304
+ : cells.join("");
1305
+ return this.renderNested(source).trim();
1306
+ })
1307
+ .filter(Boolean)
1308
+ .join("\n");
1309
+ }
1310
+ if (environment === "cases" || environment === "cases*") {
1311
+ return this.renderCases(body);
1312
+ }
1313
+ if (["array", "matrix", "smallmatrix", "pmatrix", "bmatrix", "Bmatrix", "vmatrix", "Vmatrix"].includes(environment)) {
1314
+ const matrixBody = environment === "array" ? body.replace(/^\s*\{[^}]*\}/, "") : body;
1315
+ return this.renderMatrix(environment, matrixBody);
1316
+ }
1317
+ this.supported = false;
1318
+ return body;
1319
+ }
1320
+ renderCases(body) {
1321
+ const rows = this.splitEnvironmentRows(body)
1322
+ .map((row) => row.split("&").map((cell) => this.renderNested(cell, false).trim()))
1323
+ .filter((row) => row.some(Boolean));
1324
+ const valueWidth = Math.max(0, ...rows.map((row) => visibleWidth((row[0] ?? "").replace(/,\s*$/, ""))));
1325
+ const contents = rows.map((row) => {
1326
+ const value = (row[0] ?? "").replace(/,\s*$/, "");
1327
+ const condition = row[1] ?? "";
1328
+ if (!condition) {
1329
+ return value;
1330
+ }
1331
+ const conditionPrefix = /^(?:if|when|for|otherwise)\b/i.test(condition) ? " " : " if ";
1332
+ return `${value}${PROTECTED_SPACE.repeat(valueWidth - visibleWidth(value))}${conditionPrefix}${condition}`;
1333
+ });
1334
+ if (contents.length <= 1) {
1335
+ return contents.length === 0 ? "" : `⎧ ${contents[0]}`;
1336
+ }
1337
+ const middle = Math.floor(contents.length / 2);
1338
+ const visualRows = [...contents];
1339
+ if (contents.length % 2 === 0) {
1340
+ visualRows.splice(middle, 0, undefined);
1341
+ }
1342
+ const lines = visualRows.map((content, index) => {
1343
+ const delimiter = index === 0 ? "⎧" : index === visualRows.length - 1 ? "⎩" : "⎨";
1344
+ return content === undefined ? delimiter : `${delimiter} ${content}`;
1345
+ });
1346
+ const index = this.layoutNodes.push({ type: "matrix", lines, baseline: middle }) - 1;
1347
+ return `${LAYOUT_MARKER_START}${index}${LAYOUT_MARKER_END}`;
1348
+ }
1349
+ renderMatrix(environment, body) {
1350
+ const matrix = this.splitEnvironmentRows(body)
1351
+ .map((row) => row.split("&").map((cell) => this.renderNested(cell, false).trim()))
1352
+ .filter((row) => row.some(Boolean));
1353
+ const columnCount = Math.max(0, ...matrix.map((row) => row.length));
1354
+ const columnWidths = Array.from({ length: columnCount }, (_, column) => Math.max(0, ...matrix.map((row) => visibleWidth(row[column] ?? ""))));
1355
+ const rows = matrix.map((row) => Array.from({ length: columnCount }, (_, column) => {
1356
+ const cell = row[column] ?? "";
1357
+ return `${cell}${PROTECTED_SPACE.repeat(Math.max(0, (columnWidths[column] ?? 0) - visibleWidth(cell)))}`;
1358
+ }).join(" │ "));
1359
+ let lines;
1360
+ if (environment === "array" || environment === "matrix" || environment === "smallmatrix") {
1361
+ lines = rows;
1362
+ }
1363
+ else {
1364
+ const delimiters = {
1365
+ pmatrix: ["⎛", "⎞", "⎜", "⎟", "⎝", "⎠"],
1366
+ bmatrix: ["⎡", "⎤", "⎢", "⎥", "⎣", "⎦"],
1367
+ Bmatrix: ["⎧", "⎫", "⎨", "⎬", "⎩", "⎭"],
1368
+ vmatrix: ["│", "│", "│", "│", "│", "│"],
1369
+ Vmatrix: ["║", "║", "║", "║", "║", "║"],
1370
+ };
1371
+ const delimiter = delimiters[environment];
1372
+ if (!delimiter) {
1373
+ this.supported = false;
1374
+ return rows.join("\n");
1375
+ }
1376
+ lines = rows.map((row, index) => {
1377
+ const left = index === 0 ? delimiter[0] : index === rows.length - 1 ? delimiter[4] : delimiter[2];
1378
+ const right = index === 0 ? delimiter[1] : index === rows.length - 1 ? delimiter[5] : delimiter[3];
1379
+ return `${left} ${row} ${right}`;
1380
+ });
1381
+ }
1382
+ if (lines.length <= 1) {
1383
+ return lines[0] ?? "";
1384
+ }
1385
+ const index = this.layoutNodes.push({ type: "matrix", lines, baseline: 0 }) - 1;
1386
+ return `${LAYOUT_MARKER_START}${index}${LAYOUT_MARKER_END}`;
1387
+ }
1388
+ renderNested(source, stackFractions = true) {
1389
+ const rendered = new LatexParser(source, this.layoutNodes, this.display && stackFractions).render();
1390
+ if (rendered === undefined) {
1391
+ this.supported = false;
1392
+ return source;
1393
+ }
1394
+ return rendered;
1395
+ }
1396
+ }
1397
+ /**
1398
+ * Render a basic LaTeX math expression as terminal-friendly Unicode text.
1399
+ * Returns undefined when the expression contains unsupported or malformed syntax.
1400
+ */
1401
+ export function renderLatex(source, options = {}) {
1402
+ const layoutNodes = [];
1403
+ const rendered = new LatexParser(source, layoutNodes, options.display === true).render();
1404
+ if (rendered === undefined) {
1405
+ return undefined;
1406
+ }
1407
+ if (layoutNodes.length === 0) {
1408
+ return rendered.replaceAll(PROTECTED_SPACE, " ");
1409
+ }
1410
+ const lines = renderLayout(rendered, layoutNodes).lines;
1411
+ const indentation = Math.min(...lines.filter((line) => line.trim()).map((line) => line.length - line.trimStart().length));
1412
+ return lines
1413
+ .map((line) => line.slice(indentation).trimEnd())
1414
+ .join("\n")
1415
+ .trimEnd()
1416
+ .replaceAll(PROTECTED_SPACE, " ");
1417
+ }