flexdesk 0.17.17 → 0.18.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 (300) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/LICENSE +0 -0
  3. package/README.md +1 -0
  4. package/THIRD_PARTY_LICENSES.md +0 -0
  5. package/canvas.js +0 -0
  6. package/charts.js +0 -0
  7. package/core.js +0 -0
  8. package/css/flexdesk.css +7499 -5851
  9. package/css/reset.css +1 -1
  10. package/css/tokens.css +23 -1
  11. package/dist/canvas.js +0 -0
  12. package/dist/canvas.js.map +0 -0
  13. package/dist/charts.js +10 -6
  14. package/dist/charts.js.map +1 -1
  15. package/dist/chunk-3PHCPZHT.js +0 -0
  16. package/dist/chunk-3PHCPZHT.js.map +0 -0
  17. package/dist/chunk-5W4EEKSK.js +778 -0
  18. package/dist/chunk-5W4EEKSK.js.map +7 -0
  19. package/dist/chunk-DNJ3N4T4.js +82 -0
  20. package/dist/chunk-DNJ3N4T4.js.map +7 -0
  21. package/dist/chunk-FOOS3T5L.js +0 -0
  22. package/dist/chunk-FOOS3T5L.js.map +0 -0
  23. package/dist/chunk-GOQLR5WR.js +0 -0
  24. package/dist/chunk-GOQLR5WR.js.map +0 -0
  25. package/dist/{chunk-JKZLNKG6.js → chunk-HKPB6OFA.js} +90 -25
  26. package/dist/{chunk-JKZLNKG6.js.map → chunk-HKPB6OFA.js.map} +2 -2
  27. package/dist/chunk-HNU6MM2B.js +0 -0
  28. package/dist/chunk-HNU6MM2B.js.map +0 -0
  29. package/dist/{chunk-REJ5HLIM.js → chunk-HYJYYEPK.js} +2 -2
  30. package/dist/chunk-JYWURG5T.js +0 -0
  31. package/dist/chunk-JYWURG5T.js.map +0 -0
  32. package/dist/{chunk-7U4IB65H.js → chunk-LLBJ2SJH.js} +5 -3
  33. package/dist/{chunk-7U4IB65H.js.map → chunk-LLBJ2SJH.js.map} +1 -1
  34. package/dist/chunk-N7HC3ADV.js +0 -0
  35. package/dist/chunk-N7HC3ADV.js.map +0 -0
  36. package/dist/{chunk-7OL6F2AM.js → chunk-P74F6I6P.js} +6 -4
  37. package/dist/{chunk-7OL6F2AM.js.map → chunk-P74F6I6P.js.map} +1 -1
  38. package/dist/chunk-PAI2ZUWV.js +260 -0
  39. package/dist/chunk-PAI2ZUWV.js.map +7 -0
  40. package/dist/chunk-Q7BALEPX.js +527 -0
  41. package/dist/chunk-Q7BALEPX.js.map +7 -0
  42. package/dist/chunk-QXAOTGCC.js +40 -0
  43. package/dist/chunk-QXAOTGCC.js.map +7 -0
  44. package/dist/{chunk-XJNADRGR.js → chunk-RKVYIXDC.js} +664 -91
  45. package/dist/chunk-RKVYIXDC.js.map +7 -0
  46. package/dist/{chunk-2Z2ENHR3.js → chunk-U5GKJUOC.js} +3 -3
  47. package/dist/{chunk-2Z2ENHR3.js.map → chunk-U5GKJUOC.js.map} +1 -1
  48. package/dist/chunk-UKP22RUG.js +219 -0
  49. package/dist/chunk-UKP22RUG.js.map +7 -0
  50. package/dist/chunk-VLOAI3HS.js +43 -0
  51. package/dist/chunk-VLOAI3HS.js.map +7 -0
  52. package/dist/{chunk-WUFLGETN.js → chunk-WVFGV5FT.js} +2 -39
  53. package/dist/{chunk-WUFLGETN.js.map → chunk-WVFGV5FT.js.map} +3 -3
  54. package/dist/{chunk-PGZ4EHSE.js → chunk-ZL3VKINP.js} +41 -390
  55. package/dist/chunk-ZL3VKINP.js.map +7 -0
  56. package/dist/editor.js +3 -2
  57. package/dist/editor.js.map +1 -1
  58. package/dist/flexdesk.css +7499 -5851
  59. package/dist/flow.js +29 -97
  60. package/dist/flow.js.map +3 -3
  61. package/dist/git.js +1356 -0
  62. package/dist/git.js.map +7 -0
  63. package/dist/host.js +0 -0
  64. package/dist/host.js.map +0 -0
  65. package/dist/reset.css +1 -1
  66. package/dist/tile_registry-6WZPTUZV.js +0 -0
  67. package/dist/tile_registry-6WZPTUZV.js.map +0 -0
  68. package/dist/tiles.js +20 -15
  69. package/dist/tiles.js.map +2 -2
  70. package/dist/tokens.css +23 -1
  71. package/dist/widgets.js +3969 -1189
  72. package/dist/widgets.js.map +4 -4
  73. package/dist/wm.js +121 -33
  74. package/dist/wm.js.map +2 -2
  75. package/docs/README.md +9 -4
  76. package/docs/best-practices.md +2 -2
  77. package/docs/components/chat-shell.md +198 -0
  78. package/docs/components/command-palette.md +0 -0
  79. package/docs/components/conversation.md +10 -0
  80. package/docs/components/data-table-grid.md +0 -0
  81. package/docs/components/data-table.md +0 -0
  82. package/docs/components/editor.md +0 -0
  83. package/docs/components/filter-builder.md +246 -0
  84. package/docs/components/flow-canvas-editor.md +0 -0
  85. package/docs/components/flow-editors.md +0 -0
  86. package/docs/components/flow-lane-editor.md +0 -0
  87. package/docs/components/flow-outline-editor.md +0 -0
  88. package/docs/components/forms-and-dialogs.md +22 -0
  89. package/docs/components/git.md +355 -0
  90. package/docs/components/input-fields.md +167 -2
  91. package/docs/components/keymap.md +8 -0
  92. package/docs/components/markdown-and-outline.md +0 -0
  93. package/docs/components/menus.md +120 -3
  94. package/docs/components/panels-and-desktops.md +16 -5
  95. package/docs/components/record-list-and-fact-table.md +0 -0
  96. package/docs/components/settings-view.md +0 -0
  97. package/docs/components/shell.md +104 -1
  98. package/docs/components/wizard.md +0 -0
  99. package/docs/components/workspace-picker.md +149 -0
  100. package/docs/concepts/building-and-packaging.md +2 -2
  101. package/docs/concepts/domain-neutrality.md +0 -0
  102. package/docs/concepts/host-port.md +0 -0
  103. package/docs/concepts/packages-and-entry-points.md +14 -13
  104. package/docs/concepts/peer-dependencies.md +0 -0
  105. package/docs/concepts/state-guard.md +3 -3
  106. package/docs/quickstart.md +1 -1
  107. package/editor.js +0 -0
  108. package/flow.js +0 -0
  109. package/git.js +13 -0
  110. package/host.js +0 -0
  111. package/package.json +6 -1
  112. package/src/canvas/canvas_adapter.js +0 -0
  113. package/src/canvas/edge_router.js +0 -0
  114. package/src/canvas/graph/connector_router.js +0 -0
  115. package/src/canvas/graph/history_service.js +0 -0
  116. package/src/canvas/graph/node_platform.js +0 -0
  117. package/src/canvas/index.js +0 -0
  118. package/src/canvas/layered_layout.js +0 -0
  119. package/src/charts/data_series_plot_window.js +0 -0
  120. package/src/charts/downsample.js +0 -0
  121. package/src/charts/plot_config.js +0 -0
  122. package/src/charts/plotly_wrapper.js +0 -0
  123. package/src/core/event_bus.js +0 -0
  124. package/src/core/logging.js +0 -0
  125. package/src/core/settings.js +0 -0
  126. package/src/core/state_guard.js +0 -0
  127. package/src/core/state_machine.js +0 -0
  128. package/src/editor/editor_pane.js +0 -0
  129. package/src/editor/monaco_editor_factory.js +0 -0
  130. package/src/editor/monaco_loader.js +0 -0
  131. package/src/editor/notebook_search.js +0 -0
  132. package/src/editor/notebook_undo_manager.js +0 -0
  133. package/src/editor/split_pane_container.js +0 -0
  134. package/src/flow/canvas_editor/connections.js +0 -0
  135. package/src/flow/canvas_editor/editor.js +0 -0
  136. package/src/flow/canvas_editor/index.js +0 -0
  137. package/src/flow/canvas_editor/layout.js +0 -0
  138. package/src/flow/canvas_editor/strings.js +0 -0
  139. package/src/flow/kit/always_before.js +0 -0
  140. package/src/flow/kit/catalogue.js +0 -0
  141. package/src/flow/kit/chip_input.js +0 -0
  142. package/src/flow/kit/dom.js +28 -119
  143. package/src/flow/kit/findings.js +0 -0
  144. package/src/flow/kit/history.js +0 -0
  145. package/src/flow/kit/index.js +0 -0
  146. package/src/flow/kit/keys.js +0 -0
  147. package/src/flow/kit/logic_graph.js +0 -0
  148. package/src/flow/kit/references.js +0 -0
  149. package/src/flow/kit/settings_panel.js +0 -0
  150. package/src/flow/kit/settings_schema.js +0 -0
  151. package/src/flow/kit/step_picker.js +1 -1
  152. package/src/flow/kit/strings.js +0 -0
  153. package/src/flow/kit/value_picker.js +1 -1
  154. package/src/flow/kit/widgets.js +0 -0
  155. package/src/flow/lanes/editor.js +0 -0
  156. package/src/flow/lanes/index.js +0 -0
  157. package/src/flow/lanes/layout.js +0 -0
  158. package/src/flow/lanes/pipeline.js +0 -0
  159. package/src/flow/lanes/preview.js +0 -0
  160. package/src/flow/lanes/strings.js +0 -0
  161. package/src/flow/outline/editor.js +0 -0
  162. package/src/flow/outline/index.js +0 -0
  163. package/src/flow/outline/mapping.js +0 -0
  164. package/src/flow/outline/menu.js +1 -1
  165. package/src/flow/outline/operations.js +0 -0
  166. package/src/flow/outline/recognise.js +0 -0
  167. package/src/flow/outline/strings.js +0 -0
  168. package/src/git/diff_viewer.js +212 -0
  169. package/src/git/diff_window.js +51 -0
  170. package/src/git/git_graph.js +401 -0
  171. package/src/git/git_ops.js +61 -0
  172. package/src/git/git_panel.js +755 -0
  173. package/src/git/index.js +9 -0
  174. package/src/git/line_diff.js +202 -0
  175. package/src/help/help_modal.js +0 -0
  176. package/src/help/help_registry.js +0 -0
  177. package/src/host/external_links.js +0 -0
  178. package/src/host/file_picker.js +0 -0
  179. package/src/host/host.js +0 -0
  180. package/src/host/photino_host.js +0 -0
  181. package/src/host/photino_host.md +0 -0
  182. package/src/host/pywebview_host.js +0 -0
  183. package/src/tiles/chart_tiles.js +0 -0
  184. package/src/tiles/config_schema.js +0 -0
  185. package/src/tiles/figure_tile.js +0 -0
  186. package/src/tiles/layout_persistence.js +0 -0
  187. package/src/tiles/list_tiles.js +0 -0
  188. package/src/tiles/scope_picker.js +0 -0
  189. package/src/tiles/tile_base.js +5 -4
  190. package/src/tiles/tile_config_form.js +0 -0
  191. package/src/tiles/tile_registry.js +0 -0
  192. package/src/tiling/bottom_panel_tabs.js +0 -0
  193. package/src/tiling/command_palette.js +0 -0
  194. package/src/tiling/content_registry.js +0 -0
  195. package/src/tiling/desktops.js +10 -8
  196. package/src/tiling/entity_sources.js +0 -0
  197. package/src/tiling/keymap.js +6 -5
  198. package/src/tiling/kind_taxonomy.js +15 -2
  199. package/src/tiling/landing_table.js +0 -0
  200. package/src/tiling/loading_overlay.js +0 -0
  201. package/src/tiling/nav_panel.js +0 -0
  202. package/src/tiling/page_factory.js +0 -0
  203. package/src/tiling/panel_availability.js +0 -0
  204. package/src/tiling/panel_keys.js +0 -0
  205. package/src/tiling/shell.js +124 -17
  206. package/src/tiling/tab_strip.js +0 -0
  207. package/src/tiling/tile_renderer.js +2 -3
  208. package/src/tiling/tile_tab_menu.js +0 -0
  209. package/src/tiling/zoom.js +0 -0
  210. package/src/ui/base/component_base.js +0 -0
  211. package/src/ui/base/controller_base.js +0 -0
  212. package/src/ui/base/page_base.js +0 -0
  213. package/src/ui/components/about_dialog.js +0 -0
  214. package/src/ui/components/action_dropdown.js +4 -78
  215. package/src/ui/components/alert_log.js +0 -0
  216. package/src/ui/components/alerts_pane.js +0 -0
  217. package/src/ui/components/anchored_layer.js +255 -0
  218. package/src/ui/components/attribute_list_editor.js +0 -0
  219. package/src/ui/components/autocomplete_field.js +0 -0
  220. package/src/ui/components/cell_editor_host.js +0 -0
  221. package/src/ui/components/cell_editors.js +0 -0
  222. package/src/ui/components/cell_grid.js +0 -0
  223. package/src/ui/components/cell_paste.js +0 -0
  224. package/src/ui/components/cell_selection.js +0 -0
  225. package/src/ui/components/chat_shell.js +920 -0
  226. package/src/ui/components/chat_state_machine.js +223 -0
  227. package/src/ui/components/choice_controls.js +45 -2
  228. package/src/ui/components/color_field.js +3 -2
  229. package/src/ui/components/color_list_field.js +3 -2
  230. package/src/ui/components/column_fit.js +0 -0
  231. package/src/ui/components/column_groups.js +0 -0
  232. package/src/ui/components/column_order.js +0 -0
  233. package/src/ui/components/combobox.js +422 -0
  234. package/src/ui/components/conversation_view.js +17 -2
  235. package/src/ui/components/crosstab.js +0 -0
  236. package/src/ui/components/data_table.js +2 -2
  237. package/src/ui/components/detail_header.js +0 -0
  238. package/src/ui/components/document_outline.js +0 -0
  239. package/src/ui/components/drag_reorder.js +0 -0
  240. package/src/ui/components/fact_table.js +0 -0
  241. package/src/ui/components/fill_handle.js +0 -0
  242. package/src/ui/components/filter_builder.js +766 -0
  243. package/src/ui/components/filter_model.js +614 -0
  244. package/src/ui/components/gallery_picker.js +0 -0
  245. package/src/ui/components/header_actions.js +0 -0
  246. package/src/ui/components/inline_renamer.js +0 -0
  247. package/src/ui/components/job_progress.js +0 -0
  248. package/src/ui/components/managed_window.js +24 -47
  249. package/src/ui/components/menu_bar.js +101 -24
  250. package/src/ui/components/modal.js +79 -109
  251. package/src/ui/components/option_list.js +160 -0
  252. package/src/ui/components/popover.js +94 -0
  253. package/src/ui/components/progress.js +0 -0
  254. package/src/ui/components/recent_items.js +169 -0
  255. package/src/ui/components/record_list.js +0 -0
  256. package/src/ui/components/row_activation.js +0 -0
  257. package/src/ui/components/section_stack.js +0 -0
  258. package/src/ui/components/select.js +322 -0
  259. package/src/ui/components/series.js +0 -0
  260. package/src/ui/components/settings_view.js +0 -0
  261. package/src/ui/components/slide_out_panel.js +0 -0
  262. package/src/ui/components/slider_field.js +0 -0
  263. package/src/ui/components/sortable_list.js +0 -0
  264. package/src/ui/components/staged_edits.js +0 -0
  265. package/src/ui/components/staged_history.js +0 -0
  266. package/src/ui/components/table_filter_chips.js +0 -0
  267. package/src/ui/components/table_state_store.js +0 -0
  268. package/src/ui/components/table_structure.js +0 -0
  269. package/src/ui/components/table_values.js +0 -0
  270. package/src/ui/components/tabs.js +0 -0
  271. package/src/ui/components/tag_input.js +77 -8
  272. package/src/ui/components/toast.js +0 -0
  273. package/src/ui/components/toggle_field.js +0 -0
  274. package/src/ui/components/tsv.js +0 -0
  275. package/src/ui/components/window_taskbar.js +0 -0
  276. package/src/ui/components/workspace_picker.js +1155 -0
  277. package/src/ui/controllers/window_chrome_controller.js +4 -1
  278. package/src/ui/utils/auto_scrollbars.js +0 -0
  279. package/src/ui/utils/fire_event.js +17 -0
  280. package/src/ui/utils/focusable.js +25 -0
  281. package/src/ui/utils/markdown.js +0 -0
  282. package/src/ui/utils/modal_host.js +27 -0
  283. package/src/ui/utils/native_context_menu.js +0 -0
  284. package/src/ui/utils/overlay_scrollbar.js +0 -0
  285. package/src/ui/utils/raf_resize_observer.js +0 -0
  286. package/src/ui/utils/scroll_lock.js +0 -0
  287. package/src/ui/utils/strip_scroll.js +0 -0
  288. package/src/ui/utils/tooltip_service.js +0 -0
  289. package/tiles.js +0 -0
  290. package/widgets.js +12 -2
  291. package/wm.js +0 -0
  292. package/css/base.css +0 -10527
  293. package/css/overrides.css +0 -2596
  294. package/dist/chunk-7JI7HHSY.js +0 -107
  295. package/dist/chunk-7JI7HHSY.js.map +0 -7
  296. package/dist/chunk-MIW7D6WC.js +0 -526
  297. package/dist/chunk-MIW7D6WC.js.map +0 -7
  298. package/dist/chunk-PGZ4EHSE.js.map +0 -7
  299. package/dist/chunk-XJNADRGR.js.map +0 -7
  300. /package/dist/{chunk-REJ5HLIM.js.map → chunk-HYJYYEPK.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/help/help_registry.js", "../src/ui/utils/markdown.js", "../src/ui/components/document_outline.js", "../src/help/help_modal.js", "../src/ui/components/menu_bar.js"],
4
- "sourcesContent": ["/**\n * Where the help modal gets its help.\n *\n * HelpModal used to `import { getHelpService, HELP_TOPICS } from './help_service.js'` \u2014\n * and help_service.js is 249 domain words of EcoAgent prose about sectors,\n * currencies, agents and markets. That import was the last framework -> domain\n * edge in the core: a generic modal reaching into one application's manual.\n *\n * The modal now asks this registry, and the application fills it. If nobody\n * fills it, the modal opens and says there is no help \u2014 which is the correct\n * behaviour for a library that ships no documentation about your app.\n *\n * @typedef {Object} HelpProvider\n * @property {() => string[]} getCategories\n * @property {(category: string) => Array<{id: string, title: string}>} getTopicsByCategory\n * @property {(id: string) => Promise<HelpTopic|null>} loadTopic\n * @property {(query: string) => Array<Object>} searchTopics\n * @property {Object} [markdownOptions] What the modal passes to\n * `renderMarkdown` for a markdown topic: `highlight`, `math`, `allowHtml`,\n * `inlineRules`, `blockRules`.\n *\n * @typedef {Object} HelpTopic\n * @property {string} title Text.\n * @property {string} [markdown] The article as markdown, rendered safe by\n * `renderMarkdown`: raw HTML is escaped and only http(s), mailto and #anchor\n * links go anywhere. Used when present.\n * @property {string} [html] The article as pre-rendered, TRUSTED HTML,\n * inserted verbatim. Never put unsanitised user content here.\n *\n * @typedef {Object.<string, {label: string, icon: string}>} HelpCategories\n * Keyed by category id; ITERATION ORDER IS DISPLAY ORDER.\n *\n * @typedef {{title: string, welcome: string}} HelpCopy\n * The landing heading. The modal used to hardcode \"EcoAgent Help\" and\n * \"Welcome to EcoAgent!\".\n */\n\n/** A provider with nothing in it. Not an error \u2014 just an app with no help. */\nconst EMPTY_PROVIDER = Object.freeze({\n getCategories: () => [],\n getTopicsByCategory: () => [],\n loadTopic: async () => null,\n searchTopics: () => [],\n});\n\nconst DEFAULT_COPY = Object.freeze({\n title: 'Help',\n welcome: 'Select a topic from the sidebar or browse the categories below.',\n});\n\nlet _provider = EMPTY_PROVIDER;\nlet _categories = Object.freeze({});\nlet _copy = DEFAULT_COPY;\n\n/**\n * @param {HelpProvider} provider\n * @param {HelpCategories} [categories] Display labels + icons, in display order.\n * @param {Partial<HelpCopy>} [copy] Landing heading and welcome line.\n */\nexport function setHelpProvider(provider, categories = {}, copy = {}) {\n _provider = provider ?? EMPTY_PROVIDER;\n _categories = Object.freeze({ ...categories });\n _copy = Object.freeze({ ...DEFAULT_COPY, ...copy });\n}\n\nexport function helpProvider() {\n return _provider;\n}\n\nexport function helpCategories() {\n return _categories;\n}\n\nexport function helpCopy() {\n return _copy;\n}\n", "/**\n * renderMarkdown \u2014 markdown to an HTML string, safe by default.\n *\n * A CommonMark-ish subset: ATX headings, paragraphs, emphasis, strong,\n * strikethrough, code spans, fenced code, block quotes, ordered and unordered\n * lists (nested), GFM pipe tables, thematic breaks, links, images, autolinks,\n * hard line breaks, backslash escapes and `$\u2026$` / `$$\u2026$$` math. Not in it:\n * setext headings, indented code blocks, reference links, raw HTML blocks.\n *\n * SAFE BY DEFAULT. Every character of the source is text unless markdown makes\n * it markup:\n *\n * - raw HTML is escaped. `options.allowHtml` names tags that may pass\n * through \u2014 the tag only, never its attributes, and never a tag that runs\n * or embeds anything (`script`, `iframe`, `svg`, \u2026 throw). It is empty by\n * default. An allowed tag left open is closed at the end of its paragraph,\n * and a closer with no opener is shown as text.\n * - a link goes out only to `http:`, `https:`, `mailto:` or a `#anchor`,\n * always with `rel=\"noopener noreferrer\"`. Any other target \u2014 a\n * `javascript:` URL, a `data:` URL, a relative path \u2014 renders the link's\n * text and no anchor. An image loads only from `http(s):` or a relative\n * path; otherwise its alt text is shown.\n *\n * What the CALLER returns is trusted: the highlighter's HTML, the math hook's\n * HTML and the extension rules' HTML go into the output as they are.\n *\n * WELL-FORMED WHILE STREAMING. Every element this renderer opens it closes,\n * so any prefix of a document \u2014 a chat reply arriving token by token \u2014 renders\n * to balanced HTML: an open code fence is closed at the end of the input, an\n * emphasis or a link whose closer has not arrived yet is text, and a table\n * whose delimiter row has not arrived yet is a paragraph.\n *\n * renderMarkdown(source, {\n * inline: false, // true: inline markup only, no blocks, no <p>\n * allowHtml: [], // e.g. ['kbd', 'br']\n * highlight: null, // (code, lang) => html | null (null: escaped)\n * math: undefined, // undefined: window.katex when present;\n * // false: `$` is text; or (tex, {display}) => html | null\n * inlineRules: [], // [{ pattern: /\\[\\[ref:(\\w+)\\]\\]/, render: (match, ctx) => html | null }]\n * blockRules: [], // [{ start: /^:::note/, end: /^:::$/, render: ({lines, match, closed}, ctx) => html | null }]\n * })\n *\n * A rule whose render answers null or undefined declines, and the text is\n * read as markdown. `ctx` carries `escape(text)` and `inline(text)` (render\n * markdown inline with the same options). An inline rule is tried at every\n * position outside a code span, before the built-in markup; a block rule's\n * `start` is tested against each line that begins a block, and the block runs\n * to the first later line matching `end` (inclusive) \u2014 or, with no `end`, is\n * that one line. A block whose `end` has not arrived is passed with\n * `closed: false` and runs to the end of the input.\n *\n * @module markdown\n */\n\n/** Tags `allowHtml` refuses: each runs script, embeds content or takes input. */\nconst NEVER_ALLOWED = new Set([\n 'script', 'style', 'iframe', 'frame', 'frameset', 'object', 'embed', 'applet',\n 'template', 'noscript', 'textarea', 'title', 'xmp', 'plaintext', 'noembed',\n 'svg', 'math', 'link', 'meta', 'base', 'form', 'input', 'button', 'select',\n 'option', 'video', 'audio', 'source', 'track', 'img', 'image', 'html',\n 'head', 'body', 'portal', 'dialog',\n]);\nconst VOID_TAGS = new Set(['br', 'hr', 'wbr']);\n\nconst LINK_URL = /^(?:https?:\\/\\/|mailto:|#)/i;\nconst IMAGE_URL = /^(?:https?:\\/\\/|\\/\\/|[^:/?#]*(?:[/?#]|$))/i;\nconst ENTITY = /^&(?:[a-zA-Z][a-zA-Z0-9]{1,31}|#\\d{1,7}|#[xX][0-9a-fA-F]{1,6});/;\nconst ASCII_PUNCT = /[!-/:-@[-`{-~]/;\n\nconst RE = {\n blank: /^[ \\t]*$/,\n heading: /^ {0,3}(#{1,6})(?:[ \\t]+(.*?))?(?:[ \\t]+#+)?[ \\t]*$/,\n hr: /^ {0,3}([-*_])(?:[ \\t]*\\1){2,}[ \\t]*$/,\n fence: /^( {0,3})(`{3,}|~{3,})[ \\t]*([^\\s`]*)[^`]*$/,\n quote: /^ {0,3}> ?/,\n item: /^( {0,3})([-*+]|\\d{1,9}[.)])(?=[ \\t]|$)([ \\t]*)(.*)$/,\n mathOpen: /^ {0,3}\\$\\$/,\n tableDelim: /^[ \\t]*\\|?[ \\t]*:?-+:?[ \\t]*(?:\\|[ \\t]*:?-+:?[ \\t]*)*\\|?[ \\t]*$/,\n};\n\n/**\n * Text for HTML: text content and attribute values alike.\n * @param {*} value\n * @returns {string}\n */\nfunction escapeHtml(value) {\n return String(value ?? '')\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\n/** The default math hook: window.katex, looked up per call, when it is there. */\nfunction katexMath(tex, { display }) {\n const katex = globalThis.window?.katex ?? globalThis.katex;\n if (typeof katex?.renderToString !== 'function') return null;\n try {\n return katex.renderToString(tex, { displayMode: display, throwOnError: false });\n } catch {\n return null;\n }\n}\n\nfunction compileOptions(options) {\n const allow = new Set();\n for (const raw of options.allowHtml ?? []) {\n const tag = String(raw).toLowerCase();\n if (!/^[a-z][a-z0-9-]*$/.test(tag)) {\n throw new TypeError(`renderMarkdown: allowHtml entry \"${raw}\" is not a tag name`);\n }\n if (NEVER_ALLOWED.has(tag)) {\n throw new TypeError(`renderMarkdown: <${tag}> cannot be allowed`);\n }\n allow.add(tag);\n }\n const fn = (value, name) => {\n if (value == null) return null;\n if (typeof value !== 'function') throw new TypeError(`renderMarkdown: ${name} must be a function`);\n return value;\n };\n const inlineRules = (options.inlineRules ?? []).map((rule, i) => {\n if (!(rule?.pattern instanceof RegExp) || typeof rule.render !== 'function') {\n throw new TypeError(`renderMarkdown: inlineRules[${i}] needs a RegExp pattern and a render function`);\n }\n // Sticky: the rule matches AT the position being read, never further on.\n const flags = rule.pattern.flags.replace(/[gy]/g, '') + 'y';\n return { pattern: new RegExp(rule.pattern.source, flags), render: rule.render };\n });\n const blockRules = (options.blockRules ?? []).map((rule, i) => {\n if (!(rule?.start instanceof RegExp) || typeof rule.render !== 'function'\n || (rule.end != null && !(rule.end instanceof RegExp))) {\n throw new TypeError(`renderMarkdown: blockRules[${i}] needs a RegExp start, an optional RegExp end and a render function`);\n }\n const plain = (re) => new RegExp(re.source, re.flags.replace(/[gy]/g, ''));\n return { start: plain(rule.start), end: rule.end ? plain(rule.end) : null, render: rule.render };\n });\n return {\n allow,\n highlight: fn(options.highlight, 'highlight'),\n math: options.math === undefined ? katexMath\n : options.math === false || options.math === null ? null\n : fn(options.math, 'math'),\n inlineRules,\n blockRules,\n };\n}\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// Inline\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n/** Index of the run of exactly `len` backticks closing a code span, or -1. */\nfunction findBacktickCloser(text, from, len) {\n let i = from;\n while (i < text.length) {\n const j = text.indexOf('`', i);\n if (j === -1) return -1;\n let k = j;\n while (text[k] === '`') k++;\n if (k - j === len) return j;\n i = k;\n }\n return -1;\n}\n\n/** Index after the `]` matching the `[` at `open`, or -1. */\nfunction findBracketClose(text, open) {\n let depth = 0;\n for (let i = open; i < text.length; i++) {\n const c = text[i];\n if (c === '\\\\') { i++; continue; }\n if (c === '`') {\n let k = i;\n while (text[k] === '`') k++;\n const close = findBacktickCloser(text, k, k - i);\n if (close !== -1) { i = close + (k - i) - 1; continue; }\n i = k - 1;\n continue;\n }\n if (c === '[') depth++;\n else if (c === ']' && --depth === 0) return i;\n }\n return -1;\n}\n\n/** `(url \"title\")` starting at `open`: {url, title, end} or null. */\nfunction parseDestination(text, open) {\n if (text[open] !== '(') return null;\n let i = open + 1;\n while (text[i] === ' ' || text[i] === '\\t' || text[i] === '\\n') i++;\n let url = '';\n if (text[i] === '<') {\n const close = text.indexOf('>', i);\n if (close === -1 || /[\\n<]/.test(text.slice(i + 1, close))) return null;\n url = text.slice(i + 1, close);\n i = close + 1;\n } else {\n let depth = 0;\n const start = i;\n for (; i < text.length; i++) {\n const c = text[i];\n if (c === '\\\\' && i + 1 < text.length) { i++; continue; }\n if (/\\s/.test(c)) break;\n if (c === '(') depth++;\n else if (c === ')') { if (depth === 0) break; depth--; }\n }\n url = text.slice(start, i);\n }\n while (text[i] === ' ' || text[i] === '\\t' || text[i] === '\\n') i++;\n let title = null;\n const q = text[i];\n if (q === '\"' || q === \"'\" || q === '(') {\n const closeQ = q === '(' ? ')' : q;\n const close = text.indexOf(closeQ, i + 1);\n if (close === -1) return null;\n title = text.slice(i + 1, close);\n i = close + 1;\n while (text[i] === ' ' || text[i] === '\\t' || text[i] === '\\n') i++;\n }\n if (text[i] !== ')') return null;\n return { url: url.replace(/\\\\([!-/:-@[-`{-~])/g, '$1'), title, end: i + 1 };\n}\n\nconst isSpace = (c) => c === undefined || /\\s/.test(c);\nconst isWord = (c) => c !== undefined && /[\\p{L}\\p{N}]/u.test(c);\n\n/**\n * The closer of an emphasis run of `len` \u00D7 `ch` opened at `from`: the index\n * of a run of exactly `len` that is not preceded by whitespace (and, for `_`,\n * not followed by a word character), or -1.\n */\nfunction findEmphasisCloser(text, from, ch, len) {\n let i = from;\n while (i < text.length) {\n const c = text[i];\n if (c === '\\\\') { i += 2; continue; }\n if (c === '`') {\n let k = i;\n while (text[k] === '`') k++;\n const close = findBacktickCloser(text, k, k - i);\n i = close === -1 ? k : close + (k - i);\n continue;\n }\n if (c !== ch) { i++; continue; }\n let k = i;\n while (text[k] === ch) k++;\n if (k - i === len && i > from && !isSpace(text[i - 1])\n && !(ch === '_' && isWord(text[k]))) return i;\n i = k;\n }\n return -1;\n}\n\n/** `$\u2026$` or `$$\u2026$$` at `i`: {tex, display, end} or null. */\nfunction parseInlineMath(text, i) {\n if (text[i + 1] === '$') {\n const close = text.indexOf('$$', i + 2);\n if (close === -1 || close === i + 2) return null;\n return { tex: text.slice(i + 2, close), display: true, end: close + 2 };\n }\n if (isSpace(text[i + 1])) return null;\n for (let j = i + 1; j < text.length; j++) {\n if (text[j] === '\\\\') { j++; continue; }\n if (text[j] === '\\n' && text[j + 1] === '\\n') return null;\n if (text[j] === '$' && j > i + 1 && !isSpace(text[j - 1]) && !/\\d/.test(text[j + 1] ?? '')) {\n return { tex: text.slice(i + 1, j), display: false, end: j + 1 };\n }\n }\n return null;\n}\n\nfunction renderInline(text, ctx, { inLink = false } = {}) {\n const { opts } = ctx;\n let out = '';\n let plain = '';\n const flush = () => { out += escapeHtml(plain); plain = ''; };\n const emit = (html) => { flush(); out += html; };\n const open = []; // allowed raw-HTML tags open in this span\n\n let i = 0;\n while (i < text.length) {\n const c = text[i];\n\n // Backslash: an escaped punctuation character, or a hard break.\n if (c === '\\\\') {\n const n = text[i + 1];\n if (n === '\\n') { emit('<br>\\n'); i += 2; continue; }\n if (n !== undefined && ASCII_PUNCT.test(n)) { plain += n; i += 2; continue; }\n plain += c; i++; continue;\n }\n\n // Code span: wins over everything, including the caller's rules.\n if (c === '`') {\n let k = i;\n while (text[k] === '`') k++;\n const close = findBacktickCloser(text, k, k - i);\n if (close === -1) { plain += text.slice(i, k); i = k; continue; }\n let code = text.slice(k, close).replace(/\\n/g, ' ');\n if (code.length > 2 && code[0] === ' ' && code.at(-1) === ' ' && code.trim()) code = code.slice(1, -1);\n emit(`<code>${escapeHtml(code)}</code>`);\n i = close + (k - i);\n continue;\n }\n\n // The caller's rules.\n let ruled = false;\n for (const rule of opts.inlineRules) {\n rule.pattern.lastIndex = i;\n const m = rule.pattern.exec(text);\n if (!m || !m[0].length) continue;\n const html = rule.render(m, ctx.api);\n if (html == null) continue;\n emit(String(html));\n i += m[0].length;\n ruled = true;\n break;\n }\n if (ruled) continue;\n\n // Hard break: two or more spaces before a newline.\n if (c === '\\n') {\n if (/ {2,}$/.test(plain)) { plain = plain.replace(/ +$/, ''); emit('<br>\\n'); }\n else { plain = plain.replace(/ +$/, ''); plain += '\\n'; }\n i++;\n continue;\n }\n\n if (c === '&') {\n const m = ENTITY.exec(text.slice(i, i + 40));\n if (m) { emit(m[0]); i += m[0].length; continue; }\n }\n\n if (c === '$' && opts.math) {\n const m = parseInlineMath(text, i);\n if (m) {\n const html = opts.math(m.tex, { display: m.display });\n if (html == null) plain += text.slice(i, m.end);\n else emit(String(html));\n i = m.end;\n continue;\n }\n }\n\n // Images and links.\n if ((c === '!' && text[i + 1] === '[') || (c === '[' && !inLink)) {\n const bracket = c === '!' ? i + 1 : i;\n const close = findBracketClose(text, bracket);\n const dest = close === -1 ? null : parseDestination(text, close + 1);\n if (dest) {\n const label = text.slice(bracket + 1, close);\n const title = dest.title == null ? '' : ` title=\"${escapeHtml(dest.title)}\"`;\n if (c === '!') {\n if (IMAGE_URL.test(dest.url) && !/[\\s\\x00-\\x1f]/.test(dest.url)) {\n emit(`<img src=\"${escapeHtml(dest.url)}\" alt=\"${escapeHtml(label)}\"${title}>`);\n } else {\n plain += label;\n }\n } else if (LINK_URL.test(dest.url) && !/[\\s\\x00-\\x1f]/.test(dest.url)) {\n emit(`<a href=\"${escapeHtml(dest.url)}\"${title} rel=\"noopener noreferrer\">`\n + `${renderInline(label, ctx, { inLink: true })}</a>`);\n } else {\n // Inert: the text the reader was shown, and nowhere to go.\n emit(renderInline(label, ctx, { inLink: true }));\n }\n i = dest.end;\n continue;\n }\n }\n\n if (c === '<') {\n const auto = /^<((?:https?:\\/\\/|mailto:)[^\\s<>]+)>/i.exec(text.slice(i, i + 2048));\n if (auto && !inLink) {\n emit(`<a href=\"${escapeHtml(auto[1])}\" rel=\"noopener noreferrer\">${escapeHtml(auto[1])}</a>`);\n i += auto[0].length;\n continue;\n }\n const tag = opts.allow.size ? /^<(\\/?)([A-Za-z][A-Za-z0-9-]*)(?:\\s[^<>]*)?\\/?>/.exec(text.slice(i, i + 1024)) : null;\n const name = tag?.[2].toLowerCase();\n if (tag && opts.allow.has(name)) {\n if (VOID_TAGS.has(name)) {\n if (!tag[1]) emit(`<${name}>`);\n i += tag[0].length;\n continue;\n }\n if (!tag[1]) {\n emit(`<${name}>`);\n open.push(name);\n i += tag[0].length;\n continue;\n }\n const at = open.lastIndexOf(name);\n if (at !== -1) {\n while (open.length > at) emit(`</${open.pop()}>`);\n i += tag[0].length;\n continue;\n }\n }\n }\n\n // Emphasis, strong, strikethrough.\n if (c === '*' || c === '_' || c === '~') {\n let k = i;\n while (text[k] === c) k++;\n const run = k - i;\n const opens = !isSpace(text[k]) && !(c === '_' && isWord(text[i - 1]));\n const len = c === '~' ? (run === 2 ? 2 : 0) : run <= 3 ? run : 0;\n if (opens && len) {\n const close = findEmphasisCloser(text, k, c, len);\n if (close !== -1) {\n const inner = renderInline(text.slice(k, close), ctx, { inLink });\n const wrapped = c === '~' ? `<del>${inner}</del>`\n : len === 1 ? `<em>${inner}</em>`\n : len === 2 ? `<strong>${inner}</strong>`\n : `<strong><em>${inner}</em></strong>`;\n emit(wrapped);\n i = close + len;\n continue;\n }\n }\n plain += text.slice(i, k);\n i = k;\n continue;\n }\n\n plain += c;\n i++;\n }\n flush();\n while (open.length) out += `</${open.pop()}>`;\n return out;\n}\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// Blocks\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n/** A pipe-table row's cells: unescaped `|` splits, outside code spans. */\nfunction splitRow(line) {\n let s = line.trim();\n if (s.startsWith('|')) s = s.slice(1);\n if (s.endsWith('|') && !s.endsWith('\\\\|')) s = s.slice(0, -1);\n const cells = [];\n let cell = '';\n let inCode = 0;\n for (let i = 0; i < s.length; i++) {\n const c = s[i];\n if (c === '\\\\' && s[i + 1] === '|') { cell += '|'; i++; continue; }\n if (c === '`') {\n let k = i;\n while (s[k] === '`') k++;\n const len = k - i;\n if (inCode === len) inCode = 0;\n else if (!inCode && findBacktickCloser(s, k, len) !== -1) inCode = len;\n cell += s.slice(i, k);\n i = k - 1;\n continue;\n }\n if (c === '|' && !inCode) { cells.push(cell.trim()); cell = ''; continue; }\n cell += c;\n }\n cells.push(cell.trim());\n return cells;\n}\n\nfunction isTableStart(lines, i) {\n if (!lines[i].includes('|') || i + 1 >= lines.length\n || !lines[i + 1].includes('|') || !RE.tableDelim.test(lines[i + 1])) return false;\n return splitRow(lines[i]).length === splitRow(lines[i + 1]).length;\n}\n\nfunction blockRuleAt(line, ctx) {\n for (const rule of ctx.opts.blockRules) {\n const match = rule.start.exec(line);\n if (match) return { rule, match };\n }\n return null;\n}\n\n/**\n * A `$$` line opens a display-math block when the rest of it is empty or the\n * whole formula (`$$x$$`); `$$x$$ and more` is a paragraph with inline math.\n */\nfunction isMathBlockStart(line, ctx) {\n if (!ctx.opts.math || !RE.mathOpen.test(line)) return false;\n const rest = line.replace(RE.mathOpen, '');\n return !rest.includes('$$') || /^[^$]*\\$\\$[ \\t]*$/.test(rest) && !/^[ \\t]*\\$\\$/.test(rest);\n}\n\n/** Does `lines[i]` begin a block that interrupts a paragraph? */\nfunction startsBlock(lines, i, ctx) {\n const line = lines[i];\n if (RE.heading.test(line) || RE.hr.test(line) || RE.fence.test(line) || RE.quote.test(line)) return true;\n if (isMathBlockStart(line, ctx)) return true;\n const item = RE.item.exec(line);\n if (item && item[4].trim() && (!/\\d/.test(item[2]) || /^1[.)]$/.test(item[2]))) return true;\n if (blockRuleAt(line, ctx)) return true;\n return isTableStart(lines, i);\n}\n\nfunction renderCode(lines, i, ctx) {\n const [, indent, fence, lang] = RE.fence.exec(lines[i]);\n const body = [];\n const close = new RegExp(`^ {0,3}${fence[0] === '`' ? '`' : '~'}{${fence.length},}[ \\\\t]*$`);\n let j = i + 1;\n for (; j < lines.length; j++) {\n if (close.test(lines[j])) { j++; break; }\n let line = lines[j];\n for (let n = 0; n < indent.length && line[0] === ' '; n++) line = line.slice(1);\n body.push(line);\n }\n const code = body.length ? body.join('\\n') + '\\n' : '';\n const highlighted = ctx.opts.highlight ? ctx.opts.highlight(code, lang) : null;\n const cls = lang ? ` class=\"language-${escapeHtml(lang)}\"` : '';\n return { html: `<pre><code${cls}>${highlighted == null ? escapeHtml(code) : String(highlighted)}</code></pre>\\n`, next: j };\n}\n\nfunction renderMathBlock(lines, i, ctx) {\n const first = lines[i].replace(/^ {0,3}\\$\\$/, '');\n const body = [];\n let j = i;\n let closed = false;\n if (/\\$\\$[ \\t]*$/.test(first)) {\n body.push(first.replace(/\\$\\$[ \\t]*$/, ''));\n closed = true;\n j = i + 1;\n } else {\n if (first.trim()) body.push(first);\n for (j = i + 1; j < lines.length; j++) {\n if (/\\$\\$[ \\t]*$/.test(lines[j])) {\n const last = lines[j].replace(/\\$\\$[ \\t]*$/, '');\n if (last.trim()) body.push(last);\n closed = true;\n j++;\n break;\n }\n body.push(lines[j]);\n }\n }\n const tex = body.join('\\n').trim();\n const html = closed && tex ? ctx.opts.math(tex, { display: true }) : null;\n if (html != null) return { html: `<div class=\"twm-md-math\">${String(html)}</div>\\n`, next: j };\n return { html: `<p>${escapeHtml(lines.slice(i, j).join('\\n'))}</p>\\n`, next: j };\n}\n\nfunction renderTable(lines, i, ctx) {\n const head = splitRow(lines[i]);\n const align = splitRow(lines[i + 1]).map((d) => {\n const l = d.startsWith(':');\n const r = d.endsWith(':');\n return l && r ? 'center' : r ? 'right' : l ? 'left' : null;\n });\n const cell = (tag, text, n) => {\n const style = align[n] ? ` style=\"text-align: ${align[n]}\"` : '';\n return `<${tag}${style}>${renderInline(text ?? '', ctx)}</${tag}>`;\n };\n let html = '<table>\\n<thead>\\n<tr>' + head.map((t, n) => cell('th', t, n)).join('') + '</tr>\\n</thead>\\n';\n let j = i + 2;\n const rows = [];\n for (; j < lines.length; j++) {\n if (RE.blank.test(lines[j]) || startsBlock(lines, j, ctx)) break;\n const cells = splitRow(lines[j]);\n rows.push('<tr>' + head.map((_, n) => cell('td', cells[n], n)).join('') + '</tr>\\n');\n }\n if (rows.length) html += '<tbody>\\n' + rows.join('') + '</tbody>\\n';\n return { html: html + '</table>\\n', next: j };\n}\n\nfunction renderList(lines, i, ctx) {\n const first = RE.item.exec(lines[i]);\n const ordered = /\\d/.test(first[2]);\n const delim = ordered ? first[2].at(-1) : first[2];\n const sameList = (m) => m && (ordered ? /\\d/.test(m[2]) && m[2].at(-1) === delim : m[2] === delim);\n const items = [];\n let loose = false;\n let j = i;\n while (j < lines.length) {\n const m = RE.item.exec(lines[j]);\n if (!sameList(m) || (items.length && m[1].length >= items.at(-1).indent)) break;\n const gap = m[3].length >= 5 || !m[4] ? 1 : m[3].length;\n const indent = m[1].length + m[2].length + gap;\n const item = { indent, lines: [m[3].length >= 5 ? ' '.repeat(m[3].length - 1) + m[4] : m[4]] };\n items.push(item);\n j++;\n let pendingBlank = 0;\n while (j < lines.length) {\n const line = lines[j];\n if (RE.blank.test(line)) { pendingBlank++; j++; continue; }\n const lead = line.match(/^ */)[0].length;\n if (lead >= indent) {\n for (; pendingBlank; pendingBlank--) item.lines.push('');\n item.lines.push(line.slice(indent));\n j++;\n continue;\n }\n const next = RE.item.exec(line);\n if (pendingBlank === 0 && !next && !startsBlock(lines, j, ctx)\n && !RE.blank.test(item.lines.at(-1) ?? '')) {\n item.lines.push(line.trim()); // lazy paragraph continuation\n j++;\n continue;\n }\n break;\n }\n if (pendingBlank) {\n const next = RE.item.exec(lines[j] ?? '');\n if (j < lines.length && sameList(next) && next[1].length < indent) loose = true;\n else { j -= pendingBlank; break; }\n }\n if (item.lines.slice(0, -1).some((l) => RE.blank.test(l)) && item.lines.length > 1) {\n // A blank line between two of the item's own blocks.\n const inner = item.lines.join('\\n');\n if (!/^(`{3,}|~{3,})/m.test(inner)) loose = true;\n }\n }\n const tag = ordered ? 'ol' : 'ul';\n const start = ordered ? parseInt(first[2], 10) : 1;\n let html = start !== 1 ? `<${tag} start=\"${start}\">\\n` : `<${tag}>\\n`;\n for (const item of items) {\n const body = renderBlocks(item.lines, ctx, { tight: !loose });\n html += `<li>${body.replace(/\\n$/, '')}</li>\\n`;\n }\n return { html: html + `</${tag}>\\n`, next: j };\n}\n\nfunction renderBlocks(lines, ctx, { tight = false } = {}) {\n let out = '';\n let i = 0;\n while (i < lines.length) {\n const line = lines[i];\n if (RE.blank.test(line)) { i++; continue; }\n\n const ruled = blockRuleAt(line, ctx);\n if (ruled) {\n let j = i + 1;\n let closed = true;\n if (ruled.rule.end) {\n closed = false;\n for (; j < lines.length; j++) {\n if (ruled.rule.end.test(lines[j])) { closed = true; j++; break; }\n }\n }\n const html = ruled.rule.render({ lines: lines.slice(i, j), match: ruled.match, closed }, ctx.api);\n if (html != null) {\n out += String(html) + '\\n';\n i = j;\n continue;\n }\n }\n\n let block = null;\n if (RE.fence.test(line)) block = renderCode(lines, i, ctx);\n else if (isMathBlockStart(line, ctx)) block = renderMathBlock(lines, i, ctx);\n else if (RE.heading.test(line)) {\n const [, hashes, text = ''] = RE.heading.exec(line);\n const n = hashes.length;\n block = { html: `<h${n}>${renderInline(text.trim(), ctx)}</h${n}>\\n`, next: i + 1 };\n } else if (RE.hr.test(line)) block = { html: '<hr>\\n', next: i + 1 };\n else if (RE.quote.test(line)) {\n const inner = [];\n let j = i;\n for (; j < lines.length && RE.quote.test(lines[j]); j++) inner.push(lines[j].replace(RE.quote, ''));\n block = { html: `<blockquote>\\n${renderBlocks(inner, ctx)}</blockquote>\\n`, next: j };\n } else if (RE.item.test(line)) block = renderList(lines, i, ctx);\n else if (isTableStart(lines, i)) block = renderTable(lines, i, ctx);\n\n if (block) {\n out += block.html;\n i = block.next;\n continue;\n }\n\n const para = [line];\n let j = i + 1;\n for (; j < lines.length && !RE.blank.test(lines[j]) && !startsBlock(lines, j, ctx); j++) para.push(lines[j]);\n const inline = renderInline(para.map((l, n) => (n === 0 ? l.replace(/^[ \\t]+/, '') : l.trimStart()))\n .join('\\n').replace(/[ \\t]+$/, ''), ctx);\n out += tight ? `${inline}\\n` : `<p>${inline}</p>\\n`;\n i = j;\n }\n return out;\n}\n\n/**\n * Render markdown to an HTML string. See the module comment for the subset,\n * the safety rules and the options.\n *\n * @param {string} source\n * @param {Object} [options]\n * @param {boolean} [options.inline=false] - Inline markup only: no blocks, no `<p>`.\n * @param {string[]} [options.allowHtml=[]] - Raw HTML tags that pass through, without attributes.\n * @param {(code: string, lang: string) => (string|null)} [options.highlight] - Fenced code's HTML.\n * @param {false|null|((tex: string, o: {display: boolean}) => (string|null))} [options.math]\n * Omitted: `window.katex` when present. `false`: `$` is plain text.\n * @param {Array<{pattern: RegExp, render: (match: RegExpExecArray, ctx: Object) => (string|null)}>} [options.inlineRules]\n * @param {Array<{start: RegExp, end?: RegExp, render: (block: {lines: string[], match: RegExpExecArray, closed: boolean}, ctx: Object) => (string|null)}>} [options.blockRules]\n * @returns {string}\n */\nexport function renderMarkdown(source, options = {}) {\n const ctx = { opts: compileOptions(options ?? {}) };\n ctx.api = Object.freeze({\n escape: escapeHtml,\n inline: (text) => renderInline(String(text ?? ''), ctx),\n });\n const text = String(source ?? '').replace(/\\r\\n?/g, '\\n').replace(/\\u0000/g, '\uFFFD');\n if (options?.inline) return renderInline(text, ctx);\n return renderBlocks(text.split('\\n'), ctx);\n}\n", "/**\n * document_outline.js \u2014 A LONG DOCUMENT'S OUTLINE: its sections listed and\n * numbered, the one in view marked while the document scrolls, and a click\n * that goes to a section. (0.17.0)\n *\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 1 Introduction \u2502\n * \u2502 1.1 Scope \u2502 \u2190 the section in view\n * \u2502 1.2 Terms \u2502\n * \u2502 2 Method \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n *\n * const outline = createDocumentOutline(sidebarEl, {\n * entries: [{ id: 'intro', level: 1, label: 'Introduction' }, \u2026],\n * numbering: true,\n * scrollContainer: articleEl,\n * resolveTarget: (entry) => articleEl.querySelector(`[data-section=\"${entry.id}\"]`),\n * onSelect: (id) => { \u2026 },\n * });\n *\n * Where the entries come from (headings in markup, cells in a notebook, a\n * server's table of contents) is the embedder's business. The outline is told\n * `{id, level, label}` and, through `resolveTarget`, which element in the\n * scroll container each one stands for.\n *\n * NUMBERING (`numbering: true`) is hierarchical: levels 1, 2, 2, 1 are numbered\n * 1, 1.1, 1.2, 2. An entry sits one deeper than the nearest entry above it of\n * a lower level, so the shallowest level is depth 1 and a skipped level is one\n * step, not two (1, 3, 3, 2 is 1, 1.1, 1.2, 1.3, never 1.0.1); and nothing goes\n * deeper than `maxDepth` \u2014 a deeper entry is listed, indented and numbered at\n * `maxDepth`.\n *\n * THE SCROLL-SPY. With a `scrollContainer`, every resolved target is watched by\n * an IntersectionObserver rooted at that container, with `rootMargin` (default\n * `'0px 0px -70% 0px'`: the top 30% of the container is \"in view\"). Of the\n * targets in view, the one listed FIRST is the active section \u2014 the topmost\n * visible one. When none is in view the active section stays what it was, so\n * the long body of a section keeps its heading marked. An entry whose target\n * cannot be resolved is listed, but it is never watched and never marked\n * active, by the spy or by `setActive`.\n *\n * A CLICK keeps its entry active. A click on an entry marks it at once, scrolls\n * its target into view (unless `scrollOnSelect: false`, when `onSelect` does\n * the scrolling) and calls `onSelect(id, entry)`. A smooth scroll passes over\n * every section between here and there, so the spy is SUPPRESSED while it runs:\n * it resumes on the container's `scrollend`, or after `scrollEndTimeout` ms\n * (default 1000) when no `scrollend` comes \u2014 an engine without the event, or a\n * target that was already in place and so never scrolled.\n *\n * `refresh()` resolves the targets again (the document re-rendered);\n * `setEntries(entries)` replaces the list. `dispose()` disconnects the observer,\n * clears the timer and takes the outline off the page.\n */\n\n/**\n * @typedef {Object} OutlineEntry\n * @property {string} id - Unique among the entries.\n * @property {number} [level=1] - 1 for a top-level section, 2 under it, \u2026\n * @property {string} label - The entry's words, drawn as text (never markup).\n */\n\n/**\n * @typedef {Object} DocumentOutlineConfig\n * @property {OutlineEntry[]} [entries]\n * @property {boolean} [numbering=false] - Hierarchical numbers before the labels.\n * @property {number} [maxDepth=3] - The deepest indentation and numbering depth.\n * @property {Function} [onSelect] - `(id, entry) => void`, on a click on an entry.\n * @property {boolean} [scrollOnSelect=true] - A click scrolls the entry's target\n * into view (`scrollIntoView({block: 'start', behavior: scrollBehavior})`).\n * @property {ScrollBehavior} [scrollBehavior='smooth']\n * @property {HTMLElement|null} [scrollContainer] - The element that scrolls the\n * document; the observer's root. Without it there is no scroll-spy.\n * @property {Function} [resolveTarget] - `(entry, scrollContainer) => Element|null`.\n * Defaults to the element inside the container whose `id` is the entry's id.\n * @property {string} [rootMargin='0px 0px -70% 0px']\n * @property {number} [scrollEndTimeout=1000] - ms before a click's suppression\n * lifts when no `scrollend` arrives.\n * @property {string|Node|Function|null} [emptyState='No headings'] - Shown with no entries.\n * @property {string} [label='Outline'] - The navigation's accessible name.\n * @property {string} [className] - Added to the root.\n * @property {Function} [IntersectionObserver] - The observer class; defaults to\n * the global one. Without either there is no scroll-spy.\n */\n\nexport class DocumentOutline {\n /**\n * @param {HTMLElement|null} host appended to, if given\n * @param {DocumentOutlineConfig} [config]\n */\n constructor(host, config = {}) {\n this.config = {\n entries: [],\n numbering: false,\n maxDepth: 3,\n onSelect: null,\n scrollOnSelect: true,\n scrollBehavior: 'smooth',\n scrollContainer: null,\n resolveTarget: null,\n rootMargin: '0px 0px -70% 0px',\n scrollEndTimeout: 1000,\n emptyState: 'No headings',\n label: 'Outline',\n className: null,\n IntersectionObserver: null,\n ...config,\n };\n this._entries = [];\n this._rows = []; // [{id, entry, depth, number, li, target}] in list order\n this._byId = new Map(); // id \u2192 row\n this._byTarget = new Map(); // target element \u2192 row\n this._inView = new Set(); // rows whose target intersects\n this._activeId = null;\n this._listeners = new Set();\n this._observer = null;\n this._suppressed = false;\n this._timer = null;\n this._disposed = false;\n\n const root = document.createElement('nav');\n root.className = 'twm-doc-outline'\n + (this.config.className ? ` ${this.config.className}` : '');\n if (this.config.label) root.setAttribute('aria-label', this.config.label);\n const list = document.createElement('ol');\n list.className = 'twm-doc-outline__items';\n root.appendChild(list);\n this.element = root;\n this.listElement = list;\n\n this._onClick = (ev) => this._click(ev);\n this._onScrollEnd = () => this._resume();\n list.addEventListener('click', this._onClick);\n this.config.scrollContainer?.addEventListener?.('scrollend', this._onScrollEnd);\n\n this._setEntries(this.config.entries);\n if (host) host.appendChild(root);\n }\n\n // \u2500\u2500 public \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** Replace the entries. The active entry stays active if it is still\n * listed and resolved; otherwise there is none. */\n setEntries(entries) {\n if (this._disposed) return;\n this._setEntries(entries);\n }\n\n /** The entries, as last given. */\n getEntries() {\n return this._entries.slice();\n }\n\n /** Resolve every target again and watch the new ones: the document under\n * the outline was re-rendered. */\n refresh() {\n if (this._disposed) return;\n this._observe();\n this._keepActive();\n }\n\n /** Mark an entry active (`null` for none). An id that is not listed, or\n * whose target is not resolved, is refused: returns false. */\n setActive(id) {\n if (this._disposed) return false;\n if (id == null) { this._activate(null); return true; }\n const row = this._byId.get(String(id));\n if (!row?.target) return false;\n this._activate(row.id);\n return true;\n }\n\n /** The active entry's id, or null. */\n getActive() {\n return this._activeId;\n }\n\n /** `fn(id, entry)` on every change of the active entry (`(null, null)` when\n * none). Returns the function that unsubscribes. */\n onActiveChange(fn) {\n if (typeof fn !== 'function' || this._disposed) return () => {};\n this._listeners.add(fn);\n return () => this._listeners.delete(fn);\n }\n\n /** The `<li>` drawn for an id, or null. */\n getItem(id) {\n return this._byId.get(String(id))?.li || null;\n }\n\n dispose() {\n if (this._disposed) return;\n this._disposed = true;\n this._observer?.disconnect();\n this._observer = null;\n this._clearTimer();\n this._suppressed = false;\n this.config.scrollContainer?.removeEventListener?.('scrollend', this._onScrollEnd);\n this.listElement.removeEventListener('click', this._onClick);\n this._listeners.clear();\n this._byId.clear();\n this._byTarget.clear();\n this._inView.clear();\n this._rows = [];\n this.element.remove();\n }\n\n // \u2500\u2500 drawing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n _setEntries(entries) {\n this._entries = Array.isArray(entries) ? entries.slice() : [];\n this._rows = numberEntries(this._entries, this.config.maxDepth);\n this._byId = new Map(this._rows.map((row) => [row.id, row]));\n this._draw();\n this._observe();\n this._keepActive();\n }\n\n /** The active entry survives a redraw only while it is listed and resolved. */\n _keepActive() {\n if (this._activeId !== null && !this._byId.get(this._activeId)?.target) this._activate(null);\n else this._paint();\n }\n\n _draw() {\n const list = this.listElement;\n list.replaceChildren();\n this.element.querySelector(':scope > .twm-doc-outline__empty')?.remove();\n this.element.classList.toggle('twm-doc-outline--empty', this._rows.length === 0);\n this.element.classList.toggle('twm-doc-outline--numbered', !!this.config.numbering);\n if (!this._rows.length) { this._drawEmpty(); return; }\n for (const row of this._rows) {\n const li = document.createElement('li');\n li.className = `twm-doc-outline__item twm-doc-outline__item--level-${row.depth}`;\n li.style.setProperty('--twm-doc-outline-depth', String(row.depth - 1));\n const button = document.createElement('button');\n button.type = 'button';\n button.className = 'twm-doc-outline__link';\n if (this.config.numbering) {\n const num = document.createElement('span');\n num.className = 'twm-doc-outline__number';\n num.textContent = row.number;\n button.appendChild(num);\n }\n const label = document.createElement('span');\n label.className = 'twm-doc-outline__label';\n label.textContent = String(row.entry.label ?? '');\n button.appendChild(label);\n button.title = (this.config.numbering ? `${row.number} ` : '') + label.textContent;\n li.appendChild(button);\n row.li = li;\n list.appendChild(li);\n }\n }\n\n _drawEmpty() {\n let content = this.config.emptyState;\n if (typeof content === 'function') content = content();\n if (content == null || content === false || content === '') return;\n const p = document.createElement('p');\n p.className = 'twm-doc-outline__empty';\n if (typeof Node !== 'undefined' && content instanceof Node) p.appendChild(content);\n else p.textContent = String(content);\n this.element.appendChild(p);\n }\n\n _paint() {\n for (const row of this._rows) {\n if (!row.li) continue;\n const active = row.id === this._activeId;\n row.li.classList.toggle('twm-doc-outline__item--active', active);\n row.li.classList.toggle('twm-doc-outline__item--unresolved', !row.target);\n const button = row.li.firstChild;\n if (active) button.setAttribute('aria-current', 'location');\n else button.removeAttribute('aria-current');\n }\n }\n\n _activate(id) {\n const next = id ?? null;\n if (next === this._activeId) { this._paint(); return; }\n this._activeId = next;\n this._paint();\n const entry = next === null ? null : this._byId.get(next)?.entry ?? null;\n for (const fn of [...this._listeners]) fn(next, entry);\n }\n\n // \u2500\u2500 the scroll-spy \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n _resolve(entry) {\n const container = this.config.scrollContainer;\n if (typeof this.config.resolveTarget === 'function') {\n return this.config.resolveTarget(entry, container) || null;\n }\n if (!container) return null;\n const id = String(entry.id);\n for (const el of container.querySelectorAll('[id]')) if (el.id === id) return el;\n return null;\n }\n\n _observe() {\n this._observer?.disconnect();\n this._byTarget.clear();\n this._inView.clear();\n for (const row of this._rows) row.target = this._resolve(row.entry);\n for (const row of this._rows) {\n if (row.target && !this._byTarget.has(row.target)) this._byTarget.set(row.target, row);\n }\n const container = this.config.scrollContainer;\n const IO = this.config.IntersectionObserver || globalThis.IntersectionObserver;\n if (!container || typeof IO !== 'function') return;\n if (!this._observer) {\n this._observer = new IO((records) => this._intersect(records), {\n root: container,\n rootMargin: this.config.rootMargin,\n threshold: 0,\n });\n }\n for (const target of this._byTarget.keys()) this._observer.observe(target);\n }\n\n _intersect(records) {\n if (this._disposed) return;\n for (const rec of records) {\n const row = this._byTarget.get(rec.target);\n if (!row) continue;\n if (rec.isIntersecting) this._inView.add(row);\n else this._inView.delete(row);\n }\n if (this._suppressed) return;\n // The topmost section in view: the first listed.\n const top = this._rows.find((row) => this._inView.has(row));\n if (top) this._activate(top.id);\n }\n\n _click(ev) {\n const li = ev.target?.closest?.('.twm-doc-outline__item');\n if (!li || !this.listElement.contains(li)) return;\n const row = this._rows.find((r) => r.li === li);\n if (!row) return;\n if (row.target) {\n this._activate(row.id);\n this._suppress();\n if (this.config.scrollOnSelect && typeof row.target.scrollIntoView === 'function') {\n row.target.scrollIntoView({ block: 'start', behavior: this.config.scrollBehavior });\n }\n }\n this.config.onSelect?.(row.id, row.entry);\n }\n\n _suppress() {\n this._suppressed = true;\n this._clearTimer();\n this._timer = setTimeout(() => this._resume(), this.config.scrollEndTimeout);\n }\n\n _resume() {\n this._clearTimer();\n this._suppressed = false;\n }\n\n _clearTimer() {\n if (this._timer !== null) clearTimeout(this._timer);\n this._timer = null;\n }\n}\n\n/**\n * Build a document outline, append it to `host` (if given) and draw it.\n *\n * @param {HTMLElement|null} host\n * @param {DocumentOutlineConfig} [config]\n * @returns {DocumentOutline}\n */\nexport function createDocumentOutline(host, config = {}) {\n return new DocumentOutline(host, config);\n}\n\n/**\n * Each entry's row: its id as a string, its depth and its hierarchical number.\n * An entry's depth is one more than the number of open sections of a lower\n * level above it, so the shallowest level is depth 1 and a skipped level is\n * one deeper, never two; then at most `maxDepth`.\n */\nfunction numberEntries(entries, maxDepth) {\n const cap = Math.max(1, Math.floor(Number(maxDepth) || 3));\n const open = []; // the levels of the sections this entry may sit under\n const counters = [];\n return entries.map((entry) => {\n const level = Math.max(1, Math.floor(Number(entry?.level) || 1));\n while (open.length && open[open.length - 1] >= level) open.pop();\n const depth = Math.min(cap, open.length + 1);\n open.push(level);\n counters.length = depth;\n counters[depth - 1] = (counters[depth - 1] || 0) + 1;\n return { id: String(entry?.id), entry, depth, number: counters.join('.'), li: null, target: null };\n });\n}\n", "/**\n * HelpModal - Modal dialog for displaying help content\n *\n * Features:\n * - Topics as trusted HTML (`topic.html`) or as markdown (`topic.markdown`),\n * rendered safe by `renderMarkdown` with the provider's `markdownOptions`\n * (a highlighter, math, extension rules)\n * - A table of contents for a topic with two or more headings, markdown or\n * html alike: its headings, listed and numbered, the one in view marked,\n * a click that scrolls to one (`createDocumentOutline`)\n * - Topic search\n * - Category browsing\n * - Keyboard navigation (Escape to close)\n */\n\nimport { helpProvider, helpCategories, helpCopy } from './help_registry.js';\nimport { renderMarkdown } from '../ui/utils/markdown.js';\nimport { createDocumentOutline } from '../ui/components/document_outline.js';\n\n/** The headings a topic's table of contents lists. */\nconst TOC_HEADINGS = 'h1, h2, h3, h4, h5, h6';\n/** Fewer headings than this, and a topic shows no table of contents. */\nconst TOC_MIN_HEADINGS = 2;\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// HelpModal Class\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nlet _activeModal = null;\n\nexport class HelpModal {\n /** The application's help, resolved at use time. */\n get _service() { return helpProvider(); }\n\n get _categories() { return helpCategories(); }\n\n get _copy() { return helpCopy(); }\n\n constructor() {\n // Read LAZILY, not here. A HelpModal can be constructed at boot (the\n // command palette holds one) before the application has registered its\n // help, and a constructor read would freeze the empty default forever.\n this._overlay = null;\n this._modal = null;\n this._currentTopic = null;\n this._searchQuery = '';\n this._fallback = null;\n this._toc = null;\n this._boundKeyHandler = this._handleKeyDown.bind(this);\n }\n\n /**\n * Open the help modal.\n * @param {string} [topicId] - Initial topic to display\n * @param {Object} [options]\n * @param {{title: string, html: string}} [options.fallback] - Shown for\n * `topicId` when the provider has no such topic (its `loadTopic` answers\n * null). A library-owned topic, such as the palette's keyboard shortcuts,\n * uses it so that an application's own topic of that id still wins.\n */\n async open(topicId = null, { fallback = null } = {}) {\n this._fallback = topicId && fallback ? { id: topicId, topic: fallback } : null;\n // Close any existing modal\n if (_activeModal && _activeModal !== this) {\n _activeModal.close();\n }\n _activeModal = this;\n\n this._createModal();\n document.body.appendChild(this._overlay);\n\n // Add keyboard handler\n document.addEventListener('keydown', this._boundKeyHandler);\n\n // Focus search input\n const searchInput = this._modal.querySelector('.help-search-input');\n if (searchInput) {\n setTimeout(() => searchInput.focus(), 100);\n }\n\n // Load initial topic or show index\n if (topicId) {\n await this._loadTopic(topicId);\n } else {\n this._showIndex();\n }\n }\n\n /**\n * Close the help modal.\n */\n close() {\n this._disposeToc();\n if (this._overlay) {\n document.removeEventListener('keydown', this._boundKeyHandler);\n this._overlay.remove();\n this._overlay = null;\n this._modal = null;\n }\n if (_activeModal === this) {\n _activeModal = null;\n }\n }\n\n /**\n * Create the modal DOM structure.\n * @private\n */\n _createModal() {\n // Overlay\n this._overlay = document.createElement('div');\n this._overlay.className = 'help-modal-overlay';\n this._overlay.addEventListener('click', (e) => {\n if (e.target === this._overlay) this.close();\n });\n\n // Modal container\n this._modal = document.createElement('div');\n this._modal.className = 'help-modal';\n this._modal.innerHTML = `\n <div class=\"help-modal__header\">\n <div class=\"help-modal__title\">\n <span class=\"material-symbols-outlined\">help</span>\n <span>Help</span>\n </div>\n <button class=\"help-modal__close\" title=\"Close (Esc)\">\n <span class=\"material-symbols-outlined\">close</span>\n </button>\n </div>\n <div class=\"help-modal__search\">\n <span class=\"material-symbols-outlined\">search</span>\n <input type=\"text\" class=\"help-search-input\" placeholder=\"Search help topics...\" autocomplete=\"off\">\n </div>\n <div class=\"help-modal__body\">\n <nav class=\"help-modal__sidebar\">\n <div class=\"help-sidebar__categories\"></div>\n </nav>\n <main class=\"help-modal__content\">\n <div class=\"help-content__loading\">Loading...</div>\n </main>\n </div>\n `;\n\n // Event handlers\n const closeBtn = this._modal.querySelector('.help-modal__close');\n closeBtn.addEventListener('click', () => this.close());\n\n const searchInput = this._modal.querySelector('.help-search-input');\n searchInput.addEventListener('input', (e) => this._handleSearch(e.target.value));\n searchInput.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') {\n if (e.target.value) {\n e.target.value = '';\n this._handleSearch('');\n e.stopPropagation();\n }\n }\n });\n\n // Build sidebar\n this._buildSidebar();\n\n this._overlay.appendChild(this._modal);\n }\n\n /**\n * Build the sidebar navigation.\n * @private\n */\n _buildSidebar() {\n const container = this._modal.querySelector('.help-sidebar__categories');\n const categories = this._service.getCategories();\n\n // Sort categories by order\n const categoryOrder = Object.keys(this._categories);\n categories.sort((a, b) => {\n const orderA = categoryOrder.indexOf(a);\n const orderB = categoryOrder.indexOf(b);\n return (orderA === -1 ? 99 : orderA) - (orderB === -1 ? 99 : orderB);\n });\n\n container.innerHTML = categories.map(category => {\n const topics = this._service.getTopicsByCategory(category);\n const label = this._categories[category]?.label || category;\n const icon = this._categories[category]?.icon || 'folder';\n\n return `\n <div class=\"help-category\" data-category=\"${escapeHtml(category)}\">\n <div class=\"help-category__header\">\n <span class=\"material-symbols-outlined\">${escapeHtml(icon)}</span>\n <span>${escapeHtml(label)}</span>\n </div>\n <ul class=\"help-category__topics\">\n ${topics.map(topic => `\n <li class=\"help-topic-item\" data-topic=\"${escapeHtml(topic.id)}\">\n ${escapeHtml(topic.title)}\n </li>\n `).join('')}\n </ul>\n </div>\n `;\n }).join('');\n\n // Add click handlers\n container.querySelectorAll('.help-topic-item').forEach(item => {\n item.addEventListener('click', () => {\n this._loadTopic(item.dataset.topic);\n });\n });\n\n container.querySelectorAll('.help-category__header').forEach(header => {\n header.addEventListener('click', () => {\n header.parentElement.classList.toggle('collapsed');\n });\n });\n }\n\n /**\n * Show the help index page.\n * @private\n */\n _showIndex() {\n this._disposeToc();\n const content = this._modal.querySelector('.help-modal__content');\n const categories = this._service.getCategories();\n\n const categoryOrder = Object.keys(this._categories);\n categories.sort((a, b) => {\n const orderA = categoryOrder.indexOf(a);\n const orderB = categoryOrder.indexOf(b);\n return (orderA === -1 ? 99 : orderA) - (orderB === -1 ? 99 : orderB);\n });\n\n content.innerHTML = `\n <div class=\"help-index\">\n <h1>${this._copy.title}</h1>\n <p>${this._copy.welcome}</p>\n\n <div class=\"help-index__grid\">\n ${categories.map(category => {\n const topics = this._service.getTopicsByCategory(category);\n const label = this._categories[category]?.label || category;\n const icon = this._categories[category]?.icon || 'folder';\n\n return `\n <div class=\"help-index__category\" data-category=\"${escapeHtml(category)}\">\n <div class=\"help-index__category-header\">\n <span class=\"material-symbols-outlined\">${escapeHtml(icon)}</span>\n <span>${escapeHtml(label)}</span>\n </div>\n <ul class=\"help-index__topics\">\n ${topics.slice(0, 3).map(topic => `\n <li class=\"help-index__topic\" data-topic=\"${escapeHtml(topic.id)}\">\n ${escapeHtml(topic.title)}\n </li>\n `).join('')}\n ${topics.length > 3 ? `<li class=\"help-index__more\">+${topics.length - 3} more</li>` : ''}\n </ul>\n </div>\n `;\n }).join('')}\n </div>\n </div>\n `;\n\n // Add click handlers\n content.querySelectorAll('.help-index__topic').forEach(item => {\n item.addEventListener('click', () => {\n this._loadTopic(item.dataset.topic);\n });\n });\n }\n\n /**\n * Load and display a topic.\n * @param {string} topicId - Topic ID\n * @private\n */\n async _loadTopic(topicId) {\n this._disposeToc();\n const content = this._modal.querySelector('.help-modal__content');\n content.innerHTML = '<div class=\"help-content__loading\">Loading...</div>';\n\n // Update sidebar selection\n this._modal.querySelectorAll('.help-topic-item').forEach(item => {\n item.classList.toggle('active', item.dataset.topic === topicId);\n });\n\n try {\n const topic = (await this._service.loadTopic(topicId))\n ?? (this._fallback?.id === topicId ? this._fallback.topic : null);\n // Closed (or closed and opened again) while the topic loaded.\n if (!this._modal?.contains(content)) return;\n this._currentTopic = topicId;\n\n if (!topic) {\n // An id nobody provides is not a load failure: say so plainly.\n content.innerHTML = `\n <div class=\"help-content__error help-content__error--not-found\">\n <span class=\"material-symbols-outlined\">search_off</span>\n <p>Help topic not found.</p>\n </div>\n `;\n return;\n }\n\n content.innerHTML = `\n <div class=\"help-content__article\">\n <div class=\"help-content__breadcrumb\">\n <a href=\"#\" class=\"help-breadcrumb__home\" title=\"Help Index\">\n <span class=\"material-symbols-outlined\">home</span>\n </a>\n <span class=\"help-breadcrumb__separator\">/</span>\n <span class=\"help-breadcrumb__title\">${escapeHtml(topic.title)}</span>\n </div>\n <div class=\"help-content__toc\" hidden></div>\n <article class=\"help-article\">\n ${this._articleHtml(topic)}\n </article>\n </div>\n `;\n\n // Add breadcrumb handler\n content.querySelector('.help-breadcrumb__home').addEventListener('click', (e) => {\n e.preventDefault();\n this._showIndex();\n });\n\n this._buildToc(content);\n } catch (error) {\n content.innerHTML = `\n <div class=\"help-content__error\">\n <span class=\"material-symbols-outlined\">error</span>\n <p>Failed to load help topic.</p>\n </div>\n `;\n }\n }\n\n /**\n * The article body: a markdown topic rendered safe, else the provider's\n * own HTML, which is trusted by contract.\n * @private\n */\n _articleHtml(topic) {\n if (typeof topic.markdown === 'string') {\n return renderMarkdown(topic.markdown, this._service.markdownOptions ?? {});\n }\n return topic.html ?? '';\n }\n\n /**\n * The topic's table of contents: one entry per heading in the article, in\n * document order, its level the heading's. Built only when the article\n * has `TOC_MIN_HEADINGS` or more; the outline resolves each entry to its\n * heading ELEMENT, so the provider's markup needs no ids and the modal\n * adds none.\n * @param {HTMLElement} content - The scrolling content pane.\n * @private\n */\n _buildToc(content) {\n this._disposeToc();\n const host = content.querySelector('.help-content__toc');\n const headings = [...content.querySelectorAll(`.help-article :is(${TOC_HEADINGS})`)];\n if (!host || headings.length < TOC_MIN_HEADINGS) return;\n const byId = new Map(headings.map((heading, index) => [`heading-${index}`, heading]));\n const entries = [...byId].map(([id, heading]) => ({\n id,\n level: Number(heading.tagName.slice(1)),\n label: heading.textContent.trim(),\n }));\n host.hidden = false;\n this._toc = createDocumentOutline(host, {\n entries,\n numbering: true,\n scrollContainer: content,\n resolveTarget: (entry) => byId.get(entry.id) ?? null,\n label: 'Contents',\n });\n }\n\n /** @private */\n _disposeToc() {\n this._toc?.dispose();\n this._toc = null;\n }\n\n /**\n * Handle search input.\n * @param {string} query - Search query\n * @private\n */\n _handleSearch(query) {\n this._searchQuery = query;\n const content = this._modal.querySelector('.help-modal__content');\n\n if (!query.trim()) {\n this._showIndex();\n return;\n }\n\n this._disposeToc();\n const results = this._service.searchTopics(query);\n\n if (results.length === 0) {\n content.innerHTML = `\n <div class=\"help-search-results\">\n <h2>Search Results</h2>\n <p class=\"help-search-empty\">No results found for \"${escapeHtml(query)}\"</p>\n </div>\n `;\n return;\n }\n\n content.innerHTML = `\n <div class=\"help-search-results\">\n <h2>Search Results</h2>\n <p class=\"help-search-count\">${results.length} result${results.length !== 1 ? 's' : ''} for \"${escapeHtml(query)}\"</p>\n <ul class=\"help-search-list\">\n ${results.map(topic => `\n <li class=\"help-search-item\" data-topic=\"${escapeHtml(topic.id)}\">\n <span class=\"help-search-item__title\">${escapeHtml(topic.title)}</span>\n <span class=\"help-search-item__category\">${escapeHtml(this._categories[topic.category]?.label || topic.category)}</span>\n </li>\n `).join('')}\n </ul>\n </div>\n `;\n\n // Add click handlers\n content.querySelectorAll('.help-search-item').forEach(item => {\n item.addEventListener('click', () => {\n this._loadTopic(item.dataset.topic);\n });\n });\n }\n\n /**\n * Handle keyboard events.\n * @param {KeyboardEvent} event\n * @private\n */\n _handleKeyDown(event) {\n if (event.key === 'Escape') {\n this.close();\n }\n }\n\n /**\n * Static method to open help modal.\n * @param {string} [topicId] - Initial topic\n * @param {Object} [options] - As for the instance `open`.\n * @returns {HelpModal}\n */\n static open(topicId = null, options = {}) {\n const modal = new HelpModal();\n modal.open(topicId, options);\n return modal;\n }\n\n /**\n * Close the open help modal, or open the index when none is open \u2014 what\n * the `?` shortcut does.\n * @returns {HelpModal|null} the modal opened, or null when one was closed\n */\n static toggle() {\n if (_activeModal) {\n _activeModal.close();\n return null;\n }\n return HelpModal.open();\n }\n\n /**\n * Get the currently active modal.\n * @returns {HelpModal|null}\n */\n static getActive() {\n return _activeModal;\n }\n}\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// Helpers\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n/**\n * Text for an innerHTML template. Everything the modal interpolates \u2014 the\n * search query the user typed, and the topic ids, titles and categories the\n * provider hands back \u2014 is TEXT; only `topic.html` is markup, by contract\n * (and `topic.markdown` becomes markup through `renderMarkdown`).\n * Quotes are escaped too, because ids and categories land in attributes.\n */\nfunction escapeHtml(value) {\n if (value === null || value === undefined) return '';\n return String(value)\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// The `?` shortcut \u2014 installed, never imported\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n/**\n * Bind `?` (outside editable fields) to `HelpModal.toggle()` on `target`, and\n * return the disposer that takes it off again.\n *\n * Importing this module binds nothing. It used to add a `document` listener as\n * a side effect of the import, which nobody could remove: a second shell in the\n * same page, or an application with its own `?`, got two handlers. A\n * `createShell()` shell binds `?` through its keymap (`installKeymap`), and\n * `shell.dispose()` takes it off; this is for a page that uses the help modal\n * without the shell.\n *\n * @param {object} [opts]\n * @param {EventTarget} [opts.target=document]\n * @returns {() => void}\n */\nexport function installHelpShortcut({ target = document } = {}) {\n const onKeyDown = (event) => {\n if (event.defaultPrevented || event.key !== '?') return;\n // Don't hijack `?` typed into a field (search boxes, editors).\n if (event.target?.closest?.('input, textarea, select, [contenteditable=\"true\"]')) return;\n event.preventDefault();\n HelpModal.toggle();\n };\n target.addEventListener('keydown', onKeyDown);\n return () => target.removeEventListener('keydown', onKeyDown);\n}\n\nexport default HelpModal;\n", "/**\n * menu_bar.js \u2014 a desktop menu bar, driven by a declarative model (STORY-0030).\n *\n * const bar = createMenuBar(el, {\n * menus: [\n * { id: 'file', label: 'File', items: [\n * { id: 'open', label: 'Open\u2026', shortcut: 'Ctrl+O' },\n * { id: 'recent', label: 'Open recent', submenu: () => recentItems() },\n * { separator: true },\n * { id: 'save', label: 'Save', shortcut: 'Ctrl+S', disabled: true },\n * ] },\n * { id: 'view', label: 'View', items: [\n * { id: 'grid', label: 'Show grid', checked: true }, // a check item\n * { id: 'light', label: 'Light', radio: 'theme', checked: true }, // a radio group\n * { id: 'dark', label: 'Dark', radio: 'theme', checked: false },\n * ] },\n * ],\n * onAction: (id, { item, checked }) => { \u2026 },\n * });\n *\n * \u2500\u2500 The model \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * A menu is `{ id, label, items }`. An item is `{ id, label, shortcut?,\n * disabled?, checked?, radio?, submenu? }`, or `{ separator: true }`.\n * checked a boolean makes it a CHECK item (`menuitemcheckbox`); with\n * `radio: '<group>'` it is a RADIO item (`menuitemradio`), and\n * checking one unchecks the rest of its group.\n * submenu an array of items, or a FUNCTION returning one. A function is\n * called every time the submenu opens, so a list that changes\n * under the bar (recent files, open windows) is always current.\n * shortcut drawn on the right. It is a label: the bar binds no key for it.\n *\n * `onAction(id, { item, checked })` is called for an enabled leaf item \u2014\n * never for a disabled one, a separator, or an item that opens a submenu. A\n * check or radio item has already flipped when it is called; `checked` is\n * the new state.\n *\n * \u2500\u2500 The keyboard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Alt (pressed and released on its own) or F10 focuses the bar, and pressing\n * either again leaves it. On a title: Left/Right move across the titles,\n * Down/Enter/Space open its menu on the first item, Up on the last. In a\n * menu: Up/Down/Home/End move within it, skipping separators and disabled\n * items; Right opens a submenu, or moves to the next menu; Left closes a\n * submenu, or moves to the previous menu; Enter/Space activate. Esc closes\n * one level at a time, and the Esc that leaves the bar gives focus back to\n * whatever had it before the bar did. Activating an item gives it back too,\n * BEFORE `onAction` runs, so a command acts on the context the user was in.\n *\n * \u2500\u2500 The pointer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Clicking a title opens its menu (and closes it again); while a menu is\n * open, moving over another title switches to it. Moving over an item with a\n * submenu opens it. A press outside the bar closes everything.\n *\n * \u2500\u2500 State lives here, not in the DOM \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * `setEnabled(id, bool)` and `setChecked(id, bool)` record an override for\n * that id, which wins over what the model says from then on \u2014 including over\n * a function submenu's fresh items \u2014 and patch any open menu IN PLACE: the\n * bar is not rebuilt, and focus stays where it was. A radio group keeps ONE\n * recorded selection, so it shows exactly one checked item however its menu\n * is reached \u2014 opened later, a function submenu included. To find an id the\n * bar calls function submenus (as `commands()` does), open or not.\n * `commands()` returns the same model as command-palette rows (`{ id, label,\n * shortcut, context, action }`), so the palette and the bar list identical\n * verbs.\n *\n * \u2500\u2500 Roles \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * The WAI-ARIA menubar pattern: `role=\"menubar\"` on the element you pass,\n * a `role=\"menuitem\"` title per menu inside a `role=\"none\"` wrapper, each\n * open menu a `role=\"menu\"` beside its title (or its parent item), items\n * `menuitem` / `menuitemcheckbox` / `menuitemradio` with `aria-checked`,\n * `aria-disabled` and, on a submenu's item, `aria-haspopup`/`aria-expanded`.\n * One title is in the tab order at a time (a roving tabindex).\n *\n * Every listener outside the bar is on the element's own document, and\n * `dispose()` takes them off.\n */\n\nconst SEL_TITLE = '.twm-menubar__title';\nconst SEL_ITEM = '.twm-menubar__item';\nconst SEL_MENU = '.twm-menubar__menu';\n\n/** @returns {MenuBar} */\nexport function createMenuBar(el, opts) {\n return new MenuBar(el, opts);\n}\n\nexport class MenuBar {\n /**\n * @param {Element} el the element that becomes the bar\n * @param {object} opts\n * @param {Array} opts.menus `[{ id, label, items }]`\n * @param {Function} [opts.onAction] `(id, { item, checked }) => void`\n * @param {string} [opts.label] the bar's accessible name ('Menu')\n * @param {string} [opts.emptyLabel] the disabled row an empty submenu shows ('Empty')\n */\n constructor(el, { menus, onAction = null, label = 'Menu', emptyLabel = 'Empty' } = {}) {\n if (!el || typeof el.appendChild !== 'function') {\n throw new TypeError('createMenuBar: `el` must be an element');\n }\n _validateMenus(menus);\n this.el = el;\n this.menus = menus;\n this._onAction = typeof onAction === 'function' ? onAction : null;\n this._emptyLabel = emptyLabel;\n this._doc = el.ownerDocument;\n this._disabled = new Map(); // id -> boolean (override)\n this._checked = new Map(); // id -> boolean (override, check items)\n this._radio = new Map(); // radio group -> the checked id (or null: none)\n this._models = new WeakMap(); // item element -> model item\n this._stack = []; // open menus: [{ menu, parent }]\n this._openIdx = -1; // which title's menu is open\n this._active = false; // focus is in the bar, or a menu is open\n this._returnTo = null; // what had focus before the bar did\n this._altArmed = false;\n\n el.innerHTML = '';\n el.classList.add('twm-menubar');\n el.setAttribute('role', 'menubar');\n el.setAttribute('aria-label', label);\n this._titles = menus.map((m, i) => {\n const entry = this._doc.createElement('div');\n entry.className = 'twm-menubar__entry';\n entry.setAttribute('role', 'none');\n const btn = this._doc.createElement('button');\n btn.type = 'button';\n btn.className = 'twm-menubar__title';\n btn.setAttribute('role', 'menuitem');\n btn.setAttribute('aria-haspopup', 'menu');\n btn.setAttribute('aria-expanded', 'false');\n btn.tabIndex = i === 0 ? 0 : -1;\n btn.textContent = m.label;\n entry.appendChild(btn);\n el.appendChild(entry);\n return btn;\n });\n\n this._h = {\n mousedown: (e) => this._onMouseDown(e),\n click: (e) => this._onClick(e),\n mouseover: (e) => this._onMouseOver(e),\n keydown: (e) => this._onKey(e),\n keyup: (e) => { if (e.key === ' ' && this.el.contains(e.target)) e.preventDefault(); },\n focusin: (e) => this._onFocusIn(e),\n focusout: (e) => this._onFocusOut(e),\n docKeydown: (e) => this._onDocKeyDown(e),\n docKeyup: (e) => this._onDocKeyUp(e),\n docMousedown: (e) => this._onDocMouseDown(e),\n // Alt+Tab, Alt+F4, Alt+Space: the second key goes to the OS, so no\n // keydown reaches the page to disarm Alt. The window losing focus\n // does, or the Alt keyup on return would take focus to the bar.\n winBlur: () => { this._altArmed = false; },\n };\n for (const k of ['mousedown', 'click', 'mouseover', 'keydown', 'keyup', 'focusin', 'focusout']) {\n el.addEventListener(k, this._h[k]);\n }\n this._doc.addEventListener('keydown', this._h.docKeydown, true);\n this._doc.addEventListener('keyup', this._h.docKeyup, true);\n this._doc.addEventListener('mousedown', this._h.docMousedown, true);\n this._doc.defaultView?.addEventListener('blur', this._h.winBlur);\n }\n\n // \u2500\u2500 public \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** Whether a menu is open. */\n isOpen() { return this._openIdx >= 0; }\n\n /** Open the menu with this id (focus on its title, or on its first item). */\n open(menuId, { focusItem = false } = {}) {\n const i = this.menus.findIndex((m) => m.id === menuId);\n if (i < 0) return;\n this._enter();\n this._open(i, focusItem ? 'first' : null);\n }\n\n /** Close every open menu. Focus stays in the bar if it was there. */\n close() { this._closeAll(); }\n\n /** Focus the bar's first title, as Alt or F10 does. */\n focus() {\n this._enter();\n this._focusTitle(0);\n }\n\n isEnabled(id) {\n const item = this._findModel(id);\n return item ? !this._isDisabled(item) : !this._disabled.get(id);\n }\n\n isChecked(id) {\n const item = this._findModel(id);\n return item ? this._isChecked(item) : !!this._checked.get(id);\n }\n\n /** Enable or disable every item with this id; an open menu is patched in place. */\n setEnabled(id, enabled) {\n this._disabled.set(id, !enabled);\n this._patch(id);\n }\n\n /** Check or uncheck every item with this id; checking a radio item\n * unchecks the rest of its group. An open menu is patched in place. */\n setChecked(id, checked) {\n this._check(this._findModel(id), id, checked);\n }\n\n /**\n * The model as command-palette rows: one per enabled leaf item, labelled\n * as in the menu, with its `shortcut`, and its menu path as `context`\n * ('File \u203A Open recent'). A function submenu is called now, so the rows\n * are as current as the menu would be. `action` runs the item exactly as\n * a click would, including flipping a check or radio item.\n */\n commands() {\n const rows = [];\n const walk = (items, path) => {\n for (const it of _resolve(items)) {\n if (!it || it.separator || this._isDisabled(it)) continue;\n if (it.submenu != null) { walk(it.submenu, [...path, it.label]); continue; }\n rows.push({\n id: `menubar:${it.id}`,\n label: it.label,\n ...(it.shortcut ? { shortcut: it.shortcut } : {}),\n context: path.join(' \u203A '),\n verb: 'run',\n action: () => this._fire(it),\n });\n }\n };\n for (const m of this.menus) walk(m.items, [m.label]);\n return rows;\n }\n\n dispose() {\n this._closeAll();\n for (const k of ['mousedown', 'click', 'mouseover', 'keydown', 'keyup', 'focusin', 'focusout']) {\n this.el.removeEventListener(k, this._h[k]);\n }\n this._doc.removeEventListener('keydown', this._h.docKeydown, true);\n this._doc.removeEventListener('keyup', this._h.docKeyup, true);\n this._doc.removeEventListener('mousedown', this._h.docMousedown, true);\n this._doc.defaultView?.removeEventListener('blur', this._h.winBlur);\n this.el.innerHTML = '';\n this.el.classList.remove('twm-menubar');\n this.el.removeAttribute('role');\n this.el.removeAttribute('aria-label');\n }\n\n // \u2500\u2500 state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n _isDisabled(item) {\n return this._disabled.has(item.id) ? this._disabled.get(item.id) : !!item.disabled;\n }\n\n _isChecked(item) {\n if (item.radio != null && this._radio.has(item.radio)) return this._radio.get(item.radio) === item.id;\n return this._checked.has(item.id) ? this._checked.get(item.id) : !!item.checked;\n }\n\n /** Record a check. `item` is the model item when the bar knows it (a\n * radio item then records its group's selection); `id` alone is kept as\n * an override for an item the model does not hold yet. */\n _check(item, id, checked) {\n if (item?.radio != null) {\n const group = item.radio;\n if (checked) this._radio.set(group, id);\n else if (this._isChecked(item)) this._radio.set(group, null);\n this._patchGroup(group);\n return;\n }\n this._checked.set(id, !!checked);\n this._patch(id);\n }\n\n /** Every model item the bar knows of: the model, with every function\n * submenu called now (as `commands()` does), and whatever is on screen. */\n _knownItems() {\n const out = [];\n const walk = (items) => {\n for (const it of _resolve(items)) {\n if (!it || it.separator) continue;\n out.push(it);\n if (it.submenu != null) walk(it.submenu);\n }\n };\n for (const m of this.menus) walk(m.items);\n for (const b of this.el.querySelectorAll(SEL_ITEM)) {\n const it = this._models.get(b);\n if (it && !out.includes(it)) out.push(it);\n }\n return out;\n }\n\n _findModel(id) { return this._knownItems().find((it) => it.id === id) || null; }\n\n /** Re-apply the state of every rendered item with this id. */\n _patch(id) {\n for (const b of this.el.querySelectorAll(SEL_ITEM)) {\n const it = this._models.get(b);\n if (it && it.id === id) this._apply(b, it);\n }\n }\n\n /** Re-apply the state of every rendered item of this radio group. */\n _patchGroup(group) {\n for (const b of this.el.querySelectorAll(SEL_ITEM)) {\n const it = this._models.get(b);\n if (it && it.radio === group) this._apply(b, it);\n }\n }\n\n _apply(btn, item) {\n const off = this._isDisabled(item);\n btn.classList.toggle('twm-menubar__item--disabled', off);\n if (off) btn.setAttribute('aria-disabled', 'true');\n else btn.removeAttribute('aria-disabled');\n if (_kind(item) !== 'menuitem') {\n btn.setAttribute('aria-checked', this._isChecked(item) ? 'true' : 'false');\n }\n }\n\n // \u2500\u2500 open / close \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n _setRoving(i) {\n this._titles.forEach((t, j) => { t.tabIndex = j === i ? 0 : -1; });\n }\n\n _focusTitle(i) {\n this._setRoving(i);\n this._titles[i]?.focus({ preventScroll: true });\n }\n\n /** The bar becomes active; remember what to give focus back to. */\n _enter(from = this._doc.activeElement) {\n if (this._active) return;\n this._active = true;\n this._returnTo = from && from !== this._doc.body && !this.el.contains(from) ? from : null;\n }\n\n /** Leave the bar and give focus back. */\n _exit() {\n const back = this._returnTo;\n this._closeAll();\n this._active = false;\n this._returnTo = null;\n if (back?.isConnected) back.focus({ preventScroll: true });\n else if (this.el.contains(this._doc.activeElement)) this._doc.activeElement.blur();\n }\n\n /** Focus went elsewhere on purpose: close, give nothing back. */\n _deactivate() {\n this._closeAll();\n this._active = false;\n this._returnTo = null;\n }\n\n _open(i, focus) {\n const n = this._titles.length;\n i = ((i % n) + n) % n;\n // Focus moves to the title BEFORE the old menu goes, so the element\n // being removed never holds focus.\n this._focusTitle(i);\n this._closeAll();\n const m = this.menus[i];\n const title = this._titles[i];\n const menu = this._buildMenu(m.items, m.label);\n title.parentElement.appendChild(menu);\n title.setAttribute('aria-expanded', 'true');\n this._stack = [{ menu, parent: title }];\n this._openIdx = i;\n _place(menu, title, 'below');\n this._focusIn(menu, focus);\n }\n\n _openSub(btn, focus) {\n const item = this._models.get(btn);\n if (!item || item.submenu == null || this._isDisabled(item)) return;\n const level = this._levelOf(btn);\n if (level < 0) return;\n const open = this._stack[level + 1];\n if (open && open.parent === btn) { this._focusIn(open.menu, focus); return; }\n this._closeFrom(level + 1);\n const menu = this._buildMenu(item.submenu, item.label); // a function is called here, every time\n btn.parentElement.appendChild(menu);\n btn.setAttribute('aria-expanded', 'true');\n this._stack.push({ menu, parent: btn });\n _place(menu, btn, 'right');\n this._focusIn(menu, focus);\n }\n\n _focusIn(menu, focus) {\n if (!focus) return;\n const items = this._enabledIn(menu);\n (focus === 'last' ? items[items.length - 1] : items[0])?.focus({ preventScroll: true });\n }\n\n /** Close the menus at `level` and deeper. Focus inside them goes to the\n * item (or title) they hang from. */\n _closeFrom(level) {\n if (level >= this._stack.length) return;\n const first = this._stack[level];\n if (this._stack.slice(level).some((s) => s.menu.contains(this._doc.activeElement))) {\n first.parent.focus({ preventScroll: true });\n }\n for (const s of this._stack.splice(level)) {\n s.menu.remove();\n s.parent.setAttribute('aria-expanded', 'false');\n }\n if (level === 0) this._openIdx = -1;\n }\n\n _closeAll() { this._closeFrom(0); }\n\n _levelOf(el) {\n const menu = el.closest(SEL_MENU);\n return this._stack.findIndex((s) => s.menu === menu);\n }\n\n /** The items the keyboard can land on: no separators, nothing disabled. */\n _enabledIn(menu) {\n return this._itemsIn(menu).filter((b) => !this._isDisabled(this._models.get(b)));\n }\n\n /** Every item cell of `menu` in DOM order, disabled ones included. */\n _itemsIn(menu) {\n return [...menu.children]\n .map((w) => w.firstElementChild)\n .filter((b) => b?.matches?.(SEL_ITEM));\n }\n\n /** The next (`dir` 1) or previous (-1) enabled item from `btn`'s place\n * among all the cells, wrapping. `btn` itself may be disabled: one\n * setEnabled(id, false) leaves focus on it. */\n _stepFrom(menu, btn, dir) {\n const all = this._itemsIn(menu);\n const n = all.length;\n const at = all.indexOf(btn);\n for (let k = 1; k <= n; k++) {\n const b = all[(((at + dir * k) % n) + n) % n];\n if (!this._isDisabled(this._models.get(b))) return b;\n }\n return null;\n }\n\n _buildMenu(items, label) {\n const d = this._doc;\n const menu = d.createElement('div');\n menu.className = 'twm-menubar__menu';\n menu.setAttribute('role', 'menu');\n menu.setAttribute('aria-label', label);\n const list = _resolve(items).filter((it) => {\n if (it && (it.separator || (it.id != null && it.label != null))) return true;\n console.warn('[menubar] an item needs an id and a label', it);\n return false;\n });\n const shown = list.length ? list : [{ id: null, label: this._emptyLabel, disabled: true, _empty: true }];\n for (const it of shown) {\n if (it.separator) {\n const sep = d.createElement('div');\n sep.className = 'twm-menubar__separator';\n sep.setAttribute('role', 'separator');\n menu.appendChild(sep);\n continue;\n }\n const wrap = d.createElement('div');\n wrap.className = 'twm-menubar__cell';\n wrap.setAttribute('role', 'none');\n const btn = d.createElement('button');\n btn.type = 'button';\n btn.tabIndex = -1;\n const kind = _kind(it);\n btn.className = 'twm-menubar__item';\n if (kind !== 'menuitem') btn.classList.add(kind === 'menuitemradio' ? 'twm-menubar__item--radio' : 'twm-menubar__item--check');\n btn.setAttribute('role', kind);\n if (it.id != null) btn.dataset.itemId = it.id;\n const check = d.createElement('span');\n check.className = 'twm-menubar__check';\n check.setAttribute('aria-hidden', 'true');\n const text = d.createElement('span');\n text.className = 'twm-menubar__label';\n text.textContent = it.label;\n btn.append(check, text);\n if (it.shortcut) {\n const sc = d.createElement('span');\n sc.className = 'twm-menubar__shortcut';\n sc.textContent = it.shortcut;\n btn.appendChild(sc);\n }\n if (it.submenu != null) {\n btn.setAttribute('aria-haspopup', 'menu');\n btn.setAttribute('aria-expanded', 'false');\n btn.classList.add('twm-menubar__item--submenu');\n const arrow = d.createElement('span');\n arrow.className = 'twm-menubar__arrow';\n arrow.setAttribute('aria-hidden', 'true');\n btn.appendChild(arrow);\n }\n this._models.set(btn, it);\n this._apply(btn, it);\n wrap.appendChild(btn);\n menu.appendChild(wrap);\n }\n return menu;\n }\n\n // \u2500\u2500 activation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n _activate(btn) {\n const item = this._models.get(btn);\n if (!item || this._isDisabled(item)) return;\n if (item.submenu != null) { this._openSub(btn, 'first'); return; }\n this._exit();\n this._fire(item);\n }\n\n /** Flip a check/radio item and tell the embedder. The ONE door to\n * `onAction`, for clicks, keys and palette rows alike. */\n _fire(item) {\n if (!item || item.separator || item._empty || this._isDisabled(item) || item.submenu != null) return;\n let checked;\n // The item itself, not its id: it carries its own radio group even\n // when it came from a function submenu that is not on screen.\n if (_kind(item) === 'menuitemradio') { this._check(item, item.id, true); checked = true; }\n else if (_kind(item) === 'menuitemcheckbox') { checked = !this._isChecked(item); this._check(item, item.id, checked); }\n this._onAction?.(item.id, { item, checked });\n }\n\n // \u2500\u2500 events \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n _onMouseDown(e) {\n // Before the button could take focus: remember what had it. No press\n // in the bar moves focus by itself \u2014 not on a title or an item, nor\n // on a separator, a menu's padding or the bar's empty space \u2014 the bar\n // moves it (a title on click, an item on hover), so focus never drops\n // to nothing on the way, which would end the bar's activation (see\n // _onFocusOut).\n if (e.target.closest?.(SEL_TITLE)) this._enter();\n e.preventDefault();\n }\n\n _onClick(e) {\n const title = e.target.closest?.(SEL_TITLE);\n if (title) {\n const i = this._titles.indexOf(title);\n this._enter();\n if (this._openIdx === i) this._closeAll();\n else this._open(i, null);\n return;\n }\n const btn = e.target.closest?.(SEL_ITEM);\n if (btn) { e.stopPropagation(); this._activate(btn); }\n }\n\n _onMouseOver(e) {\n const title = e.target.closest?.(SEL_TITLE);\n if (title) {\n const i = this._titles.indexOf(title);\n if (this._openIdx >= 0 && this._openIdx !== i) this._open(i, null);\n return;\n }\n const btn = e.target.closest?.(SEL_ITEM);\n if (!btn) return;\n const item = this._models.get(btn);\n if (!item || this._isDisabled(item)) return;\n btn.focus({ preventScroll: true });\n const level = this._levelOf(btn);\n if (item.submenu != null) this._openSub(btn, null);\n else if (level >= 0) this._closeFrom(level + 1);\n }\n\n /** Tabbed into: what had focus is the event's `relatedTarget`. */\n _onFocusIn(e) {\n if (!this._active) this._enter(e.relatedTarget);\n }\n\n /** Focus left the bar: to an element outside it, or to nothing (a press\n * on a non-focusable area, the window losing focus). Either way the\n * activation ends, so the next Alt/F10 remembers what has focus THEN. */\n _onFocusOut(e) {\n const to = e.relatedTarget;\n if (!to || !this.el.contains(to)) this._deactivate();\n }\n\n _onKey(e) {\n if (e.ctrlKey || e.metaKey || e.altKey) return; // app chords pass through\n const title = e.target.closest?.(SEL_TITLE);\n const btn = title ? null : e.target.closest?.(SEL_ITEM);\n if (!title && !btn) return;\n if (e.key === 'Tab') { this._deactivate(); return; } // focus moves on, as Tab says\n const handled = title ? this._titleKey(e.key, this._titles.indexOf(title))\n : this._itemKey(e.key, btn);\n if (handled) e.preventDefault();\n // Keys meant for the bar do not reach the page's own bindings\n // (Backspace is a \"go back\" in the window manager). F-keys do.\n if (handled || !/^F\\d+$/.test(e.key)) e.stopPropagation();\n }\n\n _titleKey(key, i) {\n const n = this._titles.length;\n const open = this._openIdx >= 0;\n switch (key) {\n case 'ArrowRight': open ? this._open(i + 1, null) : this._focusTitle((i + 1) % n); return true;\n case 'ArrowLeft': open ? this._open(i - 1, null) : this._focusTitle((i - 1 + n) % n); return true;\n case 'Home': open ? this._open(0, null) : this._focusTitle(0); return true;\n case 'End': open ? this._open(n - 1, null) : this._focusTitle(n - 1); return true;\n case 'ArrowDown': case 'Enter': case ' ':\n if (open && this._openIdx === i) this._focusIn(this._stack[0].menu, 'first');\n else this._open(i, 'first');\n return true;\n case 'ArrowUp':\n if (open && this._openIdx === i) this._focusIn(this._stack[0].menu, 'last');\n else this._open(i, 'last');\n return true;\n case 'Escape':\n if (open) this._closeAll();\n else this._exit();\n return true;\n default: return false;\n }\n }\n\n _itemKey(key, btn) {\n const level = this._levelOf(btn);\n if (level < 0) return false;\n const menu = this._stack[level].menu;\n const item = this._models.get(btn);\n const go = (b) => b?.focus({ preventScroll: true });\n // A submenu can be open while focus is still on the item it hangs\n // from (opened by the pointer, or with no row the keyboard can land\n // on). Left and Esc close that submenu first, keeping focus here.\n if ((key === 'ArrowLeft' || key === 'Escape') && this._stack[level + 1]?.parent === btn) {\n this._closeFrom(level + 1);\n return true;\n }\n // Moving within a menu closes any submenu open below it, as hovering\n // another item does, so no stale submenu stays next to the focus.\n if (key === 'ArrowDown' || key === 'ArrowUp' || key === 'Home' || key === 'End') {\n this._closeFrom(level + 1);\n }\n switch (key) {\n case 'ArrowDown': go(this._stepFrom(menu, btn, 1)); return true;\n case 'ArrowUp': go(this._stepFrom(menu, btn, -1)); return true;\n case 'Home': this._focusIn(menu, 'first'); return true;\n case 'End': this._focusIn(menu, 'last'); return true;\n case 'ArrowRight':\n if (item?.submenu != null && !this._isDisabled(item)) this._openSub(btn, 'first');\n else this._open(this._openIdx + 1, 'first');\n return true;\n case 'ArrowLeft':\n if (level > 0) this._closeFrom(level);\n else this._open(this._openIdx - 1, 'first');\n return true;\n case 'Enter': case ' ':\n this._activate(btn);\n return true;\n case 'Escape':\n if (level > 0) this._closeFrom(level);\n else this._closeAll();\n return true;\n default: return false;\n }\n }\n\n /** Alt on its own, and F10: armed on keydown, acted on here or on keyup. */\n _onDocKeyDown(e) {\n if (e.key === 'Alt') {\n this._altArmed = !e.ctrlKey && !e.metaKey && !e.shiftKey && !e.repeat;\n return;\n }\n this._altArmed = false;\n if (e.key === 'F10' && !e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey) {\n e.preventDefault();\n e.stopPropagation(); // F10 is the bar's while one is mounted\n this._toggle();\n }\n }\n\n _onDocKeyUp(e) {\n if (e.key !== 'Alt') return;\n const armed = this._altArmed;\n this._altArmed = false;\n if (!armed) return;\n e.preventDefault();\n this._toggle();\n }\n\n _onDocMouseDown(e) {\n this._altArmed = false;\n if (this._openIdx >= 0 && !this.el.contains(e.target)) this._deactivate();\n }\n\n _toggle() {\n if (this._active && (this._openIdx >= 0 || this.el.contains(this._doc.activeElement))) this._exit();\n else this.focus();\n }\n}\n\n// \u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction _resolve(items) {\n const v = typeof items === 'function' ? items() : items;\n return Array.isArray(v) ? v : [];\n}\n\nfunction _kind(item) {\n if (item.radio != null) return 'menuitemradio';\n if (typeof item.checked === 'boolean') return 'menuitemcheckbox';\n return 'menuitem';\n}\n\n/** A bad model is a boot error, not a menu that silently lacks a row. */\nfunction _validateMenus(menus) {\n if (!Array.isArray(menus) || !menus.length) {\n throw new TypeError('createMenuBar: `menus` must be a non-empty array');\n }\n const walk = (items, where) => {\n if (typeof items === 'function') return;\n if (!Array.isArray(items)) throw new TypeError(`createMenuBar: ${where} needs \\`items\\` (an array or a function)`);\n for (const it of items) {\n if (it?.separator) continue;\n if (it?.id == null || it?.label == null) {\n throw new TypeError(`createMenuBar: an item in ${where} needs an id and a label`);\n }\n if (it.submenu != null) walk(it.submenu, `\"${it.label}\"`);\n }\n };\n for (const m of menus) {\n if (m?.id == null || m?.label == null) throw new TypeError('createMenuBar: a menu needs an id and a label');\n walk(m.items, `menu \"${m.label}\"`);\n }\n}\n\n/** Fixed, so a bar inside an `overflow: hidden` chrome strip is not clipped;\n * kept on screen. `below` drops from a title, `right` flies out of an item. */\nfunction _place(menu, anchor, side) {\n const view = menu.ownerDocument.defaultView;\n const a = anchor.getBoundingClientRect();\n const r = menu.getBoundingClientRect();\n const vw = view?.innerWidth || 0;\n const vh = view?.innerHeight || 0;\n let left = side === 'below' ? a.left : a.right;\n let top = side === 'below' ? a.bottom : a.top;\n if (vw && left + r.width > vw) left = side === 'below' ? vw - r.width - 4 : a.left - r.width;\n if (vh && top + r.height > vh) top = Math.max(0, vh - r.height - 4);\n menu.style.left = `${Math.max(0, left)}px`;\n menu.style.top = `${Math.max(0, top)}px`;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Where the help modal gets its help.\n *\n * HelpModal used to `import { getHelpService, HELP_TOPICS } from './help_service.js'` \u2014\n * and help_service.js is 249 domain words of EcoAgent prose about sectors,\n * currencies, agents and markets. That import was the last framework -> domain\n * edge in the core: a generic modal reaching into one application's manual.\n *\n * The modal now asks this registry, and the application fills it. If nobody\n * fills it, the modal opens and says there is no help \u2014 which is the correct\n * behaviour for a library that ships no documentation about your app.\n *\n * @typedef {Object} HelpProvider\n * @property {() => string[]} getCategories\n * @property {(category: string) => Array<{id: string, title: string}>} getTopicsByCategory\n * @property {(id: string) => Promise<HelpTopic|null>} loadTopic\n * @property {(query: string) => Array<Object>} searchTopics\n * @property {Object} [markdownOptions] What the modal passes to\n * `renderMarkdown` for a markdown topic: `highlight`, `math`, `allowHtml`,\n * `inlineRules`, `blockRules`.\n *\n * @typedef {Object} HelpTopic\n * @property {string} title Text.\n * @property {string} [markdown] The article as markdown, rendered safe by\n * `renderMarkdown`: raw HTML is escaped and only http(s), mailto and #anchor\n * links go anywhere. Used when present.\n * @property {string} [html] The article as pre-rendered, TRUSTED HTML,\n * inserted verbatim. Never put unsanitised user content here.\n *\n * @typedef {Object.<string, {label: string, icon: string}>} HelpCategories\n * Keyed by category id; ITERATION ORDER IS DISPLAY ORDER.\n *\n * @typedef {{title: string, welcome: string}} HelpCopy\n * The landing heading. The modal used to hardcode \"EcoAgent Help\" and\n * \"Welcome to EcoAgent!\".\n */\n\n/** A provider with nothing in it. Not an error \u2014 just an app with no help. */\nconst EMPTY_PROVIDER = Object.freeze({\n getCategories: () => [],\n getTopicsByCategory: () => [],\n loadTopic: async () => null,\n searchTopics: () => [],\n});\n\nconst DEFAULT_COPY = Object.freeze({\n title: 'Help',\n welcome: 'Select a topic from the sidebar or browse the categories below.',\n});\n\nlet _provider = EMPTY_PROVIDER;\nlet _categories = Object.freeze({});\nlet _copy = DEFAULT_COPY;\n\n/**\n * @param {HelpProvider} provider\n * @param {HelpCategories} [categories] Display labels + icons, in display order.\n * @param {Partial<HelpCopy>} [copy] Landing heading and welcome line.\n */\nexport function setHelpProvider(provider, categories = {}, copy = {}) {\n _provider = provider ?? EMPTY_PROVIDER;\n _categories = Object.freeze({ ...categories });\n _copy = Object.freeze({ ...DEFAULT_COPY, ...copy });\n}\n\nexport function helpProvider() {\n return _provider;\n}\n\nexport function helpCategories() {\n return _categories;\n}\n\nexport function helpCopy() {\n return _copy;\n}\n", "/**\n * renderMarkdown \u2014 markdown to an HTML string, safe by default.\n *\n * A CommonMark-ish subset: ATX headings, paragraphs, emphasis, strong,\n * strikethrough, code spans, fenced code, block quotes, ordered and unordered\n * lists (nested), GFM pipe tables, thematic breaks, links, images, autolinks,\n * hard line breaks, backslash escapes and `$\u2026$` / `$$\u2026$$` math. Not in it:\n * setext headings, indented code blocks, reference links, raw HTML blocks.\n *\n * SAFE BY DEFAULT. Every character of the source is text unless markdown makes\n * it markup:\n *\n * - raw HTML is escaped. `options.allowHtml` names tags that may pass\n * through \u2014 the tag only, never its attributes, and never a tag that runs\n * or embeds anything (`script`, `iframe`, `svg`, \u2026 throw). It is empty by\n * default. An allowed tag left open is closed at the end of its paragraph,\n * and a closer with no opener is shown as text.\n * - a link goes out only to `http:`, `https:`, `mailto:` or a `#anchor`,\n * always with `rel=\"noopener noreferrer\"`. Any other target \u2014 a\n * `javascript:` URL, a `data:` URL, a relative path \u2014 renders the link's\n * text and no anchor. An image loads only from `http(s):` or a relative\n * path; otherwise its alt text is shown.\n *\n * What the CALLER returns is trusted: the highlighter's HTML, the math hook's\n * HTML and the extension rules' HTML go into the output as they are.\n *\n * WELL-FORMED WHILE STREAMING. Every element this renderer opens it closes,\n * so any prefix of a document \u2014 a chat reply arriving token by token \u2014 renders\n * to balanced HTML: an open code fence is closed at the end of the input, an\n * emphasis or a link whose closer has not arrived yet is text, and a table\n * whose delimiter row has not arrived yet is a paragraph.\n *\n * renderMarkdown(source, {\n * inline: false, // true: inline markup only, no blocks, no <p>\n * allowHtml: [], // e.g. ['kbd', 'br']\n * highlight: null, // (code, lang) => html | null (null: escaped)\n * math: undefined, // undefined: window.katex when present;\n * // false: `$` is text; or (tex, {display}) => html | null\n * inlineRules: [], // [{ pattern: /\\[\\[ref:(\\w+)\\]\\]/, render: (match, ctx) => html | null }]\n * blockRules: [], // [{ start: /^:::note/, end: /^:::$/, render: ({lines, match, closed}, ctx) => html | null }]\n * })\n *\n * A rule whose render answers null or undefined declines, and the text is\n * read as markdown. `ctx` carries `escape(text)` and `inline(text)` (render\n * markdown inline with the same options). An inline rule is tried at every\n * position outside a code span, before the built-in markup; a block rule's\n * `start` is tested against each line that begins a block, and the block runs\n * to the first later line matching `end` (inclusive) \u2014 or, with no `end`, is\n * that one line. A block whose `end` has not arrived is passed with\n * `closed: false` and runs to the end of the input.\n *\n * @module markdown\n */\n\n/** Tags `allowHtml` refuses: each runs script, embeds content or takes input. */\nconst NEVER_ALLOWED = new Set([\n 'script', 'style', 'iframe', 'frame', 'frameset', 'object', 'embed', 'applet',\n 'template', 'noscript', 'textarea', 'title', 'xmp', 'plaintext', 'noembed',\n 'svg', 'math', 'link', 'meta', 'base', 'form', 'input', 'button', 'select',\n 'option', 'video', 'audio', 'source', 'track', 'img', 'image', 'html',\n 'head', 'body', 'portal', 'dialog',\n]);\nconst VOID_TAGS = new Set(['br', 'hr', 'wbr']);\n\nconst LINK_URL = /^(?:https?:\\/\\/|mailto:|#)/i;\nconst IMAGE_URL = /^(?:https?:\\/\\/|\\/\\/|[^:/?#]*(?:[/?#]|$))/i;\nconst ENTITY = /^&(?:[a-zA-Z][a-zA-Z0-9]{1,31}|#\\d{1,7}|#[xX][0-9a-fA-F]{1,6});/;\nconst ASCII_PUNCT = /[!-/:-@[-`{-~]/;\n\nconst RE = {\n blank: /^[ \\t]*$/,\n heading: /^ {0,3}(#{1,6})(?:[ \\t]+(.*?))?(?:[ \\t]+#+)?[ \\t]*$/,\n hr: /^ {0,3}([-*_])(?:[ \\t]*\\1){2,}[ \\t]*$/,\n fence: /^( {0,3})(`{3,}|~{3,})[ \\t]*([^\\s`]*)[^`]*$/,\n quote: /^ {0,3}> ?/,\n item: /^( {0,3})([-*+]|\\d{1,9}[.)])(?=[ \\t]|$)([ \\t]*)(.*)$/,\n mathOpen: /^ {0,3}\\$\\$/,\n tableDelim: /^[ \\t]*\\|?[ \\t]*:?-+:?[ \\t]*(?:\\|[ \\t]*:?-+:?[ \\t]*)*\\|?[ \\t]*$/,\n};\n\n/**\n * Text for HTML: text content and attribute values alike.\n * @param {*} value\n * @returns {string}\n */\nfunction escapeHtml(value) {\n return String(value ?? '')\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\n/** The default math hook: window.katex, looked up per call, when it is there. */\nfunction katexMath(tex, { display }) {\n const katex = globalThis.window?.katex ?? globalThis.katex;\n if (typeof katex?.renderToString !== 'function') return null;\n try {\n return katex.renderToString(tex, { displayMode: display, throwOnError: false });\n } catch {\n return null;\n }\n}\n\nfunction compileOptions(options) {\n const allow = new Set();\n for (const raw of options.allowHtml ?? []) {\n const tag = String(raw).toLowerCase();\n if (!/^[a-z][a-z0-9-]*$/.test(tag)) {\n throw new TypeError(`renderMarkdown: allowHtml entry \"${raw}\" is not a tag name`);\n }\n if (NEVER_ALLOWED.has(tag)) {\n throw new TypeError(`renderMarkdown: <${tag}> cannot be allowed`);\n }\n allow.add(tag);\n }\n const fn = (value, name) => {\n if (value == null) return null;\n if (typeof value !== 'function') throw new TypeError(`renderMarkdown: ${name} must be a function`);\n return value;\n };\n const inlineRules = (options.inlineRules ?? []).map((rule, i) => {\n if (!(rule?.pattern instanceof RegExp) || typeof rule.render !== 'function') {\n throw new TypeError(`renderMarkdown: inlineRules[${i}] needs a RegExp pattern and a render function`);\n }\n // Sticky: the rule matches AT the position being read, never further on.\n const flags = rule.pattern.flags.replace(/[gy]/g, '') + 'y';\n return { pattern: new RegExp(rule.pattern.source, flags), render: rule.render };\n });\n const blockRules = (options.blockRules ?? []).map((rule, i) => {\n if (!(rule?.start instanceof RegExp) || typeof rule.render !== 'function'\n || (rule.end != null && !(rule.end instanceof RegExp))) {\n throw new TypeError(`renderMarkdown: blockRules[${i}] needs a RegExp start, an optional RegExp end and a render function`);\n }\n const plain = (re) => new RegExp(re.source, re.flags.replace(/[gy]/g, ''));\n return { start: plain(rule.start), end: rule.end ? plain(rule.end) : null, render: rule.render };\n });\n return {\n allow,\n highlight: fn(options.highlight, 'highlight'),\n math: options.math === undefined ? katexMath\n : options.math === false || options.math === null ? null\n : fn(options.math, 'math'),\n inlineRules,\n blockRules,\n };\n}\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// Inline\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n/** Index of the run of exactly `len` backticks closing a code span, or -1. */\nfunction findBacktickCloser(text, from, len) {\n let i = from;\n while (i < text.length) {\n const j = text.indexOf('`', i);\n if (j === -1) return -1;\n let k = j;\n while (text[k] === '`') k++;\n if (k - j === len) return j;\n i = k;\n }\n return -1;\n}\n\n/** Index after the `]` matching the `[` at `open`, or -1. */\nfunction findBracketClose(text, open) {\n let depth = 0;\n for (let i = open; i < text.length; i++) {\n const c = text[i];\n if (c === '\\\\') { i++; continue; }\n if (c === '`') {\n let k = i;\n while (text[k] === '`') k++;\n const close = findBacktickCloser(text, k, k - i);\n if (close !== -1) { i = close + (k - i) - 1; continue; }\n i = k - 1;\n continue;\n }\n if (c === '[') depth++;\n else if (c === ']' && --depth === 0) return i;\n }\n return -1;\n}\n\n/** `(url \"title\")` starting at `open`: {url, title, end} or null. */\nfunction parseDestination(text, open) {\n if (text[open] !== '(') return null;\n let i = open + 1;\n while (text[i] === ' ' || text[i] === '\\t' || text[i] === '\\n') i++;\n let url = '';\n if (text[i] === '<') {\n const close = text.indexOf('>', i);\n if (close === -1 || /[\\n<]/.test(text.slice(i + 1, close))) return null;\n url = text.slice(i + 1, close);\n i = close + 1;\n } else {\n let depth = 0;\n const start = i;\n for (; i < text.length; i++) {\n const c = text[i];\n if (c === '\\\\' && i + 1 < text.length) { i++; continue; }\n if (/\\s/.test(c)) break;\n if (c === '(') depth++;\n else if (c === ')') { if (depth === 0) break; depth--; }\n }\n url = text.slice(start, i);\n }\n while (text[i] === ' ' || text[i] === '\\t' || text[i] === '\\n') i++;\n let title = null;\n const q = text[i];\n if (q === '\"' || q === \"'\" || q === '(') {\n const closeQ = q === '(' ? ')' : q;\n const close = text.indexOf(closeQ, i + 1);\n if (close === -1) return null;\n title = text.slice(i + 1, close);\n i = close + 1;\n while (text[i] === ' ' || text[i] === '\\t' || text[i] === '\\n') i++;\n }\n if (text[i] !== ')') return null;\n return { url: url.replace(/\\\\([!-/:-@[-`{-~])/g, '$1'), title, end: i + 1 };\n}\n\nconst isSpace = (c) => c === undefined || /\\s/.test(c);\nconst isWord = (c) => c !== undefined && /[\\p{L}\\p{N}]/u.test(c);\n\n/**\n * The closer of an emphasis run of `len` \u00D7 `ch` opened at `from`: the index\n * of a run of exactly `len` that is not preceded by whitespace (and, for `_`,\n * not followed by a word character), or -1.\n */\nfunction findEmphasisCloser(text, from, ch, len) {\n let i = from;\n while (i < text.length) {\n const c = text[i];\n if (c === '\\\\') { i += 2; continue; }\n if (c === '`') {\n let k = i;\n while (text[k] === '`') k++;\n const close = findBacktickCloser(text, k, k - i);\n i = close === -1 ? k : close + (k - i);\n continue;\n }\n if (c !== ch) { i++; continue; }\n let k = i;\n while (text[k] === ch) k++;\n if (k - i === len && i > from && !isSpace(text[i - 1])\n && !(ch === '_' && isWord(text[k]))) return i;\n i = k;\n }\n return -1;\n}\n\n/** `$\u2026$` or `$$\u2026$$` at `i`: {tex, display, end} or null. */\nfunction parseInlineMath(text, i) {\n if (text[i + 1] === '$') {\n const close = text.indexOf('$$', i + 2);\n if (close === -1 || close === i + 2) return null;\n return { tex: text.slice(i + 2, close), display: true, end: close + 2 };\n }\n if (isSpace(text[i + 1])) return null;\n for (let j = i + 1; j < text.length; j++) {\n if (text[j] === '\\\\') { j++; continue; }\n if (text[j] === '\\n' && text[j + 1] === '\\n') return null;\n if (text[j] === '$' && j > i + 1 && !isSpace(text[j - 1]) && !/\\d/.test(text[j + 1] ?? '')) {\n return { tex: text.slice(i + 1, j), display: false, end: j + 1 };\n }\n }\n return null;\n}\n\nfunction renderInline(text, ctx, { inLink = false } = {}) {\n const { opts } = ctx;\n let out = '';\n let plain = '';\n const flush = () => { out += escapeHtml(plain); plain = ''; };\n const emit = (html) => { flush(); out += html; };\n const open = []; // allowed raw-HTML tags open in this span\n\n let i = 0;\n while (i < text.length) {\n const c = text[i];\n\n // Backslash: an escaped punctuation character, or a hard break.\n if (c === '\\\\') {\n const n = text[i + 1];\n if (n === '\\n') { emit('<br>\\n'); i += 2; continue; }\n if (n !== undefined && ASCII_PUNCT.test(n)) { plain += n; i += 2; continue; }\n plain += c; i++; continue;\n }\n\n // Code span: wins over everything, including the caller's rules.\n if (c === '`') {\n let k = i;\n while (text[k] === '`') k++;\n const close = findBacktickCloser(text, k, k - i);\n if (close === -1) { plain += text.slice(i, k); i = k; continue; }\n let code = text.slice(k, close).replace(/\\n/g, ' ');\n if (code.length > 2 && code[0] === ' ' && code.at(-1) === ' ' && code.trim()) code = code.slice(1, -1);\n emit(`<code>${escapeHtml(code)}</code>`);\n i = close + (k - i);\n continue;\n }\n\n // The caller's rules.\n let ruled = false;\n for (const rule of opts.inlineRules) {\n rule.pattern.lastIndex = i;\n const m = rule.pattern.exec(text);\n if (!m || !m[0].length) continue;\n const html = rule.render(m, ctx.api);\n if (html == null) continue;\n emit(String(html));\n i += m[0].length;\n ruled = true;\n break;\n }\n if (ruled) continue;\n\n // Hard break: two or more spaces before a newline.\n if (c === '\\n') {\n if (/ {2,}$/.test(plain)) { plain = plain.replace(/ +$/, ''); emit('<br>\\n'); }\n else { plain = plain.replace(/ +$/, ''); plain += '\\n'; }\n i++;\n continue;\n }\n\n if (c === '&') {\n const m = ENTITY.exec(text.slice(i, i + 40));\n if (m) { emit(m[0]); i += m[0].length; continue; }\n }\n\n if (c === '$' && opts.math) {\n const m = parseInlineMath(text, i);\n if (m) {\n const html = opts.math(m.tex, { display: m.display });\n if (html == null) plain += text.slice(i, m.end);\n else emit(String(html));\n i = m.end;\n continue;\n }\n }\n\n // Images and links.\n if ((c === '!' && text[i + 1] === '[') || (c === '[' && !inLink)) {\n const bracket = c === '!' ? i + 1 : i;\n const close = findBracketClose(text, bracket);\n const dest = close === -1 ? null : parseDestination(text, close + 1);\n if (dest) {\n const label = text.slice(bracket + 1, close);\n const title = dest.title == null ? '' : ` title=\"${escapeHtml(dest.title)}\"`;\n if (c === '!') {\n if (IMAGE_URL.test(dest.url) && !/[\\s\\x00-\\x1f]/.test(dest.url)) {\n emit(`<img src=\"${escapeHtml(dest.url)}\" alt=\"${escapeHtml(label)}\"${title}>`);\n } else {\n plain += label;\n }\n } else if (LINK_URL.test(dest.url) && !/[\\s\\x00-\\x1f]/.test(dest.url)) {\n emit(`<a href=\"${escapeHtml(dest.url)}\"${title} rel=\"noopener noreferrer\">`\n + `${renderInline(label, ctx, { inLink: true })}</a>`);\n } else {\n // Inert: the text the reader was shown, and nowhere to go.\n emit(renderInline(label, ctx, { inLink: true }));\n }\n i = dest.end;\n continue;\n }\n }\n\n if (c === '<') {\n const auto = /^<((?:https?:\\/\\/|mailto:)[^\\s<>]+)>/i.exec(text.slice(i, i + 2048));\n if (auto && !inLink) {\n emit(`<a href=\"${escapeHtml(auto[1])}\" rel=\"noopener noreferrer\">${escapeHtml(auto[1])}</a>`);\n i += auto[0].length;\n continue;\n }\n const tag = opts.allow.size ? /^<(\\/?)([A-Za-z][A-Za-z0-9-]*)(?:\\s[^<>]*)?\\/?>/.exec(text.slice(i, i + 1024)) : null;\n const name = tag?.[2].toLowerCase();\n if (tag && opts.allow.has(name)) {\n if (VOID_TAGS.has(name)) {\n if (!tag[1]) emit(`<${name}>`);\n i += tag[0].length;\n continue;\n }\n if (!tag[1]) {\n emit(`<${name}>`);\n open.push(name);\n i += tag[0].length;\n continue;\n }\n const at = open.lastIndexOf(name);\n if (at !== -1) {\n while (open.length > at) emit(`</${open.pop()}>`);\n i += tag[0].length;\n continue;\n }\n }\n }\n\n // Emphasis, strong, strikethrough.\n if (c === '*' || c === '_' || c === '~') {\n let k = i;\n while (text[k] === c) k++;\n const run = k - i;\n const opens = !isSpace(text[k]) && !(c === '_' && isWord(text[i - 1]));\n const len = c === '~' ? (run === 2 ? 2 : 0) : run <= 3 ? run : 0;\n if (opens && len) {\n const close = findEmphasisCloser(text, k, c, len);\n if (close !== -1) {\n const inner = renderInline(text.slice(k, close), ctx, { inLink });\n const wrapped = c === '~' ? `<del>${inner}</del>`\n : len === 1 ? `<em>${inner}</em>`\n : len === 2 ? `<strong>${inner}</strong>`\n : `<strong><em>${inner}</em></strong>`;\n emit(wrapped);\n i = close + len;\n continue;\n }\n }\n plain += text.slice(i, k);\n i = k;\n continue;\n }\n\n plain += c;\n i++;\n }\n flush();\n while (open.length) out += `</${open.pop()}>`;\n return out;\n}\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// Blocks\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n/** A pipe-table row's cells: unescaped `|` splits, outside code spans. */\nfunction splitRow(line) {\n let s = line.trim();\n if (s.startsWith('|')) s = s.slice(1);\n if (s.endsWith('|') && !s.endsWith('\\\\|')) s = s.slice(0, -1);\n const cells = [];\n let cell = '';\n let inCode = 0;\n for (let i = 0; i < s.length; i++) {\n const c = s[i];\n if (c === '\\\\' && s[i + 1] === '|') { cell += '|'; i++; continue; }\n if (c === '`') {\n let k = i;\n while (s[k] === '`') k++;\n const len = k - i;\n if (inCode === len) inCode = 0;\n else if (!inCode && findBacktickCloser(s, k, len) !== -1) inCode = len;\n cell += s.slice(i, k);\n i = k - 1;\n continue;\n }\n if (c === '|' && !inCode) { cells.push(cell.trim()); cell = ''; continue; }\n cell += c;\n }\n cells.push(cell.trim());\n return cells;\n}\n\nfunction isTableStart(lines, i) {\n if (!lines[i].includes('|') || i + 1 >= lines.length\n || !lines[i + 1].includes('|') || !RE.tableDelim.test(lines[i + 1])) return false;\n return splitRow(lines[i]).length === splitRow(lines[i + 1]).length;\n}\n\nfunction blockRuleAt(line, ctx) {\n for (const rule of ctx.opts.blockRules) {\n const match = rule.start.exec(line);\n if (match) return { rule, match };\n }\n return null;\n}\n\n/**\n * A `$$` line opens a display-math block when the rest of it is empty or the\n * whole formula (`$$x$$`); `$$x$$ and more` is a paragraph with inline math.\n */\nfunction isMathBlockStart(line, ctx) {\n if (!ctx.opts.math || !RE.mathOpen.test(line)) return false;\n const rest = line.replace(RE.mathOpen, '');\n return !rest.includes('$$') || /^[^$]*\\$\\$[ \\t]*$/.test(rest) && !/^[ \\t]*\\$\\$/.test(rest);\n}\n\n/** Does `lines[i]` begin a block that interrupts a paragraph? */\nfunction startsBlock(lines, i, ctx) {\n const line = lines[i];\n if (RE.heading.test(line) || RE.hr.test(line) || RE.fence.test(line) || RE.quote.test(line)) return true;\n if (isMathBlockStart(line, ctx)) return true;\n const item = RE.item.exec(line);\n if (item && item[4].trim() && (!/\\d/.test(item[2]) || /^1[.)]$/.test(item[2]))) return true;\n if (blockRuleAt(line, ctx)) return true;\n return isTableStart(lines, i);\n}\n\nfunction renderCode(lines, i, ctx) {\n const [, indent, fence, lang] = RE.fence.exec(lines[i]);\n const body = [];\n const close = new RegExp(`^ {0,3}${fence[0] === '`' ? '`' : '~'}{${fence.length},}[ \\\\t]*$`);\n let j = i + 1;\n for (; j < lines.length; j++) {\n if (close.test(lines[j])) { j++; break; }\n let line = lines[j];\n for (let n = 0; n < indent.length && line[0] === ' '; n++) line = line.slice(1);\n body.push(line);\n }\n const code = body.length ? body.join('\\n') + '\\n' : '';\n const highlighted = ctx.opts.highlight ? ctx.opts.highlight(code, lang) : null;\n const cls = lang ? ` class=\"language-${escapeHtml(lang)}\"` : '';\n return { html: `<pre><code${cls}>${highlighted == null ? escapeHtml(code) : String(highlighted)}</code></pre>\\n`, next: j };\n}\n\nfunction renderMathBlock(lines, i, ctx) {\n const first = lines[i].replace(/^ {0,3}\\$\\$/, '');\n const body = [];\n let j = i;\n let closed = false;\n if (/\\$\\$[ \\t]*$/.test(first)) {\n body.push(first.replace(/\\$\\$[ \\t]*$/, ''));\n closed = true;\n j = i + 1;\n } else {\n if (first.trim()) body.push(first);\n for (j = i + 1; j < lines.length; j++) {\n if (/\\$\\$[ \\t]*$/.test(lines[j])) {\n const last = lines[j].replace(/\\$\\$[ \\t]*$/, '');\n if (last.trim()) body.push(last);\n closed = true;\n j++;\n break;\n }\n body.push(lines[j]);\n }\n }\n const tex = body.join('\\n').trim();\n const html = closed && tex ? ctx.opts.math(tex, { display: true }) : null;\n if (html != null) return { html: `<div class=\"twm-md-math\">${String(html)}</div>\\n`, next: j };\n return { html: `<p>${escapeHtml(lines.slice(i, j).join('\\n'))}</p>\\n`, next: j };\n}\n\nfunction renderTable(lines, i, ctx) {\n const head = splitRow(lines[i]);\n const align = splitRow(lines[i + 1]).map((d) => {\n const l = d.startsWith(':');\n const r = d.endsWith(':');\n return l && r ? 'center' : r ? 'right' : l ? 'left' : null;\n });\n const cell = (tag, text, n) => {\n const style = align[n] ? ` style=\"text-align: ${align[n]}\"` : '';\n return `<${tag}${style}>${renderInline(text ?? '', ctx)}</${tag}>`;\n };\n let html = '<table>\\n<thead>\\n<tr>' + head.map((t, n) => cell('th', t, n)).join('') + '</tr>\\n</thead>\\n';\n let j = i + 2;\n const rows = [];\n for (; j < lines.length; j++) {\n if (RE.blank.test(lines[j]) || startsBlock(lines, j, ctx)) break;\n const cells = splitRow(lines[j]);\n rows.push('<tr>' + head.map((_, n) => cell('td', cells[n], n)).join('') + '</tr>\\n');\n }\n if (rows.length) html += '<tbody>\\n' + rows.join('') + '</tbody>\\n';\n return { html: html + '</table>\\n', next: j };\n}\n\nfunction renderList(lines, i, ctx) {\n const first = RE.item.exec(lines[i]);\n const ordered = /\\d/.test(first[2]);\n const delim = ordered ? first[2].at(-1) : first[2];\n const sameList = (m) => m && (ordered ? /\\d/.test(m[2]) && m[2].at(-1) === delim : m[2] === delim);\n const items = [];\n let loose = false;\n let j = i;\n while (j < lines.length) {\n const m = RE.item.exec(lines[j]);\n if (!sameList(m) || (items.length && m[1].length >= items.at(-1).indent)) break;\n const gap = m[3].length >= 5 || !m[4] ? 1 : m[3].length;\n const indent = m[1].length + m[2].length + gap;\n const item = { indent, lines: [m[3].length >= 5 ? ' '.repeat(m[3].length - 1) + m[4] : m[4]] };\n items.push(item);\n j++;\n let pendingBlank = 0;\n while (j < lines.length) {\n const line = lines[j];\n if (RE.blank.test(line)) { pendingBlank++; j++; continue; }\n const lead = line.match(/^ */)[0].length;\n if (lead >= indent) {\n for (; pendingBlank; pendingBlank--) item.lines.push('');\n item.lines.push(line.slice(indent));\n j++;\n continue;\n }\n const next = RE.item.exec(line);\n if (pendingBlank === 0 && !next && !startsBlock(lines, j, ctx)\n && !RE.blank.test(item.lines.at(-1) ?? '')) {\n item.lines.push(line.trim()); // lazy paragraph continuation\n j++;\n continue;\n }\n break;\n }\n if (pendingBlank) {\n const next = RE.item.exec(lines[j] ?? '');\n if (j < lines.length && sameList(next) && next[1].length < indent) loose = true;\n else { j -= pendingBlank; break; }\n }\n if (item.lines.slice(0, -1).some((l) => RE.blank.test(l)) && item.lines.length > 1) {\n // A blank line between two of the item's own blocks.\n const inner = item.lines.join('\\n');\n if (!/^(`{3,}|~{3,})/m.test(inner)) loose = true;\n }\n }\n const tag = ordered ? 'ol' : 'ul';\n const start = ordered ? parseInt(first[2], 10) : 1;\n let html = start !== 1 ? `<${tag} start=\"${start}\">\\n` : `<${tag}>\\n`;\n for (const item of items) {\n const body = renderBlocks(item.lines, ctx, { tight: !loose });\n html += `<li>${body.replace(/\\n$/, '')}</li>\\n`;\n }\n return { html: html + `</${tag}>\\n`, next: j };\n}\n\nfunction renderBlocks(lines, ctx, { tight = false } = {}) {\n let out = '';\n let i = 0;\n while (i < lines.length) {\n const line = lines[i];\n if (RE.blank.test(line)) { i++; continue; }\n\n const ruled = blockRuleAt(line, ctx);\n if (ruled) {\n let j = i + 1;\n let closed = true;\n if (ruled.rule.end) {\n closed = false;\n for (; j < lines.length; j++) {\n if (ruled.rule.end.test(lines[j])) { closed = true; j++; break; }\n }\n }\n const html = ruled.rule.render({ lines: lines.slice(i, j), match: ruled.match, closed }, ctx.api);\n if (html != null) {\n out += String(html) + '\\n';\n i = j;\n continue;\n }\n }\n\n let block = null;\n if (RE.fence.test(line)) block = renderCode(lines, i, ctx);\n else if (isMathBlockStart(line, ctx)) block = renderMathBlock(lines, i, ctx);\n else if (RE.heading.test(line)) {\n const [, hashes, text = ''] = RE.heading.exec(line);\n const n = hashes.length;\n block = { html: `<h${n}>${renderInline(text.trim(), ctx)}</h${n}>\\n`, next: i + 1 };\n } else if (RE.hr.test(line)) block = { html: '<hr>\\n', next: i + 1 };\n else if (RE.quote.test(line)) {\n const inner = [];\n let j = i;\n for (; j < lines.length && RE.quote.test(lines[j]); j++) inner.push(lines[j].replace(RE.quote, ''));\n block = { html: `<blockquote>\\n${renderBlocks(inner, ctx)}</blockquote>\\n`, next: j };\n } else if (RE.item.test(line)) block = renderList(lines, i, ctx);\n else if (isTableStart(lines, i)) block = renderTable(lines, i, ctx);\n\n if (block) {\n out += block.html;\n i = block.next;\n continue;\n }\n\n const para = [line];\n let j = i + 1;\n for (; j < lines.length && !RE.blank.test(lines[j]) && !startsBlock(lines, j, ctx); j++) para.push(lines[j]);\n const inline = renderInline(para.map((l, n) => (n === 0 ? l.replace(/^[ \\t]+/, '') : l.trimStart()))\n .join('\\n').replace(/[ \\t]+$/, ''), ctx);\n out += tight ? `${inline}\\n` : `<p>${inline}</p>\\n`;\n i = j;\n }\n return out;\n}\n\n/**\n * Render markdown to an HTML string. See the module comment for the subset,\n * the safety rules and the options.\n *\n * @param {string} source\n * @param {Object} [options]\n * @param {boolean} [options.inline=false] - Inline markup only: no blocks, no `<p>`.\n * @param {string[]} [options.allowHtml=[]] - Raw HTML tags that pass through, without attributes.\n * @param {(code: string, lang: string) => (string|null)} [options.highlight] - Fenced code's HTML.\n * @param {false|null|((tex: string, o: {display: boolean}) => (string|null))} [options.math]\n * Omitted: `window.katex` when present. `false`: `$` is plain text.\n * @param {Array<{pattern: RegExp, render: (match: RegExpExecArray, ctx: Object) => (string|null)}>} [options.inlineRules]\n * @param {Array<{start: RegExp, end?: RegExp, render: (block: {lines: string[], match: RegExpExecArray, closed: boolean}, ctx: Object) => (string|null)}>} [options.blockRules]\n * @returns {string}\n */\nexport function renderMarkdown(source, options = {}) {\n const ctx = { opts: compileOptions(options ?? {}) };\n ctx.api = Object.freeze({\n escape: escapeHtml,\n inline: (text) => renderInline(String(text ?? ''), ctx),\n });\n const text = String(source ?? '').replace(/\\r\\n?/g, '\\n').replace(/\\u0000/g, '\uFFFD');\n if (options?.inline) return renderInline(text, ctx);\n return renderBlocks(text.split('\\n'), ctx);\n}\n", "/**\n * document_outline.js \u2014 A LONG DOCUMENT'S OUTLINE: its sections listed and\n * numbered, the one in view marked while the document scrolls, and a click\n * that goes to a section. (0.17.0)\n *\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 1 Introduction \u2502\n * \u2502 1.1 Scope \u2502 \u2190 the section in view\n * \u2502 1.2 Terms \u2502\n * \u2502 2 Method \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n *\n * const outline = createDocumentOutline(sidebarEl, {\n * entries: [{ id: 'intro', level: 1, label: 'Introduction' }, \u2026],\n * numbering: true,\n * scrollContainer: articleEl,\n * resolveTarget: (entry) => articleEl.querySelector(`[data-section=\"${entry.id}\"]`),\n * onSelect: (id) => { \u2026 },\n * });\n *\n * Where the entries come from (headings in markup, cells in a notebook, a\n * server's table of contents) is the embedder's business. The outline is told\n * `{id, level, label}` and, through `resolveTarget`, which element in the\n * scroll container each one stands for.\n *\n * NUMBERING (`numbering: true`) is hierarchical: levels 1, 2, 2, 1 are numbered\n * 1, 1.1, 1.2, 2. An entry sits one deeper than the nearest entry above it of\n * a lower level, so the shallowest level is depth 1 and a skipped level is one\n * step, not two (1, 3, 3, 2 is 1, 1.1, 1.2, 1.3, never 1.0.1); and nothing goes\n * deeper than `maxDepth` \u2014 a deeper entry is listed, indented and numbered at\n * `maxDepth`.\n *\n * THE SCROLL-SPY. With a `scrollContainer`, every resolved target is watched by\n * an IntersectionObserver rooted at that container, with `rootMargin` (default\n * `'0px 0px -70% 0px'`: the top 30% of the container is \"in view\"). Of the\n * targets in view, the one listed FIRST is the active section \u2014 the topmost\n * visible one. When none is in view the active section stays what it was, so\n * the long body of a section keeps its heading marked. An entry whose target\n * cannot be resolved is listed, but it is never watched and never marked\n * active, by the spy or by `setActive`.\n *\n * A CLICK keeps its entry active. A click on an entry marks it at once, scrolls\n * its target into view (unless `scrollOnSelect: false`, when `onSelect` does\n * the scrolling) and calls `onSelect(id, entry)`. A smooth scroll passes over\n * every section between here and there, so the spy is SUPPRESSED while it runs:\n * it resumes on the container's `scrollend`, or after `scrollEndTimeout` ms\n * (default 1000) when no `scrollend` comes \u2014 an engine without the event, or a\n * target that was already in place and so never scrolled.\n *\n * `refresh()` resolves the targets again (the document re-rendered);\n * `setEntries(entries)` replaces the list. `dispose()` disconnects the observer,\n * clears the timer and takes the outline off the page.\n */\n\n/**\n * @typedef {Object} OutlineEntry\n * @property {string} id - Unique among the entries.\n * @property {number} [level=1] - 1 for a top-level section, 2 under it, \u2026\n * @property {string} label - The entry's words, drawn as text (never markup).\n */\n\n/**\n * @typedef {Object} DocumentOutlineConfig\n * @property {OutlineEntry[]} [entries]\n * @property {boolean} [numbering=false] - Hierarchical numbers before the labels.\n * @property {number} [maxDepth=3] - The deepest indentation and numbering depth.\n * @property {Function} [onSelect] - `(id, entry) => void`, on a click on an entry.\n * @property {boolean} [scrollOnSelect=true] - A click scrolls the entry's target\n * into view (`scrollIntoView({block: 'start', behavior: scrollBehavior})`).\n * @property {ScrollBehavior} [scrollBehavior='smooth']\n * @property {HTMLElement|null} [scrollContainer] - The element that scrolls the\n * document; the observer's root. Without it there is no scroll-spy.\n * @property {Function} [resolveTarget] - `(entry, scrollContainer) => Element|null`.\n * Defaults to the element inside the container whose `id` is the entry's id.\n * @property {string} [rootMargin='0px 0px -70% 0px']\n * @property {number} [scrollEndTimeout=1000] - ms before a click's suppression\n * lifts when no `scrollend` arrives.\n * @property {string|Node|Function|null} [emptyState='No headings'] - Shown with no entries.\n * @property {string} [label='Outline'] - The navigation's accessible name.\n * @property {string} [className] - Added to the root.\n * @property {Function} [IntersectionObserver] - The observer class; defaults to\n * the global one. Without either there is no scroll-spy.\n */\n\nexport class DocumentOutline {\n /**\n * @param {HTMLElement|null} host appended to, if given\n * @param {DocumentOutlineConfig} [config]\n */\n constructor(host, config = {}) {\n this.config = {\n entries: [],\n numbering: false,\n maxDepth: 3,\n onSelect: null,\n scrollOnSelect: true,\n scrollBehavior: 'smooth',\n scrollContainer: null,\n resolveTarget: null,\n rootMargin: '0px 0px -70% 0px',\n scrollEndTimeout: 1000,\n emptyState: 'No headings',\n label: 'Outline',\n className: null,\n IntersectionObserver: null,\n ...config,\n };\n this._entries = [];\n this._rows = []; // [{id, entry, depth, number, li, target}] in list order\n this._byId = new Map(); // id \u2192 row\n this._byTarget = new Map(); // target element \u2192 row\n this._inView = new Set(); // rows whose target intersects\n this._activeId = null;\n this._listeners = new Set();\n this._observer = null;\n this._suppressed = false;\n this._timer = null;\n this._disposed = false;\n\n const root = document.createElement('nav');\n root.className = 'twm-doc-outline'\n + (this.config.className ? ` ${this.config.className}` : '');\n if (this.config.label) root.setAttribute('aria-label', this.config.label);\n const list = document.createElement('ol');\n list.className = 'twm-doc-outline__items';\n root.appendChild(list);\n this.element = root;\n this.listElement = list;\n\n this._onClick = (ev) => this._click(ev);\n this._onScrollEnd = () => this._resume();\n list.addEventListener('click', this._onClick);\n this.config.scrollContainer?.addEventListener?.('scrollend', this._onScrollEnd);\n\n this._setEntries(this.config.entries);\n if (host) host.appendChild(root);\n }\n\n // \u2500\u2500 public \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** Replace the entries. The active entry stays active if it is still\n * listed and resolved; otherwise there is none. */\n setEntries(entries) {\n if (this._disposed) return;\n this._setEntries(entries);\n }\n\n /** The entries, as last given. */\n getEntries() {\n return this._entries.slice();\n }\n\n /** Resolve every target again and watch the new ones: the document under\n * the outline was re-rendered. */\n refresh() {\n if (this._disposed) return;\n this._observe();\n this._keepActive();\n }\n\n /** Mark an entry active (`null` for none). An id that is not listed, or\n * whose target is not resolved, is refused: returns false. */\n setActive(id) {\n if (this._disposed) return false;\n if (id == null) { this._activate(null); return true; }\n const row = this._byId.get(String(id));\n if (!row?.target) return false;\n this._activate(row.id);\n return true;\n }\n\n /** The active entry's id, or null. */\n getActive() {\n return this._activeId;\n }\n\n /** `fn(id, entry)` on every change of the active entry (`(null, null)` when\n * none). Returns the function that unsubscribes. */\n onActiveChange(fn) {\n if (typeof fn !== 'function' || this._disposed) return () => {};\n this._listeners.add(fn);\n return () => this._listeners.delete(fn);\n }\n\n /** The `<li>` drawn for an id, or null. */\n getItem(id) {\n return this._byId.get(String(id))?.li || null;\n }\n\n dispose() {\n if (this._disposed) return;\n this._disposed = true;\n this._observer?.disconnect();\n this._observer = null;\n this._clearTimer();\n this._suppressed = false;\n this.config.scrollContainer?.removeEventListener?.('scrollend', this._onScrollEnd);\n this.listElement.removeEventListener('click', this._onClick);\n this._listeners.clear();\n this._byId.clear();\n this._byTarget.clear();\n this._inView.clear();\n this._rows = [];\n this.element.remove();\n }\n\n // \u2500\u2500 drawing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n _setEntries(entries) {\n this._entries = Array.isArray(entries) ? entries.slice() : [];\n this._rows = numberEntries(this._entries, this.config.maxDepth);\n this._byId = new Map(this._rows.map((row) => [row.id, row]));\n this._draw();\n this._observe();\n this._keepActive();\n }\n\n /** The active entry survives a redraw only while it is listed and resolved. */\n _keepActive() {\n if (this._activeId !== null && !this._byId.get(this._activeId)?.target) this._activate(null);\n else this._paint();\n }\n\n _draw() {\n const list = this.listElement;\n list.replaceChildren();\n this.element.querySelector(':scope > .twm-doc-outline__empty')?.remove();\n this.element.classList.toggle('twm-doc-outline--empty', this._rows.length === 0);\n this.element.classList.toggle('twm-doc-outline--numbered', !!this.config.numbering);\n if (!this._rows.length) { this._drawEmpty(); return; }\n for (const row of this._rows) {\n const li = document.createElement('li');\n li.className = `twm-doc-outline__item twm-doc-outline__item--level-${row.depth}`;\n li.style.setProperty('--twm-doc-outline-depth', String(row.depth - 1));\n const button = document.createElement('button');\n button.type = 'button';\n button.className = 'twm-doc-outline__link';\n if (this.config.numbering) {\n const num = document.createElement('span');\n num.className = 'twm-doc-outline__number';\n num.textContent = row.number;\n button.appendChild(num);\n }\n const label = document.createElement('span');\n label.className = 'twm-doc-outline__label';\n label.textContent = String(row.entry.label ?? '');\n button.appendChild(label);\n button.title = (this.config.numbering ? `${row.number} ` : '') + label.textContent;\n li.appendChild(button);\n row.li = li;\n list.appendChild(li);\n }\n }\n\n _drawEmpty() {\n let content = this.config.emptyState;\n if (typeof content === 'function') content = content();\n if (content == null || content === false || content === '') return;\n const p = document.createElement('p');\n p.className = 'twm-doc-outline__empty';\n if (typeof Node !== 'undefined' && content instanceof Node) p.appendChild(content);\n else p.textContent = String(content);\n this.element.appendChild(p);\n }\n\n _paint() {\n for (const row of this._rows) {\n if (!row.li) continue;\n const active = row.id === this._activeId;\n row.li.classList.toggle('twm-doc-outline__item--active', active);\n row.li.classList.toggle('twm-doc-outline__item--unresolved', !row.target);\n const button = row.li.firstChild;\n if (active) button.setAttribute('aria-current', 'location');\n else button.removeAttribute('aria-current');\n }\n }\n\n _activate(id) {\n const next = id ?? null;\n if (next === this._activeId) { this._paint(); return; }\n this._activeId = next;\n this._paint();\n const entry = next === null ? null : this._byId.get(next)?.entry ?? null;\n for (const fn of [...this._listeners]) fn(next, entry);\n }\n\n // \u2500\u2500 the scroll-spy \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n _resolve(entry) {\n const container = this.config.scrollContainer;\n if (typeof this.config.resolveTarget === 'function') {\n return this.config.resolveTarget(entry, container) || null;\n }\n if (!container) return null;\n const id = String(entry.id);\n for (const el of container.querySelectorAll('[id]')) if (el.id === id) return el;\n return null;\n }\n\n _observe() {\n this._observer?.disconnect();\n this._byTarget.clear();\n this._inView.clear();\n for (const row of this._rows) row.target = this._resolve(row.entry);\n for (const row of this._rows) {\n if (row.target && !this._byTarget.has(row.target)) this._byTarget.set(row.target, row);\n }\n const container = this.config.scrollContainer;\n const IO = this.config.IntersectionObserver || globalThis.IntersectionObserver;\n if (!container || typeof IO !== 'function') return;\n if (!this._observer) {\n this._observer = new IO((records) => this._intersect(records), {\n root: container,\n rootMargin: this.config.rootMargin,\n threshold: 0,\n });\n }\n for (const target of this._byTarget.keys()) this._observer.observe(target);\n }\n\n _intersect(records) {\n if (this._disposed) return;\n for (const rec of records) {\n const row = this._byTarget.get(rec.target);\n if (!row) continue;\n if (rec.isIntersecting) this._inView.add(row);\n else this._inView.delete(row);\n }\n if (this._suppressed) return;\n // The topmost section in view: the first listed.\n const top = this._rows.find((row) => this._inView.has(row));\n if (top) this._activate(top.id);\n }\n\n _click(ev) {\n const li = ev.target?.closest?.('.twm-doc-outline__item');\n if (!li || !this.listElement.contains(li)) return;\n const row = this._rows.find((r) => r.li === li);\n if (!row) return;\n if (row.target) {\n this._activate(row.id);\n this._suppress();\n if (this.config.scrollOnSelect && typeof row.target.scrollIntoView === 'function') {\n row.target.scrollIntoView({ block: 'start', behavior: this.config.scrollBehavior });\n }\n }\n this.config.onSelect?.(row.id, row.entry);\n }\n\n _suppress() {\n this._suppressed = true;\n this._clearTimer();\n this._timer = setTimeout(() => this._resume(), this.config.scrollEndTimeout);\n }\n\n _resume() {\n this._clearTimer();\n this._suppressed = false;\n }\n\n _clearTimer() {\n if (this._timer !== null) clearTimeout(this._timer);\n this._timer = null;\n }\n}\n\n/**\n * Build a document outline, append it to `host` (if given) and draw it.\n *\n * @param {HTMLElement|null} host\n * @param {DocumentOutlineConfig} [config]\n * @returns {DocumentOutline}\n */\nexport function createDocumentOutline(host, config = {}) {\n return new DocumentOutline(host, config);\n}\n\n/**\n * Each entry's row: its id as a string, its depth and its hierarchical number.\n * An entry's depth is one more than the number of open sections of a lower\n * level above it, so the shallowest level is depth 1 and a skipped level is\n * one deeper, never two; then at most `maxDepth`.\n */\nfunction numberEntries(entries, maxDepth) {\n const cap = Math.max(1, Math.floor(Number(maxDepth) || 3));\n const open = []; // the levels of the sections this entry may sit under\n const counters = [];\n return entries.map((entry) => {\n const level = Math.max(1, Math.floor(Number(entry?.level) || 1));\n while (open.length && open[open.length - 1] >= level) open.pop();\n const depth = Math.min(cap, open.length + 1);\n open.push(level);\n counters.length = depth;\n counters[depth - 1] = (counters[depth - 1] || 0) + 1;\n return { id: String(entry?.id), entry, depth, number: counters.join('.'), li: null, target: null };\n });\n}\n", "/**\n * HelpModal - Modal dialog for displaying help content\n *\n * Features:\n * - Topics as trusted HTML (`topic.html`) or as markdown (`topic.markdown`),\n * rendered safe by `renderMarkdown` with the provider's `markdownOptions`\n * (a highlighter, math, extension rules)\n * - A table of contents for a topic with two or more headings, markdown or\n * html alike: its headings, listed and numbered, the one in view marked,\n * a click that scrolls to one (`createDocumentOutline`)\n * - Topic search\n * - Category browsing\n * - Keyboard navigation (Escape to close)\n */\n\nimport { helpProvider, helpCategories, helpCopy } from './help_registry.js';\nimport { renderMarkdown } from '../ui/utils/markdown.js';\nimport { createDocumentOutline } from '../ui/components/document_outline.js';\n\n/** The headings a topic's table of contents lists. */\nconst TOC_HEADINGS = 'h1, h2, h3, h4, h5, h6';\n/** Fewer headings than this, and a topic shows no table of contents. */\nconst TOC_MIN_HEADINGS = 2;\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// HelpModal Class\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nlet _activeModal = null;\n\nexport class HelpModal {\n /** The application's help, resolved at use time. */\n get _service() { return helpProvider(); }\n\n get _categories() { return helpCategories(); }\n\n get _copy() { return helpCopy(); }\n\n constructor() {\n // Read LAZILY, not here. A HelpModal can be constructed at boot (the\n // command palette holds one) before the application has registered its\n // help, and a constructor read would freeze the empty default forever.\n this._overlay = null;\n this._modal = null;\n this._currentTopic = null;\n this._searchQuery = '';\n this._fallback = null;\n this._toc = null;\n this._boundKeyHandler = this._handleKeyDown.bind(this);\n }\n\n /**\n * Open the help modal.\n * @param {string} [topicId] - Initial topic to display\n * @param {Object} [options]\n * @param {{title: string, html: string}} [options.fallback] - Shown for\n * `topicId` when the provider has no such topic (its `loadTopic` answers\n * null). A library-owned topic, such as the palette's keyboard shortcuts,\n * uses it so that an application's own topic of that id still wins.\n */\n async open(topicId = null, { fallback = null } = {}) {\n this._fallback = topicId && fallback ? { id: topicId, topic: fallback } : null;\n // Close any existing modal\n if (_activeModal && _activeModal !== this) {\n _activeModal.close();\n }\n _activeModal = this;\n\n this._createModal();\n document.body.appendChild(this._overlay);\n\n // Add keyboard handler\n document.addEventListener('keydown', this._boundKeyHandler);\n\n // Focus search input\n const searchInput = this._modal.querySelector('.help-search-input');\n if (searchInput) {\n setTimeout(() => searchInput.focus(), 100);\n }\n\n // Load initial topic or show index\n if (topicId) {\n await this._loadTopic(topicId);\n } else {\n this._showIndex();\n }\n }\n\n /**\n * Close the help modal.\n */\n close() {\n this._disposeToc();\n if (this._overlay) {\n document.removeEventListener('keydown', this._boundKeyHandler);\n this._overlay.remove();\n this._overlay = null;\n this._modal = null;\n }\n if (_activeModal === this) {\n _activeModal = null;\n }\n }\n\n /**\n * Create the modal DOM structure.\n * @private\n */\n _createModal() {\n // Overlay\n this._overlay = document.createElement('div');\n this._overlay.className = 'help-modal-overlay';\n this._overlay.addEventListener('click', (e) => {\n if (e.target === this._overlay) this.close();\n });\n\n // Modal container\n this._modal = document.createElement('div');\n this._modal.className = 'help-modal';\n this._modal.innerHTML = `\n <div class=\"help-modal__header\">\n <div class=\"help-modal__title\">\n <span class=\"material-symbols-outlined\">help</span>\n <span>Help</span>\n </div>\n <button class=\"help-modal__close\" title=\"Close (Esc)\">\n <span class=\"material-symbols-outlined\">close</span>\n </button>\n </div>\n <div class=\"help-modal__search\">\n <span class=\"material-symbols-outlined\">search</span>\n <input type=\"text\" class=\"help-search-input\" placeholder=\"Search help topics...\" autocomplete=\"off\">\n </div>\n <div class=\"help-modal__body\">\n <nav class=\"help-modal__sidebar\">\n <div class=\"help-sidebar__categories\"></div>\n </nav>\n <main class=\"help-modal__content\">\n <div class=\"help-content__loading\">Loading...</div>\n </main>\n </div>\n `;\n\n // Event handlers\n const closeBtn = this._modal.querySelector('.help-modal__close');\n closeBtn.addEventListener('click', () => this.close());\n\n const searchInput = this._modal.querySelector('.help-search-input');\n searchInput.addEventListener('input', (e) => this._handleSearch(e.target.value));\n searchInput.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') {\n if (e.target.value) {\n e.target.value = '';\n this._handleSearch('');\n e.stopPropagation();\n }\n }\n });\n\n // Build sidebar\n this._buildSidebar();\n\n this._overlay.appendChild(this._modal);\n }\n\n /**\n * Build the sidebar navigation.\n * @private\n */\n _buildSidebar() {\n const container = this._modal.querySelector('.help-sidebar__categories');\n const categories = this._service.getCategories();\n\n // Sort categories by order\n const categoryOrder = Object.keys(this._categories);\n categories.sort((a, b) => {\n const orderA = categoryOrder.indexOf(a);\n const orderB = categoryOrder.indexOf(b);\n return (orderA === -1 ? 99 : orderA) - (orderB === -1 ? 99 : orderB);\n });\n\n container.innerHTML = categories.map(category => {\n const topics = this._service.getTopicsByCategory(category);\n const label = this._categories[category]?.label || category;\n const icon = this._categories[category]?.icon || 'folder';\n\n return `\n <div class=\"help-category\" data-category=\"${escapeHtml(category)}\">\n <div class=\"help-category__header\">\n <span class=\"material-symbols-outlined\">${escapeHtml(icon)}</span>\n <span>${escapeHtml(label)}</span>\n </div>\n <ul class=\"help-category__topics\">\n ${topics.map(topic => `\n <li class=\"help-topic-item\" data-topic=\"${escapeHtml(topic.id)}\">\n ${escapeHtml(topic.title)}\n </li>\n `).join('')}\n </ul>\n </div>\n `;\n }).join('');\n\n // Add click handlers\n container.querySelectorAll('.help-topic-item').forEach(item => {\n item.addEventListener('click', () => {\n this._loadTopic(item.dataset.topic);\n });\n });\n\n container.querySelectorAll('.help-category__header').forEach(header => {\n header.addEventListener('click', () => {\n header.parentElement.classList.toggle('collapsed');\n });\n });\n }\n\n /**\n * Show the help index page.\n * @private\n */\n _showIndex() {\n this._disposeToc();\n const content = this._modal.querySelector('.help-modal__content');\n const categories = this._service.getCategories();\n\n const categoryOrder = Object.keys(this._categories);\n categories.sort((a, b) => {\n const orderA = categoryOrder.indexOf(a);\n const orderB = categoryOrder.indexOf(b);\n return (orderA === -1 ? 99 : orderA) - (orderB === -1 ? 99 : orderB);\n });\n\n content.innerHTML = `\n <div class=\"help-index\">\n <h1>${this._copy.title}</h1>\n <p>${this._copy.welcome}</p>\n\n <div class=\"help-index__grid\">\n ${categories.map(category => {\n const topics = this._service.getTopicsByCategory(category);\n const label = this._categories[category]?.label || category;\n const icon = this._categories[category]?.icon || 'folder';\n\n return `\n <div class=\"help-index__category\" data-category=\"${escapeHtml(category)}\">\n <div class=\"help-index__category-header\">\n <span class=\"material-symbols-outlined\">${escapeHtml(icon)}</span>\n <span>${escapeHtml(label)}</span>\n </div>\n <ul class=\"help-index__topics\">\n ${topics.slice(0, 3).map(topic => `\n <li class=\"help-index__topic\" data-topic=\"${escapeHtml(topic.id)}\">\n ${escapeHtml(topic.title)}\n </li>\n `).join('')}\n ${topics.length > 3 ? `<li class=\"help-index__more\">+${topics.length - 3} more</li>` : ''}\n </ul>\n </div>\n `;\n }).join('')}\n </div>\n </div>\n `;\n\n // Add click handlers\n content.querySelectorAll('.help-index__topic').forEach(item => {\n item.addEventListener('click', () => {\n this._loadTopic(item.dataset.topic);\n });\n });\n }\n\n /**\n * Load and display a topic.\n * @param {string} topicId - Topic ID\n * @private\n */\n async _loadTopic(topicId) {\n this._disposeToc();\n const content = this._modal.querySelector('.help-modal__content');\n content.innerHTML = '<div class=\"help-content__loading\">Loading...</div>';\n\n // Update sidebar selection\n this._modal.querySelectorAll('.help-topic-item').forEach(item => {\n item.classList.toggle('active', item.dataset.topic === topicId);\n });\n\n try {\n const topic = (await this._service.loadTopic(topicId))\n ?? (this._fallback?.id === topicId ? this._fallback.topic : null);\n // Closed (or closed and opened again) while the topic loaded.\n if (!this._modal?.contains(content)) return;\n this._currentTopic = topicId;\n\n if (!topic) {\n // An id nobody provides is not a load failure: say so plainly.\n content.innerHTML = `\n <div class=\"help-content__error help-content__error--not-found\">\n <span class=\"material-symbols-outlined\">search_off</span>\n <p>Help topic not found.</p>\n </div>\n `;\n return;\n }\n\n content.innerHTML = `\n <div class=\"help-content__article\">\n <div class=\"help-content__breadcrumb\">\n <a href=\"#\" class=\"help-breadcrumb__home\" title=\"Help Index\">\n <span class=\"material-symbols-outlined\">home</span>\n </a>\n <span class=\"help-breadcrumb__separator\">/</span>\n <span class=\"help-breadcrumb__title\">${escapeHtml(topic.title)}</span>\n </div>\n <div class=\"help-content__toc\" hidden></div>\n <article class=\"help-article\">\n ${this._articleHtml(topic)}\n </article>\n </div>\n `;\n\n // Add breadcrumb handler\n content.querySelector('.help-breadcrumb__home').addEventListener('click', (e) => {\n e.preventDefault();\n this._showIndex();\n });\n\n this._buildToc(content);\n } catch (error) {\n content.innerHTML = `\n <div class=\"help-content__error\">\n <span class=\"material-symbols-outlined\">error</span>\n <p>Failed to load help topic.</p>\n </div>\n `;\n }\n }\n\n /**\n * The article body: a markdown topic rendered safe, else the provider's\n * own HTML, which is trusted by contract.\n * @private\n */\n _articleHtml(topic) {\n if (typeof topic.markdown === 'string') {\n return renderMarkdown(topic.markdown, this._service.markdownOptions ?? {});\n }\n return topic.html ?? '';\n }\n\n /**\n * The topic's table of contents: one entry per heading in the article, in\n * document order, its level the heading's. Built only when the article\n * has `TOC_MIN_HEADINGS` or more; the outline resolves each entry to its\n * heading ELEMENT, so the provider's markup needs no ids and the modal\n * adds none.\n * @param {HTMLElement} content - The scrolling content pane.\n * @private\n */\n _buildToc(content) {\n this._disposeToc();\n const host = content.querySelector('.help-content__toc');\n const headings = [...content.querySelectorAll(`.help-article :is(${TOC_HEADINGS})`)];\n if (!host || headings.length < TOC_MIN_HEADINGS) return;\n const byId = new Map(headings.map((heading, index) => [`heading-${index}`, heading]));\n const entries = [...byId].map(([id, heading]) => ({\n id,\n level: Number(heading.tagName.slice(1)),\n label: heading.textContent.trim(),\n }));\n host.hidden = false;\n this._toc = createDocumentOutline(host, {\n entries,\n numbering: true,\n scrollContainer: content,\n resolveTarget: (entry) => byId.get(entry.id) ?? null,\n label: 'Contents',\n });\n }\n\n /** @private */\n _disposeToc() {\n this._toc?.dispose();\n this._toc = null;\n }\n\n /**\n * Handle search input.\n * @param {string} query - Search query\n * @private\n */\n _handleSearch(query) {\n this._searchQuery = query;\n const content = this._modal.querySelector('.help-modal__content');\n\n if (!query.trim()) {\n this._showIndex();\n return;\n }\n\n this._disposeToc();\n const results = this._service.searchTopics(query);\n\n if (results.length === 0) {\n content.innerHTML = `\n <div class=\"help-search-results\">\n <h2>Search Results</h2>\n <p class=\"help-search-empty\">No results found for \"${escapeHtml(query)}\"</p>\n </div>\n `;\n return;\n }\n\n content.innerHTML = `\n <div class=\"help-search-results\">\n <h2>Search Results</h2>\n <p class=\"help-search-count\">${results.length} result${results.length !== 1 ? 's' : ''} for \"${escapeHtml(query)}\"</p>\n <ul class=\"help-search-list\">\n ${results.map(topic => `\n <li class=\"help-search-item\" data-topic=\"${escapeHtml(topic.id)}\">\n <span class=\"help-search-item__title\">${escapeHtml(topic.title)}</span>\n <span class=\"help-search-item__category\">${escapeHtml(this._categories[topic.category]?.label || topic.category)}</span>\n </li>\n `).join('')}\n </ul>\n </div>\n `;\n\n // Add click handlers\n content.querySelectorAll('.help-search-item').forEach(item => {\n item.addEventListener('click', () => {\n this._loadTopic(item.dataset.topic);\n });\n });\n }\n\n /**\n * Handle keyboard events.\n * @param {KeyboardEvent} event\n * @private\n */\n _handleKeyDown(event) {\n if (event.key === 'Escape') {\n this.close();\n }\n }\n\n /**\n * Static method to open help modal.\n * @param {string} [topicId] - Initial topic\n * @param {Object} [options] - As for the instance `open`.\n * @returns {HelpModal}\n */\n static open(topicId = null, options = {}) {\n const modal = new HelpModal();\n modal.open(topicId, options);\n return modal;\n }\n\n /**\n * Close the open help modal, or open the index when none is open \u2014 what\n * the `?` shortcut does.\n * @returns {HelpModal|null} the modal opened, or null when one was closed\n */\n static toggle() {\n if (_activeModal) {\n _activeModal.close();\n return null;\n }\n return HelpModal.open();\n }\n\n /**\n * Get the currently active modal.\n * @returns {HelpModal|null}\n */\n static getActive() {\n return _activeModal;\n }\n}\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// Helpers\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n/**\n * Text for an innerHTML template. Everything the modal interpolates \u2014 the\n * search query the user typed, and the topic ids, titles and categories the\n * provider hands back \u2014 is TEXT; only `topic.html` is markup, by contract\n * (and `topic.markdown` becomes markup through `renderMarkdown`).\n * Quotes are escaped too, because ids and categories land in attributes.\n */\nfunction escapeHtml(value) {\n if (value === null || value === undefined) return '';\n return String(value)\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// The `?` shortcut \u2014 installed, never imported\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n/**\n * Bind `?` (outside editable fields) to `HelpModal.toggle()` on `target`, and\n * return the disposer that takes it off again.\n *\n * Importing this module binds nothing. It used to add a `document` listener as\n * a side effect of the import, which nobody could remove: a second shell in the\n * same page, or an application with its own `?`, got two handlers. A\n * `createShell()` shell binds `?` through its keymap (`installKeymap`), and\n * `shell.dispose()` takes it off; this is for a page that uses the help modal\n * without the shell.\n *\n * @param {object} [opts]\n * @param {EventTarget} [opts.target=document]\n * @returns {() => void}\n */\nexport function installHelpShortcut({ target = document } = {}) {\n const onKeyDown = (event) => {\n if (event.defaultPrevented || event.key !== '?') return;\n // Don't hijack `?` typed into a field (search boxes, editors).\n if (event.target?.closest?.('input, textarea, select, [contenteditable=\"true\"]')) return;\n event.preventDefault();\n HelpModal.toggle();\n };\n target.addEventListener('keydown', onKeyDown);\n return () => target.removeEventListener('keydown', onKeyDown);\n}\n\nexport default HelpModal;\n", "/**\n * menu_bar.js \u2014 a desktop menu bar, driven by a declarative model (STORY-0030).\n *\n * const bar = createMenuBar(el, {\n * menus: [\n * { id: 'file', label: 'File', items: [\n * { id: 'open', label: 'Open\u2026', shortcut: 'Ctrl+O' },\n * { id: 'recent', label: 'Open recent', submenu: () => recentItems() },\n * { separator: true },\n * { id: 'save', label: 'Save', shortcut: 'Ctrl+S', disabled: true },\n * ] },\n * { id: 'view', label: 'View', items: [\n * { id: 'grid', label: 'Show grid', checked: true }, // a check item\n * { id: 'light', label: 'Light', radio: 'theme', checked: true }, // a radio group\n * { id: 'dark', label: 'Dark', radio: 'theme', checked: false },\n * ] },\n * ],\n * onAction: (id, { item, checked }) => { \u2026 },\n * });\n *\n * \u2500\u2500 The model \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * A menu is `{ id, label, items }`. An item is `{ id, label, shortcut?,\n * disabled?, checked?, radio?, submenu? }`, or `{ separator: true }`.\n * checked a boolean makes it a CHECK item (`menuitemcheckbox`); with\n * `radio: '<group>'` it is a RADIO item (`menuitemradio`), and\n * checking one unchecks the rest of its group.\n * submenu an array of items, or a FUNCTION returning one. A function is\n * called every time the submenu opens, so a list that changes\n * under the bar (recent files, open windows) is always current.\n * shortcut drawn on the right. It is a label: the bar binds no key for it.\n *\n * `onAction(id, { item, checked })` is called for an enabled leaf item \u2014\n * never for a disabled one, a separator, or an item that opens a submenu. A\n * check or radio item has already flipped when it is called; `checked` is\n * the new state.\n *\n * \u2500\u2500 The keyboard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Alt (pressed and released on its own) or F10 focuses the bar, and pressing\n * either again leaves it. On a title: Left/Right move across the titles,\n * Down/Enter/Space open its menu on the first item, Up on the last. In a\n * menu: Up/Down/Home/End move within it, skipping separators and disabled\n * items; Right opens a submenu, or moves to the next menu; Left closes a\n * submenu, or moves to the previous menu; Enter/Space activate. Esc closes\n * one level at a time, and the Esc that leaves the bar gives focus back to\n * whatever had it before the bar did. Activating an item gives it back too,\n * BEFORE `onAction` runs, so a command acts on the context the user was in.\n *\n * \u2500\u2500 The pointer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * Clicking a title opens its menu (and closes it again); while a menu is\n * open, moving over another title switches to it. Moving over an item with a\n * submenu opens it. A press outside the bar closes everything.\n *\n * \u2500\u2500 State lives here, not in the DOM \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * `setEnabled(id, bool)` and `setChecked(id, bool)` record an override for\n * that id, which wins over what the model says from then on \u2014 including over\n * a function submenu's fresh items \u2014 and patch any open menu IN PLACE: the\n * bar is not rebuilt, and focus stays where it was. A radio group keeps ONE\n * recorded selection, so it shows exactly one checked item however its menu\n * is reached \u2014 opened later, a function submenu included. To find an id the\n * bar calls function submenus (as `commands()` does), open or not.\n * `commands()` returns the same model as command-palette rows (`{ id, label,\n * shortcut, context, action }`), so the palette and the bar list identical\n * verbs.\n *\n * \u2500\u2500 Two styles: a bar, or one hamburger button (STORY-0133) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * `style: 'bar'` (the default) draws a title per menu: File Edit Help.\n * `style: 'hamburger'` draws ONE icon button (`icon`, 'menu' by default,\n * named by `label`) whose menu lists the menus, each flying out its items:\n * \u2630 \u203A File \u203A Open\u2026. It is the same model, so `commands()`, `setEnabled`,\n * `setChecked` and `onAction` do not change; `open(menuId)` opens the\n * hamburger with that menu flown out. `setStyle(style)` switches at run\n * time (a setting, a narrow window), closing whatever is open.\n *\n * \u2500\u2500 Roles \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * The WAI-ARIA menubar pattern: `role=\"menubar\"` on the element you pass,\n * a `role=\"menuitem\"` title per menu inside a `role=\"none\"` wrapper, each\n * open menu a `role=\"menu\"` beside its title (or its parent item), items\n * `menuitem` / `menuitemcheckbox` / `menuitemradio` with `aria-checked`,\n * `aria-disabled` and, on a submenu's item, `aria-haspopup`/`aria-expanded`.\n * One title is in the tab order at a time (a roving tabindex).\n *\n * Every listener outside the bar is on the element's own document, and\n * `dispose()` takes them off.\n */\n\nconst SEL_TITLE = '.twm-menubar__title';\nconst SEL_ITEM = '.twm-menubar__item';\nconst SEL_MENU = '.twm-menubar__menu';\nconst STYLES = ['bar', 'hamburger'];\n/** The hamburger's own model ids. A menu's row in it is `${HAMBURGER}:${menu.id}`. */\nconst HAMBURGER = 'twm-menubar:hamburger';\n\n/** @returns {MenuBar} */\nexport function createMenuBar(el, opts) {\n return new MenuBar(el, opts);\n}\n\nexport class MenuBar {\n /**\n * @param {Element} el the element that becomes the bar\n * @param {object} opts\n * @param {Array} opts.menus `[{ id, label, items }]`\n * @param {Function} [opts.onAction] `(id, { item, checked }) => void`\n * @param {string} [opts.label] the bar's accessible name ('Menu')\n * @param {string} [opts.emptyLabel] the disabled row an empty submenu shows ('Empty')\n * @param {string} [opts.style] 'bar' (a title per menu, the default) or 'hamburger' (one button)\n * @param {string} [opts.icon] the hamburger's Material Symbols icon ('menu')\n */\n constructor(el, { menus, onAction = null, label = 'Menu', emptyLabel = 'Empty', style = 'bar', icon = 'menu' } = {}) {\n if (!el || typeof el.appendChild !== 'function') {\n throw new TypeError('createMenuBar: `el` must be an element');\n }\n _validateMenus(menus);\n _validateStyle(style);\n this.el = el;\n this.menus = menus;\n this._onAction = typeof onAction === 'function' ? onAction : null;\n this._emptyLabel = emptyLabel;\n this._label = label;\n this._icon = icon;\n this._style = style;\n this._doc = el.ownerDocument;\n this._disabled = new Map(); // id -> boolean (override)\n this._checked = new Map(); // id -> boolean (override, check items)\n this._radio = new Map(); // radio group -> the checked id (or null: none)\n this._models = new WeakMap(); // item element -> model item\n this._stack = []; // open menus: [{ menu, parent }]\n this._openIdx = -1; // which title's menu is open\n this._active = false; // focus is in the bar, or a menu is open\n this._returnTo = null; // what had focus before the bar did\n this._altArmed = false;\n\n el.classList.add('twm-menubar');\n el.setAttribute('role', 'menubar');\n el.setAttribute('aria-label', label);\n this._renderTitles();\n\n this._h = {\n mousedown: (e) => this._onMouseDown(e),\n click: (e) => this._onClick(e),\n mouseover: (e) => this._onMouseOver(e),\n keydown: (e) => this._onKey(e),\n keyup: (e) => { if (e.key === ' ' && this.el.contains(e.target)) e.preventDefault(); },\n focusin: (e) => this._onFocusIn(e),\n focusout: (e) => this._onFocusOut(e),\n docKeydown: (e) => this._onDocKeyDown(e),\n docKeyup: (e) => this._onDocKeyUp(e),\n docMousedown: (e) => this._onDocMouseDown(e),\n // Alt+Tab, Alt+F4, Alt+Space: the second key goes to the OS, so no\n // keydown reaches the page to disarm Alt. The window losing focus\n // does, or the Alt keyup on return would take focus to the bar.\n winBlur: () => { this._altArmed = false; },\n };\n for (const k of ['mousedown', 'click', 'mouseover', 'keydown', 'keyup', 'focusin', 'focusout']) {\n el.addEventListener(k, this._h[k]);\n }\n this._doc.addEventListener('keydown', this._h.docKeydown, true);\n this._doc.addEventListener('keyup', this._h.docKeyup, true);\n this._doc.addEventListener('mousedown', this._h.docMousedown, true);\n this._doc.defaultView?.addEventListener('blur', this._h.winBlur);\n }\n\n // \u2500\u2500 public \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** Whether a menu is open. */\n isOpen() { return this._openIdx >= 0; }\n\n /** Open the menu with this id (focus on its title, or on its first item).\n * A hamburger opens with that menu flown out (focus on its row, or on\n * the menu's first item). */\n open(menuId, { focusItem = false } = {}) {\n const i = this.menus.findIndex((m) => m.id === menuId);\n if (i < 0) return;\n this._enter();\n if (this._style !== 'hamburger') { this._open(i, focusItem ? 'first' : null); return; }\n this._open(0, null);\n const row = this._itemsIn(this._stack[0].menu)\n .find((b) => this._models.get(b)?.id === `${HAMBURGER}:${menuId}`);\n if (!row) return;\n row.focus({ preventScroll: true });\n this._openSub(row, focusItem ? 'first' : null);\n }\n\n /** 'bar' or 'hamburger'. */\n get style() { return this._style; }\n\n /** Draw the menus as a bar or as one hamburger button. Whatever is open\n * closes; the model and every setEnabled / setChecked stay. */\n setStyle(style) {\n _validateStyle(style);\n if (style === this._style) return;\n const hadFocus = this.el.contains(this._doc.activeElement);\n this._deactivate();\n this._style = style;\n this._renderTitles();\n if (hadFocus) this._focusTitle(0);\n }\n\n /** Close every open menu. Focus stays in the bar if it was there. */\n close() { this._closeAll(); }\n\n /** Focus the bar's first title, as Alt or F10 does. */\n focus() {\n this._enter();\n this._focusTitle(0);\n }\n\n isEnabled(id) {\n const item = this._findModel(id);\n return item ? !this._isDisabled(item) : !this._disabled.get(id);\n }\n\n isChecked(id) {\n const item = this._findModel(id);\n return item ? this._isChecked(item) : !!this._checked.get(id);\n }\n\n /** Enable or disable every item with this id; an open menu is patched in place. */\n setEnabled(id, enabled) {\n this._disabled.set(id, !enabled);\n this._patch(id);\n }\n\n /** Check or uncheck every item with this id; checking a radio item\n * unchecks the rest of its group. An open menu is patched in place. */\n setChecked(id, checked) {\n this._check(this._findModel(id), id, checked);\n }\n\n /**\n * The model as command-palette rows: one per enabled leaf item, labelled\n * as in the menu, with its `shortcut`, and its menu path as `context`\n * ('File \u203A Open recent'). A function submenu is called now, so the rows\n * are as current as the menu would be. `action` runs the item exactly as\n * a click would, including flipping a check or radio item.\n */\n commands() {\n const rows = [];\n const walk = (items, path) => {\n for (const it of _resolve(items)) {\n if (!it || it.separator || this._isDisabled(it)) continue;\n if (it.submenu != null) { walk(it.submenu, [...path, it.label]); continue; }\n rows.push({\n id: `menubar:${it.id}`,\n label: it.label,\n ...(it.shortcut ? { shortcut: it.shortcut } : {}),\n context: path.join(' \u203A '),\n verb: 'run',\n action: () => this._fire(it),\n });\n }\n };\n for (const m of this.menus) walk(m.items, [m.label]);\n return rows;\n }\n\n dispose() {\n this._closeAll();\n for (const k of ['mousedown', 'click', 'mouseover', 'keydown', 'keyup', 'focusin', 'focusout']) {\n this.el.removeEventListener(k, this._h[k]);\n }\n this._doc.removeEventListener('keydown', this._h.docKeydown, true);\n this._doc.removeEventListener('keyup', this._h.docKeyup, true);\n this._doc.removeEventListener('mousedown', this._h.docMousedown, true);\n this._doc.defaultView?.removeEventListener('blur', this._h.winBlur);\n this.el.innerHTML = '';\n this.el.classList.remove('twm-menubar', 'twm-menubar--hamburger');\n this.el.removeAttribute('role');\n this.el.removeAttribute('aria-label');\n }\n\n // \u2500\u2500 state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n _isDisabled(item) {\n return this._disabled.has(item.id) ? this._disabled.get(item.id) : !!item.disabled;\n }\n\n _isChecked(item) {\n if (item.radio != null && this._radio.has(item.radio)) return this._radio.get(item.radio) === item.id;\n return this._checked.has(item.id) ? this._checked.get(item.id) : !!item.checked;\n }\n\n /** Record a check. `item` is the model item when the bar knows it (a\n * radio item then records its group's selection); `id` alone is kept as\n * an override for an item the model does not hold yet. */\n _check(item, id, checked) {\n if (item?.radio != null) {\n const group = item.radio;\n if (checked) this._radio.set(group, id);\n else if (this._isChecked(item)) this._radio.set(group, null);\n this._patchGroup(group);\n return;\n }\n this._checked.set(id, !!checked);\n this._patch(id);\n }\n\n /** Every model item the bar knows of: the model, with every function\n * submenu called now (as `commands()` does), and whatever is on screen. */\n _knownItems() {\n const out = [];\n const walk = (items) => {\n for (const it of _resolve(items)) {\n if (!it || it.separator) continue;\n out.push(it);\n if (it.submenu != null) walk(it.submenu);\n }\n };\n for (const m of this.menus) walk(m.items);\n for (const b of this.el.querySelectorAll(SEL_ITEM)) {\n const it = this._models.get(b);\n if (it && !out.includes(it)) out.push(it);\n }\n return out;\n }\n\n _findModel(id) { return this._knownItems().find((it) => it.id === id) || null; }\n\n /** Re-apply the state of every rendered item with this id. */\n _patch(id) {\n for (const b of this.el.querySelectorAll(SEL_ITEM)) {\n const it = this._models.get(b);\n if (it && it.id === id) this._apply(b, it);\n }\n }\n\n /** Re-apply the state of every rendered item of this radio group. */\n _patchGroup(group) {\n for (const b of this.el.querySelectorAll(SEL_ITEM)) {\n const it = this._models.get(b);\n if (it && it.radio === group) this._apply(b, it);\n }\n }\n\n _apply(btn, item) {\n const off = this._isDisabled(item);\n btn.classList.toggle('twm-menubar__item--disabled', off);\n if (off) btn.setAttribute('aria-disabled', 'true');\n else btn.removeAttribute('aria-disabled');\n if (_kind(item) !== 'menuitem') {\n btn.setAttribute('aria-checked', this._isChecked(item) ? 'true' : 'false');\n }\n }\n\n // \u2500\u2500 titles \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n /** The titles for the current style. `_top` is what they open: the\n * menus themselves, or the hamburger's one menu that lists them. */\n _renderTitles() {\n const d = this._doc;\n const burger = this._style === 'hamburger';\n this.el.innerHTML = '';\n this.el.classList.toggle('twm-menubar--hamburger', burger);\n this._top = burger\n ? [{ id: HAMBURGER, label: this._label, items: this.menus.map((m) => ({\n id: `${HAMBURGER}:${m.id}`, label: m.label, submenu: m.items,\n })) }]\n : this.menus;\n this._titles = this._top.map((m, i) => {\n const entry = d.createElement('div');\n entry.className = 'twm-menubar__entry';\n entry.setAttribute('role', 'none');\n const btn = d.createElement('button');\n btn.type = 'button';\n btn.className = 'twm-menubar__title';\n btn.setAttribute('role', 'menuitem');\n btn.setAttribute('aria-haspopup', 'menu');\n btn.setAttribute('aria-expanded', 'false');\n btn.tabIndex = i === 0 ? 0 : -1;\n if (burger) {\n btn.classList.add('twm-menubar__title--icon', 'twm-has-tooltip');\n btn.setAttribute('aria-label', m.label);\n btn.dataset.tooltip = m.label;\n btn.dataset.tooltipPlacement = 'bottom';\n const icon = d.createElement('span');\n icon.className = 'material-symbols-outlined';\n icon.setAttribute('aria-hidden', 'true');\n icon.textContent = this._icon;\n btn.appendChild(icon);\n } else {\n btn.textContent = m.label;\n }\n entry.appendChild(btn);\n this.el.appendChild(entry);\n return btn;\n });\n }\n\n // \u2500\u2500 open / close \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n _setRoving(i) {\n this._titles.forEach((t, j) => { t.tabIndex = j === i ? 0 : -1; });\n }\n\n _focusTitle(i) {\n this._setRoving(i);\n this._titles[i]?.focus({ preventScroll: true });\n }\n\n /** The bar becomes active; remember what to give focus back to. */\n _enter(from = this._doc.activeElement) {\n if (this._active) return;\n this._active = true;\n this._returnTo = from && from !== this._doc.body && !this.el.contains(from) ? from : null;\n }\n\n /** Leave the bar and give focus back. */\n _exit() {\n const back = this._returnTo;\n this._closeAll();\n this._active = false;\n this._returnTo = null;\n if (back?.isConnected) back.focus({ preventScroll: true });\n else if (this.el.contains(this._doc.activeElement)) this._doc.activeElement.blur();\n }\n\n /** Focus went elsewhere on purpose: close, give nothing back. */\n _deactivate() {\n this._closeAll();\n this._active = false;\n this._returnTo = null;\n }\n\n _open(i, focus) {\n const n = this._titles.length;\n i = ((i % n) + n) % n;\n // Focus moves to the title BEFORE the old menu goes, so the element\n // being removed never holds focus.\n this._focusTitle(i);\n this._closeAll();\n const m = this._top[i];\n const title = this._titles[i];\n const menu = this._buildMenu(m.items, m.label);\n title.parentElement.appendChild(menu);\n title.setAttribute('aria-expanded', 'true');\n this._stack = [{ menu, parent: title }];\n this._openIdx = i;\n _place(menu, title, 'below');\n this._focusIn(menu, focus);\n }\n\n _openSub(btn, focus) {\n const item = this._models.get(btn);\n if (!item || item.submenu == null || this._isDisabled(item)) return;\n const level = this._levelOf(btn);\n if (level < 0) return;\n const open = this._stack[level + 1];\n if (open && open.parent === btn) { this._focusIn(open.menu, focus); return; }\n this._closeFrom(level + 1);\n const menu = this._buildMenu(item.submenu, item.label); // a function is called here, every time\n btn.parentElement.appendChild(menu);\n btn.setAttribute('aria-expanded', 'true');\n this._stack.push({ menu, parent: btn });\n _place(menu, btn, 'right');\n this._focusIn(menu, focus);\n }\n\n _focusIn(menu, focus) {\n if (!focus) return;\n const items = this._enabledIn(menu);\n (focus === 'last' ? items[items.length - 1] : items[0])?.focus({ preventScroll: true });\n }\n\n /** Close the menus at `level` and deeper. Focus inside them goes to the\n * item (or title) they hang from. */\n _closeFrom(level) {\n if (level >= this._stack.length) return;\n const first = this._stack[level];\n if (this._stack.slice(level).some((s) => s.menu.contains(this._doc.activeElement))) {\n first.parent.focus({ preventScroll: true });\n }\n for (const s of this._stack.splice(level)) {\n s.menu.remove();\n s.parent.setAttribute('aria-expanded', 'false');\n }\n if (level === 0) this._openIdx = -1;\n }\n\n _closeAll() { this._closeFrom(0); }\n\n _levelOf(el) {\n const menu = el.closest(SEL_MENU);\n return this._stack.findIndex((s) => s.menu === menu);\n }\n\n /** The items the keyboard can land on: no separators, nothing disabled. */\n _enabledIn(menu) {\n return this._itemsIn(menu).filter((b) => !this._isDisabled(this._models.get(b)));\n }\n\n /** Every item cell of `menu` in DOM order, disabled ones included. */\n _itemsIn(menu) {\n return [...menu.children]\n .map((w) => w.firstElementChild)\n .filter((b) => b?.matches?.(SEL_ITEM));\n }\n\n /** The next (`dir` 1) or previous (-1) enabled item from `btn`'s place\n * among all the cells, wrapping. `btn` itself may be disabled: one\n * setEnabled(id, false) leaves focus on it. */\n _stepFrom(menu, btn, dir) {\n const all = this._itemsIn(menu);\n const n = all.length;\n const at = all.indexOf(btn);\n for (let k = 1; k <= n; k++) {\n const b = all[(((at + dir * k) % n) + n) % n];\n if (!this._isDisabled(this._models.get(b))) return b;\n }\n return null;\n }\n\n _buildMenu(items, label) {\n const d = this._doc;\n const menu = d.createElement('div');\n menu.className = 'twm-menubar__menu';\n menu.setAttribute('role', 'menu');\n menu.setAttribute('aria-label', label);\n const list = _resolve(items).filter((it) => {\n if (it && (it.separator || (it.id != null && it.label != null))) return true;\n console.warn('[menubar] an item needs an id and a label', it);\n return false;\n });\n const shown = list.length ? list : [{ id: null, label: this._emptyLabel, disabled: true, _empty: true }];\n for (const it of shown) {\n if (it.separator) {\n const sep = d.createElement('div');\n sep.className = 'twm-menubar__separator';\n sep.setAttribute('role', 'separator');\n menu.appendChild(sep);\n continue;\n }\n const wrap = d.createElement('div');\n wrap.className = 'twm-menubar__cell';\n wrap.setAttribute('role', 'none');\n const btn = d.createElement('button');\n btn.type = 'button';\n btn.tabIndex = -1;\n const kind = _kind(it);\n btn.className = 'twm-menubar__item';\n if (kind !== 'menuitem') btn.classList.add(kind === 'menuitemradio' ? 'twm-menubar__item--radio' : 'twm-menubar__item--check');\n btn.setAttribute('role', kind);\n if (it.id != null) btn.dataset.itemId = it.id;\n const check = d.createElement('span');\n check.className = 'twm-menubar__check';\n check.setAttribute('aria-hidden', 'true');\n const text = d.createElement('span');\n text.className = 'twm-menubar__label';\n text.textContent = it.label;\n btn.append(check, text);\n if (it.shortcut) {\n const sc = d.createElement('span');\n sc.className = 'twm-menubar__shortcut';\n sc.textContent = it.shortcut;\n btn.appendChild(sc);\n }\n if (it.submenu != null) {\n btn.setAttribute('aria-haspopup', 'menu');\n btn.setAttribute('aria-expanded', 'false');\n btn.classList.add('twm-menubar__item--submenu');\n const arrow = d.createElement('span');\n arrow.className = 'twm-menubar__arrow';\n arrow.setAttribute('aria-hidden', 'true');\n btn.appendChild(arrow);\n }\n this._models.set(btn, it);\n this._apply(btn, it);\n wrap.appendChild(btn);\n menu.appendChild(wrap);\n }\n return menu;\n }\n\n // \u2500\u2500 activation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n _activate(btn) {\n const item = this._models.get(btn);\n if (!item || this._isDisabled(item)) return;\n if (item.submenu != null) { this._openSub(btn, 'first'); return; }\n this._exit();\n this._fire(item);\n }\n\n /** Flip a check/radio item and tell the embedder. The ONE door to\n * `onAction`, for clicks, keys and palette rows alike. */\n _fire(item) {\n if (!item || item.separator || item._empty || this._isDisabled(item) || item.submenu != null) return;\n let checked;\n // The item itself, not its id: it carries its own radio group even\n // when it came from a function submenu that is not on screen.\n if (_kind(item) === 'menuitemradio') { this._check(item, item.id, true); checked = true; }\n else if (_kind(item) === 'menuitemcheckbox') { checked = !this._isChecked(item); this._check(item, item.id, checked); }\n this._onAction?.(item.id, { item, checked });\n }\n\n // \u2500\u2500 events \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n _onMouseDown(e) {\n // Before the button could take focus: remember what had it. No press\n // in the bar moves focus by itself \u2014 not on a title or an item, nor\n // on a separator, a menu's padding or the bar's empty space \u2014 the bar\n // moves it (a title on click, an item on hover), so focus never drops\n // to nothing on the way, which would end the bar's activation (see\n // _onFocusOut).\n if (e.target.closest?.(SEL_TITLE)) this._enter();\n e.preventDefault();\n }\n\n _onClick(e) {\n const title = e.target.closest?.(SEL_TITLE);\n if (title) {\n const i = this._titles.indexOf(title);\n this._enter();\n if (this._openIdx === i) this._closeAll();\n else this._open(i, null);\n return;\n }\n const btn = e.target.closest?.(SEL_ITEM);\n if (btn) { e.stopPropagation(); this._activate(btn); }\n }\n\n _onMouseOver(e) {\n const title = e.target.closest?.(SEL_TITLE);\n if (title) {\n const i = this._titles.indexOf(title);\n if (this._openIdx >= 0 && this._openIdx !== i) this._open(i, null);\n return;\n }\n const btn = e.target.closest?.(SEL_ITEM);\n if (!btn) return;\n const item = this._models.get(btn);\n if (!item || this._isDisabled(item)) return;\n btn.focus({ preventScroll: true });\n const level = this._levelOf(btn);\n if (item.submenu != null) this._openSub(btn, null);\n else if (level >= 0) this._closeFrom(level + 1);\n }\n\n /** Tabbed into: what had focus is the event's `relatedTarget`. */\n _onFocusIn(e) {\n if (!this._active) this._enter(e.relatedTarget);\n }\n\n /** Focus left the bar: to an element outside it, or to nothing (a press\n * on a non-focusable area, the window losing focus). Either way the\n * activation ends, so the next Alt/F10 remembers what has focus THEN. */\n _onFocusOut(e) {\n const to = e.relatedTarget;\n if (!to || !this.el.contains(to)) this._deactivate();\n }\n\n _onKey(e) {\n if (e.ctrlKey || e.metaKey || e.altKey) return; // app chords pass through\n const title = e.target.closest?.(SEL_TITLE);\n const btn = title ? null : e.target.closest?.(SEL_ITEM);\n if (!title && !btn) return;\n if (e.key === 'Tab') { this._deactivate(); return; } // focus moves on, as Tab says\n const handled = title ? this._titleKey(e.key, this._titles.indexOf(title))\n : this._itemKey(e.key, btn);\n if (handled) e.preventDefault();\n // Keys meant for the bar do not reach the page's own bindings\n // (Backspace is a \"go back\" in the window manager). F-keys do.\n if (handled || !/^F\\d+$/.test(e.key)) e.stopPropagation();\n }\n\n _titleKey(key, i) {\n const n = this._titles.length;\n const open = this._openIdx >= 0;\n // One title (a hamburger): there is no next or previous menu.\n if (n === 1 && (key === 'ArrowRight' || key === 'ArrowLeft' || key === 'Home' || key === 'End')) return true;\n switch (key) {\n case 'ArrowRight': open ? this._open(i + 1, null) : this._focusTitle((i + 1) % n); return true;\n case 'ArrowLeft': open ? this._open(i - 1, null) : this._focusTitle((i - 1 + n) % n); return true;\n case 'Home': open ? this._open(0, null) : this._focusTitle(0); return true;\n case 'End': open ? this._open(n - 1, null) : this._focusTitle(n - 1); return true;\n case 'ArrowDown': case 'Enter': case ' ':\n if (open && this._openIdx === i) this._focusIn(this._stack[0].menu, 'first');\n else this._open(i, 'first');\n return true;\n case 'ArrowUp':\n if (open && this._openIdx === i) this._focusIn(this._stack[0].menu, 'last');\n else this._open(i, 'last');\n return true;\n case 'Escape':\n if (open) this._closeAll();\n else this._exit();\n return true;\n default: return false;\n }\n }\n\n _itemKey(key, btn) {\n const level = this._levelOf(btn);\n if (level < 0) return false;\n const menu = this._stack[level].menu;\n const item = this._models.get(btn);\n const go = (b) => b?.focus({ preventScroll: true });\n // A submenu can be open while focus is still on the item it hangs\n // from (opened by the pointer, or with no row the keyboard can land\n // on). Left and Esc close that submenu first, keeping focus here.\n if ((key === 'ArrowLeft' || key === 'Escape') && this._stack[level + 1]?.parent === btn) {\n this._closeFrom(level + 1);\n return true;\n }\n // Moving within a menu closes any submenu open below it, as hovering\n // another item does, so no stale submenu stays next to the focus.\n if (key === 'ArrowDown' || key === 'ArrowUp' || key === 'Home' || key === 'End') {\n this._closeFrom(level + 1);\n }\n switch (key) {\n case 'ArrowDown': go(this._stepFrom(menu, btn, 1)); return true;\n case 'ArrowUp': go(this._stepFrom(menu, btn, -1)); return true;\n case 'Home': this._focusIn(menu, 'first'); return true;\n case 'End': this._focusIn(menu, 'last'); return true;\n case 'ArrowRight':\n if (item?.submenu != null && !this._isDisabled(item)) this._openSub(btn, 'first');\n else if (this._titles.length > 1) this._open(this._openIdx + 1, 'first');\n return true;\n case 'ArrowLeft':\n if (level > 0) this._closeFrom(level);\n else if (this._titles.length > 1) this._open(this._openIdx - 1, 'first');\n return true;\n case 'Enter': case ' ':\n this._activate(btn);\n return true;\n case 'Escape':\n if (level > 0) this._closeFrom(level);\n else this._closeAll();\n return true;\n default: return false;\n }\n }\n\n /** Alt on its own, and F10: armed on keydown, acted on here or on keyup. */\n _onDocKeyDown(e) {\n if (e.key === 'Alt') {\n this._altArmed = !e.ctrlKey && !e.metaKey && !e.shiftKey && !e.repeat;\n return;\n }\n this._altArmed = false;\n if (e.key === 'F10' && !e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey) {\n e.preventDefault();\n e.stopPropagation(); // F10 is the bar's while one is mounted\n this._toggle();\n }\n }\n\n _onDocKeyUp(e) {\n if (e.key !== 'Alt') return;\n const armed = this._altArmed;\n this._altArmed = false;\n if (!armed) return;\n e.preventDefault();\n this._toggle();\n }\n\n _onDocMouseDown(e) {\n this._altArmed = false;\n if (this._openIdx >= 0 && !this.el.contains(e.target)) this._deactivate();\n }\n\n _toggle() {\n if (this._active && (this._openIdx >= 0 || this.el.contains(this._doc.activeElement))) this._exit();\n else this.focus();\n }\n}\n\n// \u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction _resolve(items) {\n const v = typeof items === 'function' ? items() : items;\n return Array.isArray(v) ? v : [];\n}\n\nfunction _kind(item) {\n if (item.radio != null) return 'menuitemradio';\n if (typeof item.checked === 'boolean') return 'menuitemcheckbox';\n return 'menuitem';\n}\n\nfunction _validateStyle(style) {\n if (!STYLES.includes(style)) {\n throw new TypeError(`createMenuBar: \\`style\\` must be ${STYLES.map((s) => `'${s}'`).join(' or ')}`);\n }\n}\n\n/** A bad model is a boot error, not a menu that silently lacks a row. */\nfunction _validateMenus(menus) {\n if (!Array.isArray(menus) || !menus.length) {\n throw new TypeError('createMenuBar: `menus` must be a non-empty array');\n }\n const walk = (items, where) => {\n if (typeof items === 'function') return;\n if (!Array.isArray(items)) throw new TypeError(`createMenuBar: ${where} needs \\`items\\` (an array or a function)`);\n for (const it of items) {\n if (it?.separator) continue;\n if (it?.id == null || it?.label == null) {\n throw new TypeError(`createMenuBar: an item in ${where} needs an id and a label`);\n }\n if (it.submenu != null) walk(it.submenu, `\"${it.label}\"`);\n }\n };\n for (const m of menus) {\n if (m?.id == null || m?.label == null) throw new TypeError('createMenuBar: a menu needs an id and a label');\n walk(m.items, `menu \"${m.label}\"`);\n }\n}\n\n/** Fixed, so a bar inside an `overflow: hidden` chrome strip is not clipped;\n * kept on screen. `below` drops from a title, `right` flies out of an item. */\nfunction _place(menu, anchor, side) {\n const view = menu.ownerDocument.defaultView;\n const a = anchor.getBoundingClientRect();\n const r = menu.getBoundingClientRect();\n const vw = view?.innerWidth || 0;\n const vh = view?.innerHeight || 0;\n let left = side === 'below' ? a.left : a.right;\n let top = side === 'below' ? a.bottom : a.top;\n if (vw && left + r.width > vw) left = side === 'below' ? vw - r.width - 4 : a.left - r.width;\n if (vh && top + r.height > vh) top = Math.max(0, vh - r.height - 4);\n menu.style.left = `${Math.max(0, left)}px`;\n menu.style.top = `${Math.max(0, top)}px`;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["k", "j", "text", "escapeHtml"]
7
7
  }